2010-06-30 8 views
10

starałem się analizować proste Lisp/program podobny do kodubudynku Lisp/Scheme-jak drzewo parse z Flex/bizon

E.g. (func a (b c d)) 

i zbudować drzewo z niego, I mógłby zrobić parsowania w C bez użycia bison (tj., Używając tylko flex, aby zwrócić tokeny i budować drzewo z rekursją). Ale z gramatyką bison nie jestem pewien, gdzie dodać kod do zbudować listę (tj. , która reguła kojarzyć z gromadzenie symboli terminalu i gdzie połączyć utworzoną listę do węzła nadrzędnego).

Moja gramatyka jest podobna do tej tutaj: Lisp grammar in yacc gramatyka jest poprawna i może rozpoznawać kod.

+1

I retagged od 'flex' do' gnu-flex' mimo przeciw-porady tutaj: http://meta.stackexchange.com/questions/26460/tag-for-two-flexes/26708#26708 tylko dlatego, że to mylące dla wielu odwiedzających stronę, aby zobaczyć ikonę Adobe na tagu. Mam nadzieję, że wkrótce zostanie to posortowane. Powodzenia w uzyskaniu odpowiedzi na twoje pytanie. – bernie

+5

Prawie nie potrzebujesz flex ani bison do parsowania prostych wyrażeń S. Powinieneś być w stanie zakodować to jako prosty parser rekurencyjny z ręcznym zwiniętym lexerem dla atomów, nawiasów i szyfrującego białą przestrzeń w czymś podobnym do setki linii C lub mniejszej. Oryginalni tłumacze LISP z pewnością robili to z niewielką ilością kodu. –

+2

Ira: To prawda, że ​​nie ma potrzeby stosowania parsera, ale "ręcznie zwinięty lexer" działa tylko w przypadku zwykłych podzbiorów zabawek, które zwykle kończą się na ludziach. Niektóre Lisps/Schemes mają tokeny, które mogą być * bardzo * owłosione. Dla Twojej rozrywki, oto przykład prawidłowej stałej liczbowej w [Rakieta] (http://racket-lang.org/): '# e # x + e # s + e @ -e # l-e'. –

Odpowiedz

3

Czy próbowałeś umieścić kod, aby dodać element do bieżącej listy w każdym atomie, i kod do zarządzania drzewem list podczas przetwarzania nawiasów? Wygląda na to najprostszy sposób, chyba że napotkasz inne problemy:

listend: members ')'  { cur = cur->parent; } 
     | ')'    { cur = cur->parent; } 
     ; 

list: '(' listend   { cur = newList(cur);} 
    ; 

atom: ID     { appendAtom(cur, "ID"); } 
    | NUM     { appendAtom(cur, "NUM");} 
    | STR     { appendAtom(cur, "STR");} 
    ; 

ta zakłada, że ​​jesteś zachować punkt rodzic w każdej liście struktury.

+0

Hi Amoss, nie próbowałem ze wskaźnikiem nadrzędnym, spróbuję tego podejścia. Dzięki. – vyom

+0

vjom: Czy to działa? Jeśli tak, proszę, daj Amossowi należne, akceptując odpowiedź :) – Baggers