Wybrane narzędzia do tworzenia analizatorów leksykalnych i składniowych w C/C++ by Kapitol Team

Podobne dokumenty
Generatory analizatorów

10. Translacja sterowana składnią i YACC

Wybrane narzędzia do tworzenia analizatorów leksykalnych i składniowych w C/C++ Narzędzia, zastosowanie oraz próby rankingu.

Bison - generator analizatorów składniowych

Generator YACC: gramatyki niejednoznaczne

Podstawy generatora YACC. Bartosz Bogacki.

Wybrane narzędzia do tworzenia analizatorów leksykalnych i składniowych w Javie

Metody Kompilacji Wykład 8 Analiza Syntaktyczna cd. Włodzimierz Bielecki WI ZUT

Metody Kompilacji Wykład 7 Analiza Syntaktyczna

Wykład 5. Jan Pustelnik

Analizator syntaktyczny

Semantyka i Weryfikacja Programów - Laboratorium 6

Analiza leksykalna 1. Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

L E X. Generator analizatorów leksykalnych

Zadanie analizy leksykalnej

Generator LLgen. Wojciech Complak Generator LLgen - charakterystyka. Generator LLgen -składnia specyfikacji

Włączenie analizy leksykalnej do analizy składniowej jest nietrudne; po co więc jest wydzielona?

Metody Realizacji Języków Programowania

Plan wykładu. Kompilatory. Literatura. Translatory. Literatura Translatory. Paweł J. Matuszyk

Laboratorium z użyciem analizatora leksykalnego FLEX

Analiza leksykalna i generator LEX

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Języki formalne i automaty Ćwiczenia 4

PARADYGMATY I JĘZYKI PROGRAMOWANIA. lex/flex i yacc/bison w- 4 (2014)

Generator YACC: gramatyki niejednoznaczne

Podstawy programowania skrót z wykładów:

Generator skanerów Flex

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Translacja sterowana składnią w generatorze YACC

Podstawy Kompilatorów

Wprowadzenie do szablonów szablony funkcji

Wprowadzenie do szablonów szablony funkcji

Zajęcia nr 1 Podstawy programowania. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Metody Kompilacji Wykład 13

Flex - generator analizatorów leksykalnych

Wstęp do programowania

ZYKI BEZKONTEKSTOWE (KLASA

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Gramatyka operatorowa

Program We Kompilator Wy Źródłowy

Podstawy Kompilatorów

Podstawy kompilatorów. Generator LLgen. Wojciech Complak.

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 26 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 28

Szablony funkcji i szablony klas

Podstawy Kompilatorów

Projektowanie klas c.d. Projektowanie klas przykład

Metody Kompilacji Wykład 3

Język ludzki kod maszynowy

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Operacje wejścia/wyjścia (odsłona druga) - pliki

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podział programu na moduły

Przesłanianie nazw, przestrzenie nazw

Wprowadzenie do kompilatorów

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

5. JĘZYKI BEZKONTEKSTOWE (KLASA "2") GRAMATYKI BEZKONTEKSTOWE AUTOMATY ZE STOSEM DETERMINISTYCZNE JĘZYKI BEZKONTEKSTOWE I

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Uproszczony schemat działania kompilatora

Zasady programowania Dokumentacja

Język C++ Różnice między C a C++

1. Wprowadzenie do C/C++

Języki formalne i automaty Ćwiczenia 2

Programowanie Komputerów

Programowanie obiektowe

Wstęp do Programowania 2

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Obiektowa implementacja parsera klasy LL(1)

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 25 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 38

Operacje wejścia/wyjścia odsłona pierwsza

Pytania sprawdzające wiedzę z programowania C++

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com

Podstawy Informatyki sem. I 2014/2015 studia zaoczne Elektronika i Telekomunikacja!

Podstawy programowania w C++

Ćwiczenia nr 11. Translatory. Wprowadzenie teoretyczne

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Metody Kompilacji Wykład 1 Wstęp

Programowanie w językach

Gramatyki atrybutywne

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Analiza leksykalna 1. Języki formalne i automaty. Dr inż. Janusz Majewski Katedra Informatyki

1. Wprowadzenie do C/C++

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

I - Microsoft Visual Studio C++

Wstęp do programowania

1 Pierwsze kroki w C++ cz.3 2 Obsługa plików

KONSTRUKCJA KOMPILATORÓW

Programowanie w Sieci Internet Blok 2 - PHP. Kraków, 09 listopada 2012 mgr Piotr Rytko Wydział Matematyki i Informatyki

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Języki i techniki programowania Ćwiczenia 2

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Język C++ wykład VIII

Podstawy Programowania

Podstawy algorytmiki i programowania - wykład 4 C-struktury

Signals + Threads: Qt vs. Boost

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

Transkrypt:

Wybrane narzędzia do tworzenia analizatorów leksykalnych i składniowych w C/C++ by Kapitol Team

Flex a generatory skanerów C++ 2 sposoby wymuszenia stworzenia skanera w C++ flex -+ flexfile.l użycie %option c++ wygenerowany plik: lex.yy.cc lex.yy.cc załącza plik FlexLexer.h definiujący dwie klasy FlexLexer interfejs głównego skanera yyflexlexer dziedziczy po FlexLexer, pomocnicze funkcje kompilacja g++ lex.yy.cc -o skaner -lfl

Yet-another Object Oriented Lex (YooLex) Podział pliku wejściowego na 3 sekcje (jak w Flexie) sekcja 1: sekcja 2: sekcja 3: - instrukcje na początku pliku wyjściowego - nazwy wyrażeń regularnych - warunki startu - prolog umieszczony na początku funkcji yylexcase( ) - definicje wyrażeń regularnych - epilog umieszczony na końcu w/w funkcji (w celach ewentualnego sprzątania) - instrukcje dodane na końcu pliku wyjściowego (pomocnicze klasy, funkcja main)

Yet-another Object Oriented Lex (YooLex) instrukcje dodane na początku pliku wyjściowego %{ // code here will be echoed at the beginning of the generated // C++ source file. #include <iostream> using namespace std; %} nazwy wyrażeń regularnych IDENT [A-Za-z_][A-Za-z0-9_]* NUMBER [1-9][0-9]* 0 warunki startu - wspólny %s CONDITION1 CONDITION2 - wyłączny %x CONDITION1 CONDITION2

Yet-another Object Oriented Lex (YooLex) prolog umieszczony na początku funkcji yylexcase( ) %{ // code here will be inserted at the beginning of class::yylexcase () function. // It is useful to has some code that does something whenever yycase () is // called. static int yycasecallcounter = 0; %} definicje wyrażeń regularnych ab(c/d)*e <<EOF>> {std::cout<< Hello world! <<std::endl;} {std::cout<< End of file. <<std::endl; yyterminate(); } epilog umieszczony na końcu funkcji yylexcase( ) %{ // code here will be inserted at the end of class::yylexcase () function. myobject.cleanup( ); %}

Yet-another Object Oriented Lex (YooLex) instrukcje dodane na końcu pliku wyjściowego int main (void) { std::ios::sync_with_stdio (false); DefaultLex scanner; while (scanner.yylex() >= 0) ; return 0; } Kształt całego pliku wejściowego lexera: {section 1} %% {section 2} %% {section 3}

Yet-another Object Oriented Lex (YooLex) Konfiguracja pliku wejściowego: %option main line char /*w sekcji 1*/ main generuj domyślną line zliczanie linii w pliku wejściowym skanera char zliczanie znaków w pliku wejściowym skanera Pomocnicze zmienne, funkcje, makra YYTextType _yytext; yyleng size_t yygetcharnum () const; size_t yygetlinenum () const; bool yyisbol () const; yyterminate () /*dopasowany ciąg znaków*/ /*makro zwracające długość dopasowanego ciągu*/ /*dla %option char, zwraca dotychczasową liczbę dopasowanych znaków w pliku wejściowym*/ /*dla %option line, zwraca dotychczasową liczbę linii w pliku wejściowym*/ /*zwraca true, jeśli jesteśmy na początku linii*/ /*kończy pracę skanera*/

Yet-another Object Oriented Lex (YooLex) Przykład: Skaner analizujący tekst i zwracający jego statystyki /*Statystyki dla tekstu*/ %{ #include <iostream> using namespace std; %} string [A-Za-z_][A-Za-z_0-9]* emptysign [ \t\n] text {string}{emptysign}+ %option main line char %% static int counter=0; {emptysign}*{text} {++counter;std::cout<<_yytext<<" "<<std::endl;} <<EOF>> {std::cout<<"naliczyłem się: "<<counter<<" słów, "; std::cout<<_yylinenum<<" linii, "; std::cout<<_yycharnum<<" liter."<<std::endl; yyterminate();} %%

Yet-another Object Oriented Lex (YooLex) Generacja parsera z pliku plik.l:./yoolex plik.l - generuje pliki DefaultLex.cc i DefaultLex.hh pliki skanera Kompilacja parsera parser: g++ DefaultLex.cc -Iścieżka_do_katalogu_yoolex -o parser

Parsery (Analizatory składniowe) parser kolejno pobiera tokeny od analizatora leksykalnego (lexera) i stwierdza czy dana sekwencja mogła zostać wygenerowana przez zadaną z góry gramatykę parsery tworzy się do gramatyk bezkontekstowych (np. gramatyk języków programowania - łatwe w przetwarzaniu w przeciwieństwie do gramatyk opisujących język naturaly) typy parserów: a)top-down b)bottom-up

Parsery (Analizatory składniowe) top-down analiza zaczyna się od symbolu startowego; następnie podejmowana jest próba wyprowadzania z niego coraz bardziej szczegółowych konstrukcji, która w razie sukcesu kończy się wyprowadzaniem zadanego słowa wejściowego;przykładem parserów top-down są parsery korzystające z algorytmu LL (wywód lewostronny) bottom-up analiza zaczyna się od tokenów podawanych na wejście (terminali);podejmowana jest próba z redukowania ciągu tokenów do symbolu startowego; przykładem są tu parsery korzystające z algorytmu LR (wywód prawostronny)

Lemon stworzony na potrzeby projektu SQLite napisany w C generuje parsery w C i C++ generuje parsery LALR(1) parsery LALR przetwarzają wiecej gramatyk bezkontekstowych niż SLR, ale mnie niż LR(1);LALR stanowi kompromis między wielkością tablicy parsingu, a ilością gramatyk, które przetwarza cechy generatora: reentrant ten sam fragment kodu może być dzielony między wiele niezależnych procesów thread-safe - bezpieczny, gdy mamy do czynienia z aplikacją wykorzystującą wielowątkowość

cechy generatora (c.d): Lemon implementuje koncepcję destruktora terminali i nieterminali szybszy od yacc czy bisona przekształca bezkontekstowe gramatyki (Context Free Grammar) nie ma wbudowanego lexera; jest kompatybilny z flexem gramatykę umieszcza się w pliku z roszerzeniem.y (tak jak w bisonie) ogólna postać reguł: expr ::= expr TOK_NR1 expr1. expr nieterminal TOK_NR1 terminal

Lemon wykonywanie akcji związanych z dopasowaniem reguły expr ::= expr TOK_NR1 { akcja; } wykonywanie operacji na wartościach (zwracanie) %type expr {int} deklarujemy, że nieterminal 'expr' zwraca wartość typu int (możemy sobie tworzyć własne typy) expr(a) ::= expr(b) OPERATOR expr(c) { A = B + 2 * C; } domyślnie konfilikty shift/reduce są rozwiązywane na korzyść shift, reduce/reduce na korzyść tej reguły, która pierwsza pojawiła się w definicji gramatyki; jednak lemon pozwala na zmienianie tego zachowania przy użyciu tzw. precedence rules, które odnoszą się do terminali, np: %left PLUS MINUS. %left DIVIDE TIMES.

Lemon konflikty (c.d) Przy czym reguły znajdujące się 'wyżej' mają niższy priorytet, stąd: expr PLUS expr DIVIDE expr zostanie zinterpretowane jako: expr PLUS (expr DIVIDE expr) Oprócz ww. zależności są jeszcze reguły decydujące o kolejności wiązania: %left OP1. %right OP2. expr OP1 expr OP1 expr zostanie zinterpretowane jako (expr OP1 expr) OP1 expr z kolei: expr OP2 expr OP2 expr jako:expr OP2 (expr OP2 expr)

Elkhound stworzony na potrzeby projektu Elsa (parser C/C++) napisany w C++ generowane parsery w C++ (i Ocaml) generuje parsery GLR GLR (Generalized LR) parsery GLR działają tak samo jak LR, z tym, że tablica parsingu może zawierać konfilikty typu shitf/reduce lub reduce/reduce; gdy wykryty zostaje konflikt stos zostaje podzielony na dwie części i każda gałąź jest utrzymywana oddzielnie ma złożoność O(n 3 ) stworzony by radzić sobie z gramatykami niedeterministycznymi i niejednoznacznymi wygenerowane parsery mogą używać dodatkowo algorytmu LR

Elkhound nie ma wbudowanego lexera; można użyc np. flexa jako lexera gramatykę umieszcza się w pliku.gr ogólna postać reguł: nonterm expr { -> expr OPERATOR expr } akcje przy dopasowaniu: nonterm expr { } -> expr OPERATOR expr { akcja; } zwracanie wartości: nonterm(int) expr { } -> a1:expr PLUS a2:expr1 { return a1 + a2; } -> n:literal { return n; }

Elkhound aby zwrócić token jako wartość należy uprzednio zadeklarować jak ma być dany token interpretowany: token(int) LITERAL; priorytety ustala się w następujący sposób precedence { left 20 MUL DIV; // wyższy priorytet, łączność lewostronna right 10 PLUS MINUS; // niższy priorytet, łączność prawostronna }

Bibliografia http://www.compilers.net/dir/scannergens.htm http://www.compilers.net/dir/parsergens.htm http://dmoz.org/computers/programming/compilers/lexer_and_parser_generators/ http://www.gnu.org/software/flex/manual/html_node/flex_19.html http://yoolex.sourceforge.net/ http://www.hwaci.com/sw/lemon/ http://www.sqlite.org/ http://linuxgazette.net/106/chirico.html http://en.wikipedia.org/wiki/glr_parser http://www.cs.berkeley.edu/~smcpeak/elkhound/ http://en.wikipedia.org/wiki/lexical_analysis http://en.wikipedia.org/wiki/parser http://en.wikipedia.org/wiki/compiler-compiler http://www.google.pl