P8.1 Generatori skenera i parsera

Слични документи
Razvoj programa, Code::Blocks, struktura programa, printf, scanf, konverzioni karakteri predavač: Nadežda Jakšić

P2.1 Formalne gramatike

Programiranje 2 0. predavanje Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb Prog2 2019, 0. predavanje p. 1/4

Funkcije predavač: Nadežda Jakšić

Microsoft PowerPoint - Programski_Jezik_C_Organizacija_Izvornog_Programa_I_Greske [Compatibility Mode]

P8.2 Pravljenje sintaksnog analizatora

Osnovi programiranja Beleške sa vežbi Smer Računarstvo i informatika Matematički fakultet, Beograd Jelena Tomašević i Sana Stojanović November 7, 2005

Uvod u računarstvo 2+2

Tutoring System for Distance Learning of Java Programming Language

Microsoft PowerPoint - Bitovi [Compatibility Mode]

P11.2 Izbor instrukcija, IBURG

070-ALIP2-udzbenik.indb

Tutoring System for Distance Learning of Java Programming Language

Microsoft PowerPoint - Datoteke [Compatibility Mode]

Microsoft Word - 11 Pokazivaci

PowerPoint Presentation

Uvod u računarstvo 2+2

Grananje u programu predavač: Nadežda Jakšić

Tutoring System for Distance Learning of Java Programming Language

Microsoft PowerPoint - C-4-1

Funkcije predavač: Nadežda Jakšić

Programski jezik C

Programski jezik C

Uvod u računarstvo 2+2

Programiranje 1 Beleške sa vežbi Školska 2007/2008 godina Matematički fakultet, Beograd Jelena Tomašević December 5, 2007

Uvod u računarstvo 2+2

Strukture predavač: Nadežda Jakšić

PowerPoint Presentation

PowerPoint Presentation

P1.2 Projektovanje asemblera

Konstrukcija i analiza algoritama vežbe 10 Nina Radojičić 15. decembar Algoritamske strategije - podeli pa vladaj (divide and conquer) Ova stra

07_PJISP_II_Predavanja

ELEKTROTEHNIČKI FAKULTET UNIVERZITETA U BEOGRADU BEOGRAD, Ispit iz Programiranja 2 Ispit traje 135 minuta Napomene: a) Pažljivo proučite U

P1.1 Analiza efikasnosti algoritama 1

Microsoft Word - 02 Elementi programskog jezika Pascal

3.Kontrlne (upravlja~ke) strukture u Javi

Fortran

Programiranje 1 5. predavanje dodatak Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb Prog1 2018, 5. predavanj

Microsoft PowerPoint - 10-Jednodimenzionalni nizovi.ppt [Compatibility Mode]

Programiranje II Beleške sa vežbi Smer Informatika Matematički fakultet, Beograd Sana Stojanović 1

PROGRAMIRANJE Program je niz naredbi razumljivih računalu koje rješavaju neki problem. Algoritam je postupak raščlanjivanja problema na jednostavnije

PRIRODNO MATEMATIČKI FAKULTET U NIŠU DEPARTMAN ZA RAČUNARSKE NAUKE Utorak, godine PRIJEMNI ISPIT IZ INFORMATIKE 1. Koja od navedenih ekste

Uvod u PHP

Microsoft PowerPoint - 13-Funkcije_2.ppt [Compatibility Mode]

Računarski praktikum I - Vježbe 03 - Implementacija strukture string

Datoteke predavač: Nadežda Jakšić

PowerPoint Presentation

Programiranje predavanje Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb Prog1 2016, 10. predavanje p. 1

KDP

Uvod u takmičarsko programiranje

Програмирај!

P11.3 Analiza zivotnog veka, Graf smetnji

Programski jezici i strukture podataka 2018/2019. Programski jezici i strukture podataka Računarske vežbe vežba 10 Zimski semestar 2018/2019. Studijsk

I grupa 1. Napisati program koji izračunava i ispisuje zbir 4 najveća od pet brojeva unetih sa standardnog ulaza. ulaz izlaz Analiza: 1.

Programiranje 2 popravni kolokvij, 15. lipnja Ime i prezime: JMBAG: Upute: Na kolokviju je dozvoljeno koristiti samo pribor za pisanje i brisanj

Konverzije, operatori, matematičke funkcije predavač: Nadežda Jakšić

Računarski praktikum I - Vježbe 01 - Uvod

Microsoft Word - CAD sistemi

1. OPĆE INFORMACIJE 1.1. Naziv kolegija Programiranje 1.6. Semestar Nositelj kolegija dr.sc. Bruno Trstenjak, v. pred Bodovna vrijednost

Microsoft PowerPoint - OOPpredavanja05 [Compatibility Mode]

Microsoft PowerPoint - 03-Slozenost [Compatibility Mode]

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature opti

Tutoring System for Distance Learning of Java Programming Language

Programiranje u C-u ili C++-u Pseudo-slučajni brojevi; Dinamička alokacija memorije 1 ZADACI SA ČASA Zadatak 1 Napraviti funkciju koja generišlučajan

PROMENLJIVE, TIPOVI PROMENLJIVIH

P9.2 Optimizujuci kompajler, prednji deo

P1.3 Projektovanje makroasemblera

PHP kod

Microsoft PowerPoint - 11.Programski_Jezik_C_ulaz-izlaz [Compatibility Mode]

P3.2 Paralelno programiranje 2

Algoritmi i arhitekture DSP I

Programiranje 2 7. predavanje Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb Prog2 2019, 7. predavanje p. 1/7

Programiranje 1 drugi kolokvij, 2. veljače Ime i prezime: JMBAG: Upute: Na kolokviju je dozvoljeno koristiti samo pribor za pisanje i brisanje,

Microsoft PowerPoint - MR - Vjezbe - 03.ppt [Compatibility Mode]

Microsoft PowerPoint - 12-Funkcije_1.ppt [Compatibility Mode]

Teorija skupova - blog.sake.ba

KATUŠIĆ ANTONIO.pdf

Inženjering informacionih sistema

6-8. ČAS Celobrojno programiranje Rešavamo sledeći poblem celobrojnog programiranja: Gde pretpostavljamo da je A celobrojna matrica dimenzije,. Takođe

Microsoft PowerPoint - 07-DinamickeStrukturePodataka

Algoritmi

MIP-heuristike (Matheuristike) Hibridi izmedu metaheurističkih i egzaktnih metoda Tatjana Davidović Matematički institut SANU

PowerPoint Presentation

Programski jezici i strukture podataka

Programiranje 1

Konstrukcija i analiza algoritama Nina Radojičić februar Analiza algoritama, rekurentne relacije 1 Definicija: Neka su f i g dve pozitivne fun

Oblikovanje i analiza algoritama 5. predavanje Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb OAA 2017, 5. pr

Slide 1

Microsoft Word - Zadaci za samostalno vjezbanje 4.doc

Рачунарска интелигенција

Programiranje 1 9. predavanje Saša Singer web.math.pmf.unizg.hr/~singer PMF Matematički odsjek, Zagreb Prog1 2018, 9. predavanje p. 1/6

LAB PRAKTIKUM OR1 _ETR_

Државно такмичење године 5. и 6. разред 1. [pločice] Правоугаону терасу димензија d s центиметара квадратних треба поплочати коришћењем плочица

PASCAL UVOD 2 II razred gimnazije

NIZOVI

1, 2, 3, кодирај! Активности циклуса 4 Пројект «Аркадне игре» - Час 6: Програмирање падања новчића (наставак) Доминантна дисциплина Математикa Резиме

Sveucilište u Zagrebu

Kombinatorno testiranje

Slide 1

Microsoft Word - 1.Operacije i zakoni operacija

Транскрипт:

Генератор лексичких и синтаксних анализатора Пример спецификације језика Flex генератор лексичких анализатора Bison генератор синтаксних анализатора 1

Граматика => Језик (Бесконачан) скуп реченица 2

Граматика <=> Језик (Бесконачан) скуп реченица 3

Различите граматике могу дефинисати исти језик S -> E E -> T T -> iks E -> E plus T S -> E E -> T T -> iks E -> T plus E S -> E E -> T T -> iks E -> E plus E S -> E S -> iks S -> S plus iks E -> iks E -> E plus E Jezik: iks iks plus iks iks plus iks plus iks iks plus iks plus iks plus iks... 4

Синтаксни анализатор јесте део језика Низ терминалних симбола A(J) G није део језика 5

Синтаксни анализатор јесте део језика Низ терминалних симбола A(G) J није део језика 6

Синтаксни анализатор јесте део језика Низ терминалних симбола A(G) Да ли ово имамо на улазу? J није део језика 7

Синтаксни анализатор јесте део језика Низ терминалних симбола A(G) Да ли ово имамо на улазу? Не, имамо низ знакова J није део језика 8

Синтаксни анализатор Два приступа: Написати граматику језика код које су знакови терминални симболи. Анализу обавити у два корака: Низ знакова L(G) јесте терминални симбол (који?) низ терминалних симбола Лексички анализатор није терминални симбол 9

Лексички анализатор Позови лексер Низ знакова L(G) Добави наредни терминални симбол A(G) 10

Лексички анализатор Слично као синтаксни анализатор Другачија граматика - једноставнија Терминални симболи су знаци Регуларна граматика (нижег нивоа од контекстно слободних граматика): G (N, T, Σ, P) Где је P скуп смена (продукција) које могу имати један од следећа три облика: B -> α, где B припада N, а αприпада T B -> αc (или B -> Cα), где C припада N B -> ε, где је ε празан знаковни низ 11

Лексички анализатор Алгоритам за одређивање да ли је неки улаз део језика дефинисаног регуларном граматиком (лексички исправан) заснива се на детерминистичком аутомату са коначним бројем стања (DFA Deterministic Finite Automata). То је јако повољан и ефикасан алгоритам. 12

Лексички анализатор 13

Прављење лексичког анализатора Можемо га правити ручно Коришћењем DFA Или неком другом, мање ефикасном техником (али опет довољно ефикасном) Можемо га генерисати помоћу алата Алат који на основу спецификације генерише лексички анализатора Један од таквих алата је Flex Flex генерише анализатор који се заснива на DFA Пример лексичког анализатора за језик Tiger 14

Прављење лексичког анализатора Како специфицирамо терминале језика? тј. регуларну граматику којом су дефинисани? Не пишемо продукције Много напорно и нејасно Користимо регуларне изразе Чест механизам за претраживање текста 15

Нотација регуларних израза a Обичан знак који стоји сам за себе ε Празан стринг Такође празан стринг M N Избор М или N M N Спајање М и N, иза М иде N MN Други начин да се напише спајање М и N M* Понављање М, нула или више пута M+ Понављање М, један или више пута M? Једно или ни једно појављивање М [a-za-z] Избор знака из скупа знакова. Тачка, означава један знак, било који, осим новог реда abc Низ знакова, било којих знакова 16

Коришћење регуларних израза Коришћењем овог језика можемо специфицирати лексичке симболе (токене) програмских језика Кључна реч if Идентификатор (почиње словом, а затим могу и слова и цифре) Цели бројеви Позитивни реални бројеви (53.7.28 4.) 17

Коришћење регуларних израза Коришћењем овог језика можемо специфицирати лексичке симболе (токене) програмских језика Кључна реч if if Идентификатор (почиње словом, а затим могу и слова и цифре) [a-z][a-z0-9]* Цели бројеви -?[0-9]+ Позитивни реални бројеви (53.7.28 4.) ([0-9]+. [0-9]*) ([0-9]*. [0-9]+) 18

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације %{ int brojdjura = 0; %} %% djura brojdjura += 1;. ; #include <stdio.h> int main() { yylex(); printf( %d, brojdjura); return 0; } 19

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације %{ %} %% djura return 1; pera return 2; mika return 3; #include <stdio.h> int main() { int toktype = yylex(); while (toktype!= 0) { print( %d, toktype); toktype = yylex(); } return 0; } 20

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације %{ %} %% djura return 1; pera return 2; mika return 3; #include <stdio.h> int main() { int toktype = yylex(); while (toktype!= 0) { print( %s, yytext); toktype = yylex(); } return 0; } 21

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације %{ %} %% djura return 1; pera return 2; mika return 3; #include <stdio.h> int main() { yyin = fopen( datoteka.txt, r ); int toktype = yylex(); while (toktype!= 0) { print( %s, yytext); toktype = yylex(); } return 0; } 22

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације %{ %} %% djura return 1; pera return 2; mika return 3; #include <stdio.h> int main() { yyin = fopen( datoteka.txt, r ); int toktype = yylex(); while (toktype!= 0) { print( %s, %d, yytext, yylen); toktype = yylex(); } return 0; } 23

Flex: генератор лексичких анализатора Генерише Це код на основу лексичке спецификације За сваки тип лексичког симбола наводи се Регуларни израз и акција у Це језику, нпр. %{ /* C declarations */ #include tokens.h /* definitions of IF, ID, NUM, */ #include errormsg.h union {int ival; string sval; double fval;} yylval; int charpos = 1; #define ADJ {EM_tokPos = charpos; charpos += yyleng;} %} digits [0-9]+ /* Lex definition of digits */ %% /* Regular expressions and actions */ if {ADJ; return IF;} [a-z][a-z0-9]* {ADJ; yylval.sval = String(yytext); return ID;} digits {ADJ; yylval.ival = atoi(yytext); return NUM;} (digits. [0-9]*) ([0-9]*. digits) {ADJ; yyval.fval = atof(yytext); return FLOAT} ( -- [a-z]* \n ) ( \n \t )+ { ADJ; /* do nothing */ } 24. {ADJ; error();}

Детаљи Flex спецификације и излаза Излаз Flex-а је Це програм lex.yy.c Који интерпретира DFA и извршава Це код акција Спецификација I део, између %{ и %}: Це #include и декларације Потребне за Це код до краја датотеке II део: скраћенице рег. израза и декларације стања Нпр. digits је скраћеница за [0-9]+ III део: регуларни изрази и акције Акције враћају целобројну вредност (int), која означава врсту пронађеног симбола Даље читање: Flex упутство на Интернету 25

Пример вишег програмског језика Tiger аутор A.W.Apple, Modern Compiler Impl. Tiger је мали језик са Угњежденим функцијама Вредностима слогова са имплицитним показивачима Низовима Целобројним и стринг променљивама Неколико конструкција за структуирану контролу тока Спецификација: Лексика: уобичајени идентификатори и Це коментари Декларације и променљиве и изрази 26

Декларације (1/3) decs је низ декларација типова, вредности и функција decs {dec}, где {x} може бити празан скуп ε dec tydec vardec fundec Типови података tydec type type-id = ty ty type-id {tyfields} овде су { и } терминални симболи array of type-id tyfields ε id: type-id{, id : type-id} 27

Декларације (2/3) Уграђени типови: int и string Свака декларација низа или слога ствара нов тип Чак иако су сва поља идентична са неким претходним Међусобно рекурзивни типови Сваки циклус рекурзије мора проћи кроз тип слога или низа Нпр. саморекурзија: type intlist = {head:int, tail:intlist} Међурекурзија: type tree = {key:int, children:treelist} type treelist = {head:tree, tail:treelist} Декларације променљивих: vardec var id := exp var id:type-id := exp 28

Декларације (3/3) Декларације функција: fundec function id (tyfields) = exp fundec function id (tyfields) : type-id = exp Међусобно рекурзивне процедуре и функције, нпр. function treeleaves(t : tree) : int = if t=nil then 1 else treelistleaves(t.children) function treelistleaves(l : treelist) : int = if L=nil then 0 else treeleaves(l.head) + treelistleaves(l.tail) 29

Променљиве и изрази (1/4) Л-вредност је локација која се чита или у коју се пише lvalue id променљиве Изрази lvalue lvalue. id поља слогова (структура) lvalue [ exp ] елементи низова Изрази без вредности Позив процедуре, додела, if-then, while, break, и понекад if-thenelse nil нула, припада сваком типу слога Низ израза (exp; exp;... exp) израчунава изразе с лева у десно коначна вредност је вредност последњег израза у низу Нема вредност: () и let израз без ичега између in и end 30

Променљиве и изрази (2/4) Целобројни литерал низ децималних цифара Стринг литерал низ знакова између наводника Специјални знаци се наводе након знака \ (\n, \t, итд.) Негација целобројном изразу може претходити знак - Позив функције: id() или id(exp{,exp}) Аритметички израз: exp op exp, gde op +, -, *, /, захтевају и производе целе бројеве Поређење: exp op exp, gde op =, <>, >, <, >=, <=, пореде операнде и производе 1 (тачно) или 0 (нетачно) Поређење стрингова: два стринга су иста ако им је садржај идентичан 31

Променљиве и изрази (3/4) Изрази са Буловим операторима: exp op exp, где је op & или Приоритет оператора: unarni -, *, /, +, -, =, <>, >, <, >=, <=, &, Асоцијативност оператера: *, /, +, -, су асоцијативни у лево; оператори поређења нису асоцијативни. Додела вредности: lvalue := exp If-then-else: if exp1 then exp2 else epx3, где exp2 и exp3 морају бити истог типа, тај тип је и тип резултата If-then: if exp1 then exp2, где exp2 не производи вредност While: while exp1 do exp2, где exp2 не производи вредност For: for id := exp1 to exp2 do exp3, exp3 нема вредност 32

Променљиве и изрази (4/4) Break: прекида извршење најближе петље (while или for) Let: израз let decs in expseq end евалуира декларације decs, а затим израчунава низ израза expseq, чији коначни резултат је резултат задњег израза у низу. Заграде: могу се користити за синтаксно груписање израза 33

Пример: програм queens (1/2) /* A program to solve the 8-queens problem */ let var N := 8 type intarray = array of int var row := intarray [ N ] of 0 var col := intarray [ N ] of 0 var diag1 := intarray [N+N-1] of 0 var diag2 := intarray [N+N-1] of 0 function printboard() = (for i := 0 to N-1 do (for j := 0 to N-1 do print(if col[i]=j then " O" else "."); print("\n")); print("\n")) 34

Пример: програм queens (2/2) function try(c:int) = if c=n then printboard() else for r := 0 to N-1 do if row[r] = 0 & diag1[r+c] = 0 & diag2[r+7-c] = 0 then (row[r] := 1; diag1[r+c] := 1; diag2[r+7-c] := 1; col[c] := r; try(c+1); row[r] := 0; diag1[r+c] := 0; diag2[r+7-c] := 0) in try(0) end 35

Лексички анализатор за Tiger (1/4) tokens.h typedef union { int pos; int ival; string sval; } YYSTYPE; extern YYSTYPE yylval; # define ID 257 # define STRING 258 # define INT 259 # define COMMA 260 # define COLON 261 # define SEMICOLON 262 # define LPAREN 263 # define RPAREN 264 # define LBRACK 265 # define RBRACK 266 # define LBRACE 267 # define RBRACE 268 # define DOT 269 # define PLUS 270 # define MINUS 271 # define TIMES 272... # define IF 284 # define THEN 285 # define ELSE 286 # define WHILE 287 # define FOR 288 # define TO 289 # define DO 290 # define LET 291 # define IN 292 # define END 293 # define OF 294 # define BREAK 295 # define NIL 296 # define FUNCTION 297 # define VAR 298 # define TYPE 299 36

Лексички анализатор за Tiger (2/4) tiger.lex (1/2)... %% " " {adjust(); continue;} \n {adjust(); EM_newline(); continue;} \t {adjust(); EM_newline(); continue;} "," {adjust(); return COMMA;} ":" {adjust(); return COLON;} ";" {adjust(); return SEMICOLON;} "(" {adjust(); return LPAREN;} ")" {adjust(); return RPAREN;} "[" {adjust(); return LBRACK;} "]" {adjust(); return RBRACK;} "{" {adjust(); return LBRACE;} "}" {adjust(); return RBRACE;} "." {adjust(); return DOT;} "+" {adjust(); return PLUS;} "-" {adjust(); return MINUS;} "*" {adjust(); return TIMES;} "/" {adjust(); return DIVIDE;} "=" {adjust(); return EQ;}... 37

Лексички анализатор за Tiger (3/4) tiger.lex (2/2)... while {adjust(); return WHILE;} for {adjust(); return FOR;} to {adjust(); return TO;} break {adjust(); return BREAK;} let {adjust(); return LET;} in {adjust(); return IN;} end {adjust(); return END;} function {adjust(); return FUNCTION;} var {adjust(); return VAR;} type {adjust(); return TYPE;} array {adjust(); return ARRAY;} if {adjust(); return IF;} then {adjust(); return THEN;} else {adjust(); return ELSE;} do {adjust(); return DO;} of {adjust(); return OF;} nil {adjust(); return NIL;} [a-za-z][a-za-z0-9"_"]* {adjust(); yylval.sval=string((char*)yytext); return ID;}... 38

Лексички анализатор за Tiger (3/4) driver.c int main(int argc, char** argv) { char* fname = argv[1]; EM_reset(fname); yyin = fopen(fname, r ); while (1) { int tok = yylex(); if (tok == 0) break; switch(tok) { case ID: case STRING: printf("%10s %4d %s\n", tokname(tok), EM_tokPos, yylval.sval); break; case INT: printf("%10s %4d %d\n", tokname(tok), EM_tokPos, yylval.ival); break; default: printf("%10s %4d\n", tokname(tok), EM_tokPos); } } fclose(yyin); return 0; 39 }

Лексички анализатор за Tiger (4/4) Излаз: прог. queens трансформисан у низ симбола FUNCTION 210 ID 219 printboard LPAREN 229 RPAREN 230 EQ 232 LPAREN 241 FOR 242 ID 246 i ASSIGN 248 INT 251 0 TO 253 ID 256 N MINUS 257 INT 258 1 DO 262 LPAREN 265 FOR 266 ID 270 j... function printboard() = (for i := 0 to N-1 do (for j := 0 to N-1 do print(if col[i]=j then " O" else "."); print("\n")); print("\n"))... 40

Прављење синтаксног анализатора Можемо га правити ручно Разни могући алгоритми. Разликују се по граматикама са којима могу да се носе и по ефикасности (меморијском и процесорском заузећу) Типична ручна техника: Синтаксни анализатор са рекурзивним спуштањем Можемо га генерисати помоћу алата Алат који на основу граматике генерише синтаксни анализатор Један од таквих алата је Bison (део GNU-а) Bison генерише анализатор који се заснива на LALR алгоритму 41

Граматика независна од контекста (контекстно слободна) Спецификација језика у облику низа продукција Пример: језик праволинијских програма Нетерминални симболи: S, E и L; почетни симбол је S Терминални симболи: id print num, + ( ) := ; Пример реченице у овом језику id := num; id := id + (id := num + num, id) Може потицати од следећег улаза (изворног кода): a := 7; b := c + (d := 5 + 6, d) Имена a,b,c и бројеви 5,6,7 су семантичке вредности симбола S S ; S S id := E S print ( L ) E id E num E E + E E (S, E) L E L L, E 42

Изводи реченица и стабла анализе Постоји више извода исте реченица: pera := 15; djole := 13 + pera S S ; S S id := E S print ( L ) E id E num E E + E E (S, E) L E L L, E 43

Изводи реченица и стабла анализе Постоји више извода исте реченице, нпр. Крајњи леви: увек се смењује крајњи леви нетерминал Крајњи десни: увек се смењује крајњи десни нетерминал Стабло синтаксне анализе Сваки симбол у изводу се спаја са симболом из ког је изведен Два различита извода могу имати исто стабло синтаксне анализе S S ; S id := E ; S id := num ; S id := num ; id := E id := num ; id := E + E 44

Нејасне граматике Граматика је НЕЈАСНА ако може да произведе исту реченицу са два различита стабла Нпр. граматика SLP-а је нејасна јер за реченицу id:=id+id+id постоје два стабла синтаксне анализе 45

Проблем нејасне граматике: Различита значења! Пример 1: Граматика Калкулатор 1 Два стабла за реченицу 1-2-3 Ако се стабло користи за интерпретирање значења Прво значење: (1-2)-3 = -4 Друго значење: 1-(2-3) = 2 E id E num E E * E E E / E E E + E E E E E (E ) 46

Други пример различитих значења! Пример 2: Граматика Калкулатор 1 Два стабла за реченицу 1+2*3 Ако се стабло користи за интерпретирање значења Прво значење: (1+2)*3 = 9 Друго значење: 1+(2*3) = 7 E id E num E E * E E E / E E E + E E E E E (E ) 47

Решење проблема: Јасна граматика Калкулатор 2 Задатак: Покушајмо да пронађемо јасну граматику Калкулатор 2, која дефинише (прихвата) исти језик Решење: Прво, оператор * треба да има првенство у односу на + Друго, сви оператори треба да буду асоцијативни у лево Ово се постиже увођењем нових нетерминалних симбола T и F Да би * била асоцијативна у десно, уместо ово продукције: T T * F писали би ову продукцију T F * T. E E + T E E T E T T T * F T T / F T F F id F num F ( E ) 48

Bison: генератор синт. анализатора Генерише Це код на основу улазне спецификације Bison је наследник алата Yacc Улазна спец. се састоји од три дела, раздвојених са %{, %} и %% (врло слично Flex-у) Програмски код: Це код који ће користи акције из доњих делова Декларације: списак терминала, нетерминала, итд. Граматичка правила (продукције): нетерминал : дефиниција, нпр. exp : exp PLUS exp {семантичка акција} где је exp нетерминал (израз) а PLUS терминал (оператор +) Излаз је Це код: y.tab.h и y.tab.c Приликом генерисања води рачуна о конфликтима 49

Пример спецификације (без акција) %{ int yylex(void); void error(char* s) {...} %} %token ID WHILE BEGIN END DO IF THEN ELSE SEMI ASSIGN %start prog %% prog: stmlist stm: ID ASSIGN ID WHILE ID DO stm BEGIN stmlist END IF ID THEN stm IF ID THEN stm ELSE stm stmlist: stm stmlist SEMI stm S id := id S while id do S S begin L end S if id then S S if id then S else S L S L L ; S 50

Синтаксни анализатор за Tiger (1/6) tiger.grm (1/3) %union { int pos; int ival; string sval; } %token <sval> ID STRING %token <ival> INT %token COMMA COLON SEMICOLON LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE DOT PLUS MINUS TIMES DIVIDE EQ NEQ LT LE GT GE... %nonassoc EQ NEQ LT LE GT GE %left MINUS PLUS %left TIMES DIVIDE %left DOT %left NEG 51

Синтаксни анализатор за Tiger (2/6) tiger.grm (2/3) %start input %% input: stm ; stm: assignment ifthenelse ifthen while for break compoundstm let ; exp: lvalue NIL INT STRING NEG INT functioncall arithmetic comparison booleanexp recordcreation arraycreation ; 52

Синтаксни анализатор за Tiger (3/6) tiger.grm (3/3) arithmetic: exp PLUS exp exp MINUS exp exp TIMES exp exp DIVIDE exp MINUS exp %prec NEG ; comparison: exp EQ exp exp NEQ exp exp GT exp exp LT exp exp GE exp exp LE exp ; booleanexp: exp AND exp exp OR exp ; decs: /* empty */ decs dec ; dec: tydec vardec fundec ; tydec: TYPE ID EQ ty ; ty: ID LBRACE tyfields RBRACE ARRAY OF ID ; tyfields: /* empty */ typeidlist ; 53

Синтаксни анализатор за Tiger (4/6) Изгенерисани y.tab.h /* Tokens. */ #ifndef YYTOKENTYPE #define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { ID = 258, STRING = 259, INT = 260, COMMA = 261, COLON = 262, SEMICOLON = 263, LPAREN = 264, RPAREN = 265, LBRACK = 266, RBRACK = 267, LBRACE = 268,... 54

Синтаксни анализатор за Tiger (5/6) parsetest.c програм за тестирање #include <stdio.h> #include <stdlib.h> #include "util.h" #include "errormsg.h int main(int argc, char** argv) { yyin = stdin; yyout = stdout; parse(argv[1]); return 0; } void parse(char* fname) { EM_reset(fname); if (yyparse() == 0) /* parsing worked */ fprintf(stderr, "Parsing successful!\n"); else fprintf(stderr, "Parsing failed\n"); } 55

Синтаксни анализатор за Tiger (6/6) Добро је почети са једноставним тестовима pera pera.mika pera[djoka] pera[mika.djoka] nil () (pera;mika) (pera;mika;djoka) 100 "string" -100 foo() foo(pera) foo(pera, mika) pera + mika pera - mika pera * mika pera / mika -pera + mika pera = mika pera <> mika pera > mika pera < mika pera >= mika pera <= mika "string1" = "string2" pera & mika pera mika pera & mika djoka (pera mika) & djoka pera {} pera {mika=djoka} pera {mika=djoka, laza=nil} type tippera = perintip type tippera = {} type tippera = {id1:id1tip} 56

Bison у практичној употреби Предности: Једноставније специфицирати језик помоћу граматике Ако је граматика ваљана, сигурније је да ће и анализатор бити ваљан Алат нам помаже у откривању неких концептуалних проблема у граматици Мане: Резултујући анализатор је (мало) спорији од ручно писаног Теже организовање смисленог пријављивања грешака Лоше ношење са нејасним граматикама Теже дебаговање саме граматике (метајезик за описивање граматике уноси индирекцију) 57

Bison у практичној употреби Тренутно се користи за Ruby, PHP, Bash... Користио се за GCC do 2004. CLANG (Це предњи део за LLVM) је одмах писан ручно EDG предњи део се користи у већини комерцијалних Це/Це++ компајлера (Intel, пример) Постоје и други алати: ANTLR, JavaCC... 58