lex & yacc

Post on 03-Jan-2016

89 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Lex & Yacc. โดย...นายชัชวาลย์ ฮาสุวรรณกิจ. UNIX ได้จัดเครื่องมือสำหรับการพัฒนาตัวภาษา (Language Development Tools) เครื่องมือนี้คือ lex ( LEXical analyzer) yacc (Yet Another Compiler Compiler). Lex เป็นเครื่องมือที่ใช้เพื่อตรวจจับรูปแบบเหมือน (Pattern matching) - PowerPoint PPT Presentation

TRANSCRIPT

Lex & Yacc

โดย... นายชั�ชัวาลย� ฮาสุ�วรรณกิ�จ

UNIX ได�จ�ดเคร��องมื�อสุ�าหร�บกิารพั�ฒนาตั�วภาษา (Language Development Tools)

เคร��องมื�อน%&ค�อ •lex ( LEXical analyzer) •yacc (Yet Another Compiler Compiler)

Lex•เป็(นเคร��องมื�อที่%�ใชั�เพั��อตัรวจจ�บร+ป็แบบเหมื�อน (Pattern matching) จากิ Input ที่%�อ-านเข้�ามืาที่%ละอ�กิข้ระ ได�เป็(น Tokens ตั-างๆ•ผลล�พัธ์�ที่%�ได�จากิ lex เป็(นชั�ดค�าสุ��งย-อยภาษาซี% ชั��อ yylex()•มื�กิเร%ยกิอ%กิอย-างว-า Scanner

Yacc•เป็(นเคร��องมื�อที่%�ใชั�ว�เคราะห�วากิยสุ�มืพั�นธ์� (Syntax Analysis) •ผลล�พัธ์�ที่%�ได�จากิ yacc เป็(นชั�ดค�าสุ��งย-อยภาษาซี% ชั��อ yyparse()•มื�กิเร%ยกิอ%กิอย-างว-า Parser

3ร+ป็ที่%� ตั�วว�เคราะห�กิารกิ ระจาย(Parser) ที่%�ใชั�Yacc และ Lex

Lex specif. Yacc specif.

lex yacc

Lexicalanalyzer

parser

Lexical errors Parsing errors

Parseroutput

Programinput

tokens

Lex มื% Input เป็(น Lex specifications fileและมื% Output ออกิเป็(นภาษา C

Lex Specifications file มื%ร+ป็แบบที่��วไป็ด�งน%&definitions%%lex regular expressions and actions%%User functions

Lex specifications fileตั�วอย-าง 1%%[0-9]+{ printf(“INTEGER\n”); }[-*/+]{ printf(“OPERATOR\n”); }

ตั�วอย-าง 2%%[0-9]+ { return (INT); }[-*/+] { return (OPR); }

Lex Definitions

INTEGER [0-9]+%%{ INTEGER } printf(" Integer encountered\n");{ INTEGER } \. { INTEGER } {

printf(" Real number encountered\n");

}

Yacc specifications file มื%โครงสุร�างที่%�คล�ายคล4งกิ�บ Lex specifications file ด�งน%&

declarations%%yacc rules and actions%%User functions

ตั�วอย-าง Yacc specifications program สุ�าหร�บ Parser อย-างง-ายข้�างตั�นเข้%ยนได�ด�งน%&

%token INT OPR%start expr%%expt : INT OPR INT

{printf("The input expression was syntactically correct\n");}| error{printf("The input expression was syntactically incorrect\n");}

%%

Main program

#include <stdio.h>main( ){

yyparse( );}#include "y.tab.c"#include "lex.yy.c"

กิาร Run Parser

lex file-nameFile-name เป็(นชั��อข้อง File ที่%�มื% Lex specifications ในกิาร Execute ค�าสุ��งจะสุร�าง File ที่%�เร%ยกิว-า lex.yy.c ซี4�งเป็(น C program ที่%�มื% function yylex อย+-

yacc file-nameFile-name เป็(นชั��อข้อง File ที่%�มื% yacc specifications ในกิาร Execute ค�าสุ��งจะสุร�าง File ที่%�เร%ยกิว-า y.tab.c ซี4�งเป็(น C program ที่%�มื% function yyparse

กิาร Run Parser

•สุร�าง a.out parser ด�วยกิารใชั�ค�าสุ��งด�งข้�างล-างน%& cc main.c -ly• กิาร Compile จะใชั� Standard CC command และ เราสุามืารถเร%ยกิใชั� Yacc library ได�โดยกิารใชั� -ly option เราสุามืารถเร%ยกิใชั�Lex library โดยกิารใชั� -ll option ในค�าสุ��ง CC command line

• แตั-ไมื-จ�าเป็(นเสุมือไป็ที่�กิคร�&งที่%�จะตั�องใชั� Yacc และ Lex libraries

• -ly ใชั� Yacc library เพัราะว-ามื%กิารใชั� Error option

Table 1: Pattern Matching Primitives

Metacharacter Matches.\n*+?^$a|b(ab)+"a+b"[ ]

any character except newlinenewlinezero or more copies of preceding expressionone or more copies of preceding expressionzero or one copy of preceding expressionbeginning of lineend of linea or bone or more copies of ab (grouping)literal “a+b”character class

Table 2: Pattern Matching Examples

Expression Matchesabcabc*abc+a(bc)+a(bc)?[abc][a-z][a\-z][-az][A-Za-z0-9]+[ \t\n]+[^ab][a^b][a|b]a|b

abcab, abc, abcc, abccc, …abc, abcc, abccc, …abc, abcbc, abcbcbc, …a, abca, b, cany letter, a through za, -, z-, a, zone or more alphanumeric characterswhitespaceanything except: a, ba, ^, ba, |, ba or b

Context Sensitivity

• Lex ได�มื%กิลไกิที่%�เป็(นเง��อนไข้ในกิารที่�างาน (Start condition) สุ�าหร�บ กิรณ% Left context sensitivity ไว�ให�

• Left context sensitivity บอกิว-า ความืหมืายข้อง Token หน4�งจะข้4&นอย+-กิ�บ Token ที่%�อย+-กิ-อนหน�ามื�น

• หล�กิกิารข้องกิารใชั� start condition ค�อเพั��อ Set และ Unset ตั�ว Token น�&น เมื��อมื%เหตั�กิารณ�เกิ�ดข้4&น • Start conditions ใน Lex กิ�าหนดได�ตัามืร+ป็แบบน%&

%start start1 start2 start3 …

โดยที่%� start1, start2 และ start3 เป็(นชั��อข้อง Start conditions

• กิาร Set start condition ใชั� Statement ด�งน%&

BIGIN start1

โดยที่%� start1 เป็(นชั��อข้อง Start condition

• กิาร Unset start condition ตั-างๆ ใชั� Statement ด�งน%&

BEGIN 0;

• กิาร Match สุตัร�งหน4�งกิ�บ Regular expression ที่%�มื% Start condition

เข้%ยนได�ด�งน%&< start1 > reg_expr { actions }

ตั�วอย-างกิารใชั� Start Condition

แป็ลงตั�วเลข้จ�านวนน�บสุองหล�กิไป็เป็(นกิารแสุดงด�วยตั�วหน�งสุ�อ โดยให� input ข้4&นตั�นด�วย $ (Dollar sign) แล�วตัามืหล�งด�วยตั�วเลข้สุองตั�ว ตั�วอย-างเชั-นถ�า Input เป็(น $23 จะได� output เป็(น Twenty three dollars

เราสุามืารถเข้%ยน Lex specifications file สุ�าหร�บโป็รแกิรมืน%&ด�งด�งน%&

%start TT ZZ DD TN%%\ $ { BEGIN TT; }< TT > [ 0-9 ] {

tenth = yytext[0];BEGIN 0;Switch (yytext[0]){case '0' : BEGIN

ZZ; break;case '1' : BEGIN

TN; break;default : BEGIN

DD; break;}}

< ZZ > [ 0-9 ]{ BEGIN 0;Switch (yytext[0]){case '0' : printf("Zero

dollars"); break;case '1' : printf("One

dollars"); break;case '2' : printf("Two

dollars"); break;case '3' :

printf("Three dollars"); break;case '4' : printf("Four

dollars"); break;case '5' : printf("Five

dollars"); break;case '6' : printf("Six

dollars"); break;case '7' :

printf("Seven dollars"); break;case '8' :

printf("Eight dollars"); break;case '9' : printf("Nine

dollars"); break;}}

< TN > [ 0-9] { BEGIN 0;Switch (yytext[0]){case '0' : printf("Ten

dollars"); break;case '1' : printf("Eleven

dollars"); break;case '2' : printf("Twelve

dollars"); break;case '3' : printf("Thirteen

dollars"); break;case '4' :

printf("Fourteen dollars"); break;case '5' : printf("Fifteen

dollars"); break;case '6' : printf("Sixteen

dollars"); break;case '7' :

printf("Seventeen dollars"); break;case '8' : printf("Eighteen

dollars"); break;case '9' :

printf("Nineteen dollars"); break;}}

< DD > [ 0-9 ] {BEGIN 0;Switch (tenth){case '2' :

printf("Twenty "); break;case '3' :

printf("Thirty "); break;case '4' :

printf("Forty "); break;case '5' :

printf("Fifty "); break;case '6' :

printf("Sixty "); break;case '7' :

printf("Seventy "); break;case '8' :

printf("Eighty "); break;case '9' :

printf("Ninety "); break;}

Switch (yytext[0]){case '0' :

printf("dollars"); break;case '1' : printf("One

dollars"); break;case '2' : printf("Two

dollars"); break;case '3' : printf("Three

dollars"); break;case '4' : printf("Four

dollars"); break;case '5' : printf("Five

dollars"); break;case '6' : printf("Six

dollars"); break;case '7' : printf("Seven

dollars"); break;case '8' : printf("Eight

dollars"); break;case '9' : printf("Nine

dollars"); break;}}

main function โป็รแกิรมืภาษา C เข้%ยนได�ด�งข้�างล-างน%&

#include < stdio.h>char tenth;main( ){

while (1)yylex( );

}yywrap( ){

exit (0);}#include " lex.yy.c "

Predefined Pseudovariables

• ค-าที่%�สุ-งกิล�บมืาสุ�าหร�บแตั-ละ Token โดย Lexical analyzer สุามืารถจะเข้�าถ4งและน�าไป็ใชั�งานได�ภายในกิฎข้อง Yacc • Precefined pseudovariables ถ+กิใชั�ในกิารเข้�าถ4งค-าตั-างๆข้อง Token ใชั�สุ�ญล�กิษณ�เร��มืตั�นด�วย $ (Dollar Sign) แล�วตัามืด�วยตั�วเลข้ (Integer) โดยที่%�เลข้ Integer น%&จะอ�างถ4งตั�าแหน-งข้อง Terminal symbol ภายใน Rule และ $$ จะอ�างอ�งถ4ง Left-hand nontermal symbol ในกิฎด�งน%&

result : VAR1 '+' VAR2 '+' VAR3{ $$ = $1 + $3+ $5; };

$1 ถ+กิกิ�าหนดค-าให�โดย VAR1, $2 จะถ+กิกิ�าหนดค-าให�โดย Terminal symbol +,

และตั-อไป็ตัามืล�าด�บ...จนถ4ง$5 จะถ+กิกิ�าหนดค-าโดย VAR3

โดยผลข้องกิารค�านวณจะสุ-งไป็ให�กิ�บ Nonterminal result

Predefined pseudovariables จะมื%ป็ระโยชัน�โดยเฉพัาะใชั�ในกิารว�เคราะห�กิารกิระจาย (Parsing) และกิารหาค-าจากิร+ป็ป็ระโยคที่างคณ�ตัศาสุตัร� (Arithmetic expressions)

มืาที่�าโป็รแกิรมื Calculator

กิ�นเถอะ

มืาที่�าโป็รแกิรมื Calculator

กิ�นเถอะ

Lex specifications file > cat cal.l

%{ # include"y. tab. h"

extern char yytext[]; extern intyylval;

%}%%

- [0 9]+ { yylval =atoi(yytext); return INTEGER; }(ตั-อ)

(ตั-อ)-[ + +++ ++++++

* yytext; [\t] ;

. { exit(0 ); }%%+++ +++++

{ return 1; }

Yacc specifications file> cat cal.y | more

%token INTEGER%%program:program expr '\n' {printf("%d\n",$2);} | ;expr: INTEGER {$$ = $1;} |expr '+' expr {$$ = $1 + $3 ;} |expr '-' expr {$$ = $1 - $3 ;} ;(ตั-อ)

(ตั-อ)%%yyerror(){ exit(0);}main(){ yyparse(); return 0;}

Compile และRun โป็รแกิรมื

>yacc –d cal.y > lex cal.l - > cc lex.yy.c y.tab.c o

+++ > ./cal-31 /* input */

2 /* ผลล�พัธ์� */-42 1+

1 /* ผลล�พัธ์� */-5 3 21+ +

9 /* ผลล�พัธ์� */. /* exit */>

REFERENCE

UNIX UTILITIES, International Edition,

-R.S. Tare, McGraw Hill, 1988

“ A Compact Guide to LEX and YACC”

http://epaperpress.com/y_man.html,

Access date Feb,42001

top related