html5-img
1 / 35

Lex & Yacc

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

Download Presentation

Lex & Yacc

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lex & Yacc โดย...นายชัชวาลย์ ฮาสุวรรณกิจ

  2. UNIXได้จัดเครื่องมือสำหรับการพัฒนาตัวภาษา • (Language Development Tools) • เครื่องมือนี้คือ • lex ( LEXical analyzer) • yacc (Yet Another Compiler Compiler)

  3. Lex • เป็นเครื่องมือที่ใช้เพื่อตรวจจับรูปแบบเหมือน (Pattern matching) • จาก Input ที่อ่านเข้ามาทีละอักขระ ได้เป็น Tokens ต่างๆ • ผลลัพธ์ที่ได้จาก lex เป็นชุดคำสั่งย่อยภาษาซี ชื่อ yylex() • มักเรียกอีกอย่างว่า Scanner • Yacc • เป็นเครื่องมือที่ใช้วิเคราะห์วากยสัมพันธ์ (Syntax Analysis) • ผลลัพธ์ที่ได้จาก yacc เป็นชุดคำสั่งย่อยภาษาซี ชื่อ yyparse() • มักเรียกอีกอย่างว่าParser

  4. Lex มี Input เป็น Lex specifications file และมี Output ออกเป็นภาษา C Lex Specifications fileมีรูปแบบทั่วไปดังนี้ definitions %% lex regular expressions and actions %% User functions

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

  6. Lex Definitions • INTEGER [0-9]+ • %% • { INTEGER } printf(" Integer encountered\n"); • { INTEGER } \. { INTEGER } { • printf(" Real number encountered\n"); • }

  7. Yacc specifications file มีโครงสร้างที่คล้ายคลึงกับ Lex specifications file ดังนี้ declarations %% yacc rules and actions %% User functions

  8. ตัวอย่าง Yacc specifications program สำหรับ Parser อย่างง่ายข้างต้นเขียนได้ดังนี้

  9. %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"); } %%

  10. Main program #include <stdio.h> main( ) { yyparse( ); } #include "y.tab.c" #include "lex.yy.c"

  11. การ Run Parser lex file-name File-name เป็นชื่อของ File ที่มี Lex specifications ในการ Execute คำสั่งจะสร้าง File ที่เรียกว่า lex.yy.c ซึ่งเป็น C program ที่มี function yylex อยู่ yacc file-name File-name เป็นชื่อของ File ที่มี yacc specifications ในการ Execute คำสั่งจะสร้าง File ที่เรียกว่า y.tab.c ซึ่งเป็น C program ที่มี function yyparse

  12. การ 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

  13. Context Sensitivity • Lex ได้มีกลไกที่เป็นเงื่อนไขในการทำงาน (Start condition) สำหรับ กรณี Left context sensitivity ไว้ให้ • Left context sensitivity บอกว่า ความหมายของ Token หนึ่งจะขึ้นอยู่กับ Token ที่อยู่ก่อนหน้ามัน • หลักการของการใช้ start condition คือเพื่อ Set และ Unset ตัว Token นั้น เมื่อมีเหตุการณ์เกิดขึ้น • Start conditionsใน Lex กำหนดได้ตามรูปแบบนี้ • %start start1 start2 start3 …

  14. โดยที่ start1, start2 และ start3 เป็นชื่อของ Start conditions • การ Set start condition ใช้ Statement ดังนี้ • BIGIN start1 • โดยที่ start1 เป็นชื่อของ Start condition • การ Unset start conditionต่างๆ ใช้ Statement ดังนี้ • BEGIN 0; • การ Match สตริงหนึ่งกับ Regular expression ที่มี Start condition • เขียนได้ดังนี้ • < start1 > reg_expr { actions }

  15. ตัวอย่างการใช้ Start Condition แปลงตัวเลขจำนวนนับสองหลักไปเป็นการแสดงด้วยตัวหนังสือ โดยให้ input ขึ้นต้นด้วย $ (Dollar sign) แล้วตามหลังด้วยตัวเลขสองตัว ตัวอย่างเช่นถ้า Input เป็น $23 จะได้ output เป็น Twenty three dollars เราสามารถเขียน Lex specifications file สำหรับโปรแกรมนี้ดังดังนี้

  16. %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; } }

  17. < 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; } }

  18. < 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; } }

  19. < 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; }

  20. 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; } }

  21. main function โปรแกรมภาษา C เขียนได้ดังข้างล่างนี้ #include < stdio.h> char tenth; main( ) { while (1) yylex( ); } yywrap( ) { exit (0); } #include " lex.yy.c "

  22. Predefined Pseudovariables • ค่าที่ส่งกลับมาสำหรับแต่ละ Token โดย Lexical analyzer • สามารถจะเข้าถึงและนำไปใช้งานได้ภายในกฎของ Yacc • Precefined pseudovariables ถูกใช้ในการเข้าถึงค่าต่างๆของ Token • ใช้สัญลักษณ์เริ่มต้นด้วย $ (Dollar Sign) แล้วตามด้วยตัวเลข (Integer) • โดยที่เลข Integer นี้จะอ้างถึงตำแหน่งของ Terminal symbol • ภายใน Rule และ $$ จะอ้างอิงถึง Left-hand nontermal symbol • ในกฎดังนี้ • result : VAR1 '+' VAR2 '+' VAR3 • { $$ = $1 + $3+ $5; };

  23. $1ถูกกำหนดค่าให้โดย VAR1, $2จะถูกกำหนดค่าให้โดย Terminal symbol +, และต่อไปตามลำดับ...จนถึง $5จะถูกกำหนดค่าโดย VAR3 โดยผลของการคำนวณจะส่งไปให้กับ Nonterminal result Predefined pseudovariablesจะมีประโยชน์โดยเฉพาะ ใช้ในการวิเคราะห์การกระจาย (Parsing) และ การหาค่าจากรูปประโยคทางคณิตศาสตร์ (Arithmetic expressions)

  24. มาทำโปรแกรม Calculator กันเถอะ

  25. Lex specifications file > cat cal.l %{ #include "y.tab.h" extern char yytext[]; extern int yylval; %} %% [0-9]+ { yylval = atoi(yytext); return INTEGER; } (ต่อ)

  26. (ต่อ) [-+\n] return *yytext; [\t] ; . { exit(0); } %% yywrap() { return 1; }

  27. 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 ;} • ; (ต่อ)

  28. (ต่อ) %% yyerror() { exit(0); } main(){ yyparse(); return 0; }

  29. Compile และRun โปรแกรม • >yacc –d cal.y • > lex cal.l • > cc lex.yy.c y.tab.c -o cal • > ./cal • 3-1/* input */ • 2/* ผลลัพธ์ */ • 4-2+1 • 1/* ผลลัพธ์ */ • 5+3+2-1 • 9/* ผลลัพธ์ */ • ./* exit */ • >

  30. 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,4 2001

More Related