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

Slides:



Advertisements
งานนำเสนอที่คล้ายกัน
โครงสร้างของภาษา C ในโปรแกรมที่พัฒนาด้วยภาษา C ทุกโปรแกรมจะมีโครงสร้างการพัฒนาไม่แตกต่างกัน ซึ่งประกอบด้วย 6 ส่วนหลัก ๆ โดยที่แต่ละส่วนจะมีหน้าที่แตกต่างกัน.
Advertisements

Introduction to C Introduction to C.
โครงสร้างโปรแกรมภาษา C
โครงสร้างภาษาซี เบื้องต้น
สาขาวิชาคอมพิวเตอร์ คณะวิทยาศาสตร์และเทคโนโลยี
Lecture 5: ทางเลือกแบบหลายทาง
โดยอาจารย์ศิริพร ศักดิ์บุญญารัตน์ ครูชำนาญการ โรงเรียนมหิดลวิทยานุสรณ์
การเขียนโปรแกรมด้วยคำสั่งเบื้องต้น
Control Statement if..else switch..case for while do-while.
Department of Computer Business
สายอักขระและ การประมวลผลสายอักขระ (String and String manipulation)
บทที่ 3 ตอนที่ 1 คำสั่งเงื่อนไขและการตัดสินใจ(p
Type Judgments และ Type Rules. คำศัพท์ที่จะใช้ Type judgment: การตัดสินความถูกต้องของ type สำหรับ expression หรือ statement ใน โปรแกรม – เป็นบทสรุป (conclusion)
Structure Programming
Structure Programming
คำสั่ง while ควบคุมการทำงานวนซ้ำ กรณีระบบงานมีลักษณะตรวจสอบเงื่อนไขก่อน แล้วเข้าสู่ส่วนลำดับงานคำสั่งที่กำหนดไว้ การเขียนคำสั่ง while ต้องกำหนดนิพจน์แบบตรรกะเป็นเงื่อนไขมีค่าในหน่วยความจำเป็น.
องค์ประกอบของโปรแกรม
คำสั่งเพื่อการกำหนดเงื่อนไข
CE 112 บทที่ 5 การทำซ้ำในภาษา C
PHP LANGUAGE.
โครงสร้างภาษาซี.
หน่วยที่ 1 ระบบคอมพิวเตอร์
ฟังก์ชั่น function.
ปฏิบัติการครั้งที่ 9 ฟังก์ชัน.
การประกาศตัวแปร “ตัวแปร” คือสิ่งที่เราสร้างขึ้นมาเพื่อใช้เก็บค่าต่างๆและอ้างอิงใช้งานภายในโปรแกรม ตามที่เรากำหนดขึ้น การสร้างตัวแปรขึ้นมาเราเรียกว่า.
Arrays.
C Programming Lecture no. 6: Function.
หน่วยที่ 4: คำสั่งควบคุมโปรแกรม (Control Flow Command)
ไวยากรณ์ของภาษาการทำโปรแกรม (1) (Syntax of programming languages)
คำสั่งควบคุมการทำงาน
Lecture 7 ฟังก์ชัน To do: Hand back assignments
Flow Control.
การเขียนโปรแกรมภาษาซี
Page: 1 การโปรแกรมเชิงวัตถุด้วยภาษา JAVA บุรินทร์ รุจจนพันธุ์.. ปรับปรุง 15 มิถุนายน 2550 Structure Programming มหาวิทยาลัยเนชั่น.
การเขียนโปรแกรมภาษาซี
Chapter 4 คำสั่งควบคุมทิศทาง
Introduction to C Language
ตัวแปรกับชนิดของข้อมูล
ง30212 การเขียนโปรแกรมภาษาคอมพิวเตอร์ โรงเรียนปลวกแดงพิทยาคม
ฟังก์ชัน ง30212 การเขียนโปรแกรมด้วยภาษาคอมพิวเตอร์ ศูนย์คอมพิวเตอร์
ง30212 การเขียนโปรแกรมด้วยภาษาคอมพิวเตอร์ โรงเรียนปลวกแดงพิทยาคม
ทบทวน กันก่อน .....กระบวนการแปลโปรแกรม
Week 2 Variables.
Week 5 การทำซ้ำโดย while loop และ do while loop
เสรี ชิโนดม ฟังก์ชัน เสรี ชิโนดม
Computer Programming for Engineers
Week 5 การทำซ้ำโดย while loop และ do while loop
2 /* ข้อความนี้เป็นเพียงคำอธิบาย ไม่มีผลต่อขั้นตอนการ ทำงานของโปรแกรม */ /* A simple program to display a line of text */ #include void main ( ) { printf.
วิทยา กรระสี (วท.บ. วิทยาการคอมพิวเตอร์)
วิชา COSC2202 โครงสร้างข้อมูล (Data Structure)
หลักการเขียนโปรแกรม ( )
อัลกอริทึ่มทำงานวนซ้ำ
หน้าหลัก เมนูหลัก ย้อนกลับ ถัดไป หน้าหลัก เมนูหลัก ย้อนกลับ.
Computer Programming Asst. Prof. Dr. Choopan Rattanapoka
stack #2 ผู้สอน อาจารย์ ยืนยง กันทะเนตร
โครงสร้าง ภาษาซี.
CONDITION Computer Programming Asst. Prof. Dr. Choopan Rattanapoka.
สื่อเสริมการเรียนรู้
แนะนำการเขียนโปรแกรมภาษา C Introduction to C Programming Language
Function ธนวัฒน์ แซ่ เอียบ. What is a function ฟังก์ชันในภาษา C เป็นโปรแกรมที่ถูกออกแบบมาเพื่อ ใช้แก้ปัญหางานใดงานหนึ่งโดยเฉพาะ ฟังก์ชันจะเปลี่ยน input.
1 Functions กนกวรรธน์ เซี่ยงเจ็น สำนักวิชาเทคโนโลยีสารสนเทศ และการสื่อสาร มหาวิทยาลัยนเรศวร พะเยา.
การรับและแสดงผลข้อมูล (Input/Output)
Function. วัตถุประสงค์การเรียนรู้ ให้รู้จักว่าฟังก์ชันคืออะไร ให้รู้จักว่าเราสร้างฟังก์ชันเพื่อจุดประสงค์ใด หรือ เพื่อประโยชน์ใด ให้รู้จักประเภทของฟังก์ชัน.
Syntax and Semantics ธนวัฒน์ แซ่เอียบ.
การทำซ้ำ Pisit Nakjai.
Computer Programming การเขียนโปรแกรม คอมพิวเตอร์ สัปดาห์ที่ 6 คำสั่งควบคุมการทำงานแบบ เงื่อนไขและคำสั่งควบคุมการ ทำงานแบบวนซ้ำ.
Cardinal number = จำนวนนับ Ordinal number = ลำดับที่
A for animals.
D 1 E 1 S E M N G ม. I G I T Vocabulary A L 4.0.
อาจารย์ประจำวิชาอภิธาน
ใบสำเนางานนำเสนอ:

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

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 มีโครงสร้างที่คล้ายคลึงกับ 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-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

สร้าง a.out parser ด้วยการใช้คำสั่งดังข้างล่างนี้ cc main.c -ly การ 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

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 …

โดยที่ 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 }

ตัวอย่างการใช้ Start Condition แปลงตัวเลขจำนวนนับสองหลักไปเป็นการแสดงด้วยตัวหนังสือ โดยให้ input ขึ้นต้นด้วย $ (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; }

case '0' : printf("dollars"); 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 สามารถจะเข้าถึงและนำไปใช้งานได้ภายในกฎของ Yacc Precefined pseudovariables ถูกใช้ในการเข้าถึงค่าต่างๆของ Token ใช้สัญลักษณ์เริ่มต้นด้วย $ (Dollar Sign) แล้วตามด้วยตัวเลข (Integer) โดยที่เลข Integer นี้จะอ้างถึงตำแหน่งของ Terminal symbol ภายใน Rule และ $$ จะอ้างอิงถึง Left-hand nontermal symbol ในกฎดังนี้ result : VAR1 '+' VAR2 '+' VAR3 { $$ = $1 + $3+ $5; };

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

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

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

(ต่อ) [- +\n] return *yytext; [\t] ; . { exit(0); } %% yywrap() { 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 > ./cal 3-1 /* input */ 2 /* ผลลัพธ์ */ 4-2+1 1 /* ผลลัพธ์ */ 5+3+2-1 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,4 2001