2010-06-30 7 views
10

stavo cercando di analizzare semplice LispCostruire Lisp/Scheme-come con/schema-come il codice flex/bisonte

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

e costruire un albero da esso, ho potrebbe fare il parsing in C senza utilizzare bison (ad esempio, utilizzando solo flex per restituire token e costruire l'albero con ricorsione). Ma, con bison la grammatica, non sono sicuro dove aggiungere il codice per creare l'elenco (cioè, quale regola per associare con accumulare terminale simboli e dove collegare un elenco costruito per nodo padre).

mia grammatica è simile a quello qui: Lisp grammar in yacc la grammatica è corretta e in grado di riconoscere il codice.

+1

Mi sono ricollocato da 'flex' a' gnu-flex' nonostante il contro-consiglio qui: http://meta.stackexchange.com/questions/26460/tag-for-two-flexes/26708#26708 semplicemente perché è confondere molti visitatori del sito per vedere l'icona di Adobe sul tag. Spero che questo venga risolto presto. Buona fortuna per avere una risposta alla tua domanda. – bernie

+5

Non hai bisogno di flex o di bisonti per analizzare semplici espressioni S. Dovresti essere in grado di codificarlo come un semplice parser di discesa ricorsivo con un lexer arrotolato a mano per atomi, parentesi e uno skipper di spazi bianchi in qualcosa come cento linee di C o meno. Gli interpreti LISP originali certamente l'hanno fatto con solo un pezzetto di codice. –

+2

Ira: Vero che non c'è bisogno di un parser, ma "lexer arrotolato a mano" funziona solo per i consueti sottoinsiemi di giocattoli con cui solitamente le persone finiscono. Alcuni Lisp/Schemi hanno token che possono diventare * molto * pelosi. Per il tuo divertimento, ecco un esempio di costante numerica valida in [Racket] (http://racket-lang.org/): '# e # x + e # s + e @ -e # l-e'. –

risposta

3

Hai provato a inserire il codice per aggiungere un elemento all'elenco corrente in ogni atomo e codice per gestire un albero di elenchi quando elabori le parentesi? Sembra che il modo più semplice a meno che non si esegue in altri problemi:

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");} 
    ; 

Questo presuppone che l'utente mantenere un punto di genitore in ogni elenco struct.

+0

Ciao Amoss, non ho provato con un puntatore genitore, proverò questo approccio. Grazie. – vyom

+0

vjom: Funzionava? Se è così, per favore dai a Amoss il suo dovuto accettando la risposta :) – Baggers