A Tutorial. George J. Klir State University of New York (SUNY) Binghamton, New York 13902, USA

Podobné dokumenty
Konstruktory překladačů

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE LEXIKÁLNÍ ANALÝZA

George J. Klir. State University of New York (SUNY) Binghamton, New York 13902, USA

PROGRAMOVÁNÍ V C++ CVIČENÍ

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE STRUKTURA PŘEKLADAČE

Úvod do programovacích jazyků (Java)

Překladač a jeho struktura

Tvorba výrazu: speciální znaky shellu se uvádějí do apostrofů jednotlivé části výrazu se oddělují mezerou

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Operační systémy. Cvičení 4: Programování v C pod Unixem

IUJCE 07/08 Přednáška č. 1

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Operační systémy. Cvičení 3: Programování v C pod Unixem

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Preprocesor a koncepce (větších) programů. Úvod do programování 2 Tomáš Kühr

Virtuální počítač. Uživatelský program Překladač programovacího jazyka Operační systém Interpret makroinstrukcí Procesor. PGS K.

Programovací jazyk C++ Hodina 1

Lexikální analýza (Obsah)

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Problém, jehož různé instance je třeba často řešit Tyto instance lze vyjádřit větami v jednoduchém jazyce

Odvozené a strukturované typy dat

Univerzita Karlova v Praze. Matematicko-fyzikální fakulta DIPLOMOVÁ PRÁCE. Karel Fišer. Moderní implementace LALR(1) konstruktoru

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Koncepce (větších) programů. Základy programování 2 Tomáš Kühr

Třídy a struktury v C++

Programovací jazyk Pascal

Parsování v Haskellu, knihovna Parsec

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Programování v C++ 1, 1. cvičení

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje

Úvod z historie. Kompilátory. Kompilace / Kompilátor Compile / Compiler. Pojem kompilátoru. Úvod z historie

Programovací jazyk C(++) C++ area->vm_mm->locked_vm -= len >> PAGE_SHIFT;

Lexikální analýza. Rozhraní lexikálního analyzátoru. Miroslav Beneš Dušan Kolář. M. Beneš, D. Kolář: Lexikální analýza 1. Lexikální analýza 2

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele

Lexikální analýza. Miroslav Beneš Dušan Kolář

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

Algoritmizace a programování

Jazyk C++ I. Šablony 2

Lexikální analýza Teorie programovacích jazyků

Západočeská univerzita v Plzni Dokumentace překladače PL/0 v PHP Předmět KIV/FJP

Úvod do Operačních Systémů

Konečný automat. Jan Kybic.

X36UNX 16. Numerické výpočty v sh příkazy expr, bc, dc. Zdeněk Sojka

Základy programování (IZP)

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

PB161 Programování v jazyce C++ Přednáška 10

Formální jazyky a překladače

Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky -

Jazyk C++, některá rozšíření oproti C

Výpočetní modely pro rozpoznávání bezkontextových jazyků zásobníkové automaty LL(k) a LR(k) analyzátory

Paradigmata programování 1

Vědecký tutoriál, část I. A Tutorial. Vilém Vychodil (Univerzita Palackého v Olomouci)

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Bitové operátory a bitová pole. Úvod do programování 2 Tomáš Kühr

Úvod do programování. Lekce 1

Začínáme vážně programovat. Řídící struktury Přetypování Vstupně výstupní operace Vlastní tvorba programů

PSK3-9. Základy skriptování. Hlavička

Algoritmizace a programování

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Semestrální práce implementuje univerzální tokenizer založený na stavovém automatu. Jsou implementovány následující automaty:

Implementace LL(1) překladů

Programovací jazyk. - norma PASCAL (1974) - implementace Turbo Pascal, Borland Pascal FreePascal Object Pascal (Delphi)

NSWI096 - INTERNET JavaScript

1. Od Scheme k Lispu

Sémantika Tabulka symbolů Intermediální kód Typová kontrola, přetypování Statická a dynamická sémantika. Sémantická analýza.

Programovanie v jazyku C - ti to zratam...

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

Lekce 6 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

8) Jaké jsou důvody pro použití víceprůchodového překladače Dříve hlavně kvůli úspoře paměti, dnes spíše z důvodu optimalizace

DTP Základy programování Úvod do předmětu

2 Datové typy v jazyce C

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 23, 2016

Dílčí příklady použití jazykových konstrukcí v projektu. Jazyk C Příklady. Pravidla překladu v gmake. Zadání

Algoritmizace a programování. Ak. rok 2012/2013 vbp 1. ze 44

Programování v C++ 1, 14. cvičení

awk programovatelný filtr

int => unsigned int => long => unsigned long => float => double => long double - tj. bude-li:

Programovací jazyk C(++) C++ area->vm_mm->locked_vm -= len >> PAGE_SHIFT;

Jazyk C Program v jazyku C má následující strukturu: konstanty nebo proměnné musí Jednoduché datové typy: Strukturované datové typy Výrazy operátory

Základy programování (IZP)

Střední odborná škola a Střední odborné učiliště, Hořovice

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY

Programování v jazyce C pro chemiky (C2160) 12. Specifické problémy při vývoji vědeckého softwaru

Objektově orientované programování

Programování v Pythonu

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Programování v jazyce C pro chemiky (C2160) 10. Grafická knihovna g2

Př. další použití pointerů

PŘETĚŽOVÁNÍ OPERÁTORŮ

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a

Vstupní a vstupní proudy v C++

Algoritmizace a programování

Programování 2 (NMIN102) Soubory. RNDr. Michal Žemlička, Ph.D.

Transkript:

A Tutorial Generování syntaktických analyzátorů George J. Klir Jan Konečný State University of New York (SUNY) Binghamton, New York 13902, USA gklir@binghamton.edu Palacky University, Olomouc, Czech Republic prepared for International Centre for Information and Uncertainty, Palacky University, Olomouc!!!! J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 1 / 28

lex & yacc Nástroje pro psaní programů, které zpracovávají (transformují) strukturované vstupy. Dva hlavní požadavky na takové programy: rozdělení vstupu do smysluplných jednotek. nalezení vztahů mezi těmi jednotkami. lex je nástroj pro vytváření lexikálních analyzátorů (též lexerů). yacc (Yet Another Compiler Compiler) je nástroj pro vytváření syntaktických analyzátorů (též parserů). J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 2 / 28

Lex Struktura vstupního souboru: sekce definic %% sekce pravidel %% sekce C kódu Výstupem je kód v C sekce definic definuje makra a importuje hlavičkové soubory v C. Též je možno psát sem jakýkoli kód v C. sekce pravidel spojuje regulární výrazy s kódem v C. Když je rozpoznán text odpovidající regulárnímu výrazu, je spuštěn odpovídající kód. sekce C kódu obsahuje libovolný kód v C, J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 3 / 28

První easy example: Example Specifikace pro desetinná čísla %% [\n\t ] ; -?(([0-9]+) ([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { printf("number\n"); }. ECHO; %% main() { yylex(); } J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 4 / 28

První easy example: Example (cont.) Překlad: > lex first.l > cc lex.yy.c -o first -ll Spuštění:.65ea12 number eanumber J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 5 / 28

Počítání slov Vytvoříme program na počítání slov, podobný UNIXovému programu wc. Definiční sekce: %{ unsigned charcount = 0, wordcount = 0, linecount = 0; %} word [^ \t\n]+ eol \n Sekce pravidel: %% {word} { wordcount++; charcount += yyleng; } {eol} { charcount++; linecount++; }. charcount++; J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 6 / 28

Sekce C kódu: main() { yylex(); printf("%d %d %d\n", linecount, wordcount, charcount); } nedělá to nic zvláštního, jen využívá toho, že lex defaultně čte ze standardního vstupu. pokud bychom to chtěli vylepšit... J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 7 / 28

main(argc,argv) int argc ; char **argv; { if (argc > 1) { FILE *file; file = fopen(argv[l], "r"); if (!file) { fprintf(stderr,"could not open %s\n",argv[1]); exit(1); } yyin = file; } yylex(); printf("%d %d %d\n",charcount, wordcount, linecount); return 0; } J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 8 / 28

Parsování příkazové řádky % { unsigned verbose; char *progname; % } %% -h "-?" -help { printf("usage is: %s [-help -h -? ]" "[-verbose -v] [(-file -f) filename]\n", progname); } -v -verbose { printf ("verbose mode is on\n"); verbose = 1; } J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 9 / 28

%% main(argc, argv) int argc; char **argv; { progname = *argv; yylex(); } Problém: tohle ale ještě nečte z příkazové řádky, ale ze vstupu. Řešení: můžeme předefinovat funkce input a unput, aby zacházely s argv. Problém: ještě nemáme -file <filename>. Řešení: lex umožňuje použít alternativní počáteční stavy a zahrnout tak kontextovou závislost. J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 10 / 28

Generátor syntaktických analyzátorů vstup: gramatika (LL(1), LR(1), SLR, LALR(1)) výstup: syntaktický analyzátor rozhoduje platná slova gramatiky. První co zkusíme: statement NAME = expr expr NUMBER expr + NUMBER expr - NUMBER J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 11 / 28

Shift/Reduce Parsing; trocha velmi zjednodušené teorie Generátor podle gramatiky vytvoří množinu stavů, každý z nich odpovídá možné pozici v jednom nebo více částečně parsovaného pravidla. Parser čte tokeny: pokud token neukončuje pravidlo, uložíme ho na zásobník a přesuneme se jiného stavu =shift, přesun, symboly na zasobníku tvoří pravou stranu pravidla, popnem je, a pushnem levou stranu pravida =redukce. při redukci je spuštěn odpovídající kousek kódu =akce. http://vychodil.inf.upol.cz/publications/white-papers/lalr.pdf J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 12 / 28

Vstup pro yacc vstup má stejnou strukturu jako vstup lexu. Sekce definic %token NAME NUMBER Sekce pravidel %% statement: NAME = expr expr ; expr: expr + NUMBER expr - NUMBER NUMBER ; J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 13 / 28

Hodnoty symbolů a akce každý symbol má hodnotu neterminální symboly mají hodnotu vytvořenou kódem v parseru (ve skutečných parserech různé datové typy union typedef YYSYTYPE). Defaultně je vše int. Kdykoli parser redukuje, spustí uživatelský kód asociovaný k pravidlu akce. Akce se odkazuje na hodnoty symbolů na pravé straně jako $1, $2... a nastavuje hodnotu symbolu na levé straně přes $$. J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 14 / 28

Sekce pravidel (s doplněnými akcemi) statement: NAME = expr expr { printf("= %d\n",$1); } ; expr: expr + NUMBER { $$ = $1 + $3; } expr - NUMBER { $$ = $1 - $3; } NUMBER { $$ = $1; } ; J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 15 / 28

Lexer Abychom mohli vyzkoušet náš parser, potřebujeme mu dodat tokeny. %{ #include "y.tab.h" extern int yylval; %} %% [0-9]+ { yylval = atoi(yytext) ; return NUMBER;} [ \t] ; /* ignore whitespace */ \n return 0; /* logical EOF */. return yytext[0]; %% J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 16 / 28

> yacc -d calc.y > lex calc.1 > cc -c calc y.tab.c lex.yy.c -ly -ll > calc 99+12 = 111 > calc 2 + 3-14+33 = 24 > calc 100 + -50 syntax error J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 17 / 28

Aritmetické výrazy a nejednoznačnost expr: expr + expr { $$ = $1 + $3; } expr - expr { $$ = $1 -$3; } expr * expr { $$ = $1 * $3; } expr / expr { if ($3 == 0) yyerror( "divide by zero") ; else $$ = $1 / $3; } - expr { $$ = -$2; } ( expr ) { $$ = $2; } NUMBER { $$ = $1; } J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 18 / 28

Ta gramatika má ale problém nejednoznačnost. Example Parsujeme 2+3*4 : 2 přesuň NUMBER E redukce E NUMBER E+ přesuň + E+3 přesuň NUMBER E+E redukce E NUMBER Ted můžeme přesunout * a později redukovat přes pravidlo E E*E nebo rovnou redukovat E E+E Neřekli jsme, který operátor má přednost, ani nic o asociativitě. J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 19 / 28

Mohli bychom to řešit přímo v gramatice: expr: expr + mlexp expr - mlexp mlexp ; mlexp: mlexp * primary mlexp / primary primary ; primary: ( expr ) - primary NUMBER ; J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 20 / 28

Můžeme to ale dodat explicitně %left + - %left * / %nonassoc UMINUS J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 21 / 28

statement: NAME = expr expr { printf ("= %d\n", $1) ; } expr: expr + expr { $$ = $1 + $3; } expr - expr { $$ = $1 -$3; } expr * expr { $$ = $1 * $3; } expr / expr { if ($3 == 0) yyerror("divide by zero"); else $$ = $1 / $3;} - expr %prec UMINUS { $$ = -$2; } ( expr ) { $$ = $2; } NUMBER { $$ = $1; } ; %% J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 22 / 28

Proměnné a typované tokeny (a více vyhodnocovaných výrazů) %{ double vbltable[26]; %} %union { double dval; int vblno; } %token <vblno> NAME %token <dval> NUMBER %left + - %left * / %nonassoc UMINUS %type <dval> expression %% J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 23 / 28

statement-list: statement \n statement-list statement \n statement: NAME = expr { vbltable[$l] = $3; } expr { printf ("= %g\n", $1) ; } expr: NAME { $$ = vbltable[$1]; } ; J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 24 / 28

%{ #include <y.tab.h> #include <math.h> extern double vbltable[26]; %} %% ([0-9]+) ([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval.dval=atof(yytext); return NUMBER; } [ \t]; [a-z] { yylval.vblno = yytext[0] - a ; return NAME; } "$" { return 0; /* end of input */ } \n. return yytext[0]; %% J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 25 / 28

v souboru y.tab.h: #define NAME 257 #define NUMBER 258 #define UMINUS 259 typedef union { double dval; int vblno; } YYSTYPE; extern YYSTYPE yylval; Proto uvádíme %token <vblno> NAME %token <dval> NUMBER %type <dval> expression J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 26 / 28

Jak to ještě můžem vylepšit libovolná jména pro proměnné. funkce (sqrt, log, exp) DOMACÍ UKOL... J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 27 / 28

Chcete vědět víc? Bison manual: http://www.gnu.org/software/bison/manual/bison.pdf LALR Gramatiky (VV) http://vychodil.inf.upol.cz/publications/white-papers/lalr.pdf lex & yacc, 2nd Edition By Doug Brown, John Levine, Tony Mason, Publisher: O Reilly Media Released: October 1992 J. Konečný (DAMOL) Generování syntaktických analyzátorů 12. května 2014 28 / 28