Jak skonstruować abstrakcyjne drzewo składni

Mam ogólne pojęcie, czym jest AST, ale chcę wiedzieć, jak go skonstruować.

Jeśli masz gramatykę i drzewo parse, jak skonstruować AST?

Jak to zrobić, jeśli dostajesz gramatykę i wyrażenie?

Author: neuromancer, 2009-11-12

2 answers

Cóż, po pierwsze, gramatyka jest używana do konstruowania drzewa parsującego z wyrażenia. Więc jeśli masz już drzewo parse, nie potrzebujesz gramatyki.

W zależności od tego, ile pracy wykonuje Twój parser, wynikowe drzewo utworzone z parsowania wyrażenia może być już abstrakcyjnym drzewem składni. Albo może to być proste drzewo parsowania, które wymaga drugiego przejścia do skonstruowania ast.

Aby skonstruować drzewo parsowania z gramatyki i wyrażenia, musisz najpierw konwersja gramatyki do kodu roboczego. Zwykle dzielimy pracę na tokenizer, który dzieli strumień wejściowy reprezentujący wyrażenie na listę tokenów, oraz parser, który pobiera listę tokenów i konstruuje z niej drzewo parsowania\AST.

Więc wyrażenie 1 + 2*(3+4) może być podzielone na listę tokenów, jak to:

1 - int
+ - add_operator
2 - int
* - mul_operator
( - lparen
3 - int
+ - add_operator
4 - int
) - rparen

Pierwsza kolumna jest rzeczywistą wartością tekstu. Drugi reprezentuje typ tokena. Tokeny te są przekazywane do parsera, który zbudowany jest z twoja gramatyka i rozpoznaje tokeny i buduje drzewo parse.

Więc, jak można napisać Tokenizer leksykalny i rzeczywisty parser? Możesz toczyć własne ręcznie. Lub, częściej, używać generatora parsera jak coco lub antlr lub lex / yacc. Te narzędzia pobierają opis gramatyki i generują kod dla tokenziera i parsera. (Generatory kodu istnieją również dla większości popularnych języków i niektórych niepopularnych.)

Sposób konstruowania parsera zależy w dużej mierze od tego, co język, którego używasz. Sposób pisania parsera w Haskell jest zupełnie inny niż w, powiedzmy, C.

 42
Author: HS.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 13:58:29

Odpowiem na to z ogólnej perspektywy, nie próbując mówić o lexerach i parserach.

Drzewo parsowania zawiera symbole nie-terminalowe, które są częścią gramatyki bezkontekstowej i pokazuje Łańcuch produkcji, aby uzyskać ciąg składający się z symboli terminalowych, rekurencyjnie lub nie. Więc kiedy masz drzewo parse nie potrzebujesz gramatyki - możesz czerpać gramatykę z drzewa parse.

AST nie zawiera żadnych symboli nieterminalnych. Zawiera tylko symbole.

Przykład:

 E
 |
 E + T
 |   |
 T   M * M
 |   |   |
 M   a   b
 |
 a

, która jest bardzo szybką wersją pokazywania a+a*b. Uwaga, sposób interpretowania abstrakcyjnego drzewa składniowego zależy od pierwszeństwa drzewa, rodzaju przejścia (w kolejności, pre-order, post-order) będzie to ogólna funkcja, którą kodujesz w swoim drzewie wyszukiwania. Jednak, ogólnie rzecz biorąc, AST dla tego drzewa parsowania może wyglądać tak:

   +
 |   |
 a   * 
    | |
    a b
 3
Author: Dhruv Ghulati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-24 19:20:22