Upload
joelle-nixon
View
100
Download
1
Embed Size (px)
DESCRIPTION
Lex & Yacc. โดย...นายชัชวาลย์ ฮาสุวรรณกิจ. UNIX ได้จัดเครื่องมือสำหรับการพัฒนาตัวภาษา (Language Development Tools) เครื่องมือนี้คือ lex ( LEXical analyzer) yacc (Yet Another Compiler Compiler). Lex เป็นเครื่องมือที่ใช้เพื่อตรวจจับรูปแบบเหมือน (Pattern matching) - PowerPoint PPT Presentation
Citation preview
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