2009-12-03 9 views
8

Jaki jest najlepszy sposób tworzenia parsera w C++ z pliku z gramatyką?C++ Utwórz parser

+5

W jakim formacie jest "plik z gramatyką"? –

+1

http://stackoverflow.com/questions/1669/learning-to-write-a-compiler jest kanonicznym pytaniem o to, jak na kompilatorach i tłumaczach tutaj. Wiele dobrych linków tam. Aby ręcznie zbudować godne rekurencyjne podejście, spójrz na samouczek Crenshaw. – dmckee

Odpowiedz

17

też chcieć rzucić okiem na te linki:

+0

Po drugie. Dokumentacja Boost jest naprawdę pomocna. – anno

+1

Proponuję nie używać 'boost :: spirit', jeśli planujesz kompilator jakiejkolwiek przyzwoitej wielkości - czasy kompilacji dla parserów zbudowanych z' boost :: spirit' zwykle stają się bardzo duże, co czyni nawet bardzo małe zmiany PITA (ponieważ wszystko odbywa się za pomocą szablonów) –

8

Istnieją flex i bison. Lex & Kuzyni Yacc, którzy biorą pod uwagę C++ istnienie.

3

Czy obejrzałeś Lex and Yacc? Cytując z sekcji 5 połączonego dokumentu:

mój ulubiony sposób, aby parser C++ jest mieć Lex wygenerować C zwykły plik, a następnie pozwolić YACC generowania kodu C++ . Kiedy następnie połączysz aplikację , możesz napotkać pewne problemy z , ponieważ kod C++ domyślnie nie będzie mógł znaleźć funkcji C , chyba że powiedzieliście, że te funkcje są zewnętrznymi "C".

+0

Lex i Yacc zostały zastąpione przez Flex i Bison. –

2

Najlepszym sposobem utworzenia parsera jest użycie lex i yacc.

+3

Nikt nie może odpowiedzieć na pytanie o * najlepsze *, ale naprawdę się zbliżyłeś - lex & yacc cousins ​​flex & bison biorą C++ pod uwagę. –

+0

Przyjąłem, że pytanie dotyczyło ręcznego pisania parsera w C++. – Dima

2

Użyłem bison, znalazłem przykłady w sam raz dla mojego poziomu. Był w stanie stworzyć z nią prosty kalkulator, oczywiście może zrobić znacznie więcej.

Na przykład kalkulator zajął 1 + 2 * 3 i zbudował drzewo składniowe. Dokumentacja nie opisała jednak, jak zbudować drzewo, co zajęło mi trochę czasu na opracowanie.

Gdybym szedł znowu, zaglądałbym w "antlr", ponieważ wyglądał dobrze i był dobrze obsługiwany.

Martin.

9

To zależy w dużej mierze od gramatyki. Zazwyczaj lubię parsery rekursywne, które są zwykle pisane ręcznie (choć można je wygenerować z opisu gramatyki).

Jeśli masz zamiar użyć generatora analizatora składni, istnieją naprawdę dwa dobre wybory: Byacc i Antlr. Jeśli chcesz czegoś, co jest (rozsądnie) kompatybilne z Yacc, to Byacc jest (zdecydowanie) najlepszym wyborem. Jeśli zaczynasz od początku, bez istniejącego kodu ani doświadczenia, które faworyzuje używanie czegoś kompatybilnego z Yacc, Antlr prawie na pewno jest twoim najlepszym wyborem.

Od tego czasu wspomniałem także o Bison. Uniknęłabym Bizona jak zaraza, którą to jest. Porada Brooksa "Zaplanuj wyrzucenie jednego" dotyczy tutaj. Robert Corbett (autor Byacc) napisał Bison jako swoją pierwszą próbę do generatora parsera. Niestety, podarował go GNU zamiast go wyrzucać. W klasycznym przypadku marketingu pokonującego doskonałość techniczną, Bison jest szeroko stosowany (a nawet zalecany przez tych, którzy nie wiedzą lepiej), podczas gdy Byacc pozostaje stosunkowo mało znany.

Edytuj: Nienawidzę tego robić, ale ponieważ jest to również wspomniane, będę również komentować Boost.spirit. Chociaż może to być najfajniejszy przykład szablonowego programowania meta, ma kilka problemów, które sprawiają, że zalecam, aby nie próbować go poważnie wykorzystać.

  1. Skompiluj z nim czas może stać się nieznośny - 10 minut jest powszechne, a większa/bardziej złożona gramatyka może potrwać jeszcze dłużej (zakładając, że kompilator się nie zawiesza).
  2. Jeśli popełnisz jakiś błąd, może on i często będzie generować szalenie długie komunikaty o błędach, które są praktycznie niemożliwe do odczytania. Komunikaty o błędach z ciężkiego kodu szablonu są i tak bardzo złe, a Spirit podkreśla system bardziej niż prawie wszystko.

Uwierzcie mi: fakt, że można napisać coś w rodzaju Ducha w ogóle jest na granicy między imponującym a zadziwiającym - ale nadal bym go używał tylko wtedy, gdy byłbym pewien, że gramatyka, z którą miałem do czynienia (i zawsze pozostanie) całkiem mały i prosty.