2010-06-30 4 views
10

je cherchais à analyser simplement le code Lisp/comme systèmeBuilding Lisp/Scheme comme arbre d'analyse syntaxique flex/bison

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

et construire un arbre de celui-ci, je pourrait faire l'analyse syntaxique dans C sans utiliser bison (c'est-à-dire, en utilisant seulement flex pour renvoyer des jetons et construire l'arbre avec récursivité). Mais, avec la grammaire bison, je ne suis pas sûr où ajouter le code à construire la liste (i.e., qui règle à associer à la borne accumuler symboles et où lier une liste intégrée au nœud parent).

Ma grammaire est similaire à celle-ci: Lisp grammar in yacc la grammaire est correcte et peut reconnaître le code.

+1

J'ai repassé de 'flex' à' gnu-flex' malgré le contre-conseil ici: http://meta.stackexchange.com/questions/26460/tag-for-two-flexes/26708#26708 simplement parce que c'est déroutant à de nombreux visiteurs sur le site pour voir l'icône Adobe sur l'étiquette. J'espère que cela sera réglé bientôt. Bonne chance d'avoir une réponse à votre question. – bernie

+5

Vous n'avez pas besoin de flex ou de bison pour analyser des expressions S simples. Vous devriez être capable de coder ceci comme un simple analyseur de descente récursif avec une lexer roulé à la main pour les atomes, les parenthèses et un skipper d'espace blanc dans quelque chose comme une centaine de lignes de C ou moins. Les interpréteurs LISP originaux l'ont fait avec seulement un tout petit peu de code. –

+2

Ira: Vraie à propos de l'inutilité d'un analyseur, mais "lexer roulé à la main" ne fonctionne que pour les sous-ensembles de jouets habituels auxquels les gens se retrouvent habituellement. Certains Lisps/Schemes ont des jetons qui peuvent être très poilus. Pour votre divertissement, voici un exemple de constante numérique valide dans [Racket] (http://racket-lang.org/): '# e # x + e # s + e @ -e # l-e'. –

Répondre

3

Avez-vous essayé de placer le code pour ajouter un élément à la liste actuelle dans chaque atome, et de code pour gérer un arbre de listes lorsque vous traitez les parenthèses? Il semble que le moyen le plus facile à moins que vous rencontrez d'autres problèmes:

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

Cela suppose que vous garder un point de parent dans chaque struct liste.

+0

Bonjour Amoss, je n'avais pas essayé avec un pointeur parent, j'essaierai cette approche. Merci. – vyom

+0

vjom: Cela a-t-il fonctionné? Si oui, s'il vous plait donnez Amoss son dû en acceptant la réponse :) – Baggers