Ich versuche, eine Lisp-Grammatik zu bauen. Einfach richtig? Scheinbar nicht.Lisp Grammatik in Yacc
stelle ich diese Eingaben und Fehlermeldungen ...
(1 1)
23 23 23
ui ui
Dies ist die Grammatik ...
%%
sexpr: atom {printf("matched sexpr\n");}
| list
;
list: '(' members ')' {printf("matched list\n");}
| '('')' {printf("matched empty list\n");}
;
members: sexpr {printf("members 1\n");}
| sexpr members {printf("members 2\n");}
;
atom: ID {printf("ID\n");}
| NUM {printf("NUM\n");}
| STR {printf("STR\n");}
;
%%
So nahe, wie ich sagen kann, ich brauche einen einzigen Nicht-Terminal definiert als ein Programm, auf dem der ganze Parse-Baum hängen kann. Aber ich habe es versucht und es schien nicht zu funktionieren.
bearbeiten - das war mein "Top-Terminal" -Ansatz:
program: slist;
slist: slist sexpr | sexpr;
Aber es erlaubt Probleme wie:
(1 1
Edit2: Die FLEX-Code ist ...
%{
#include <stdio.h>
#include "a.yacc.tab.h"
int linenumber;
extern int yylval;
%}
%%
\n { linenumber++; }
[0-9]+ { yylval = atoi(yytext); return NUM; }
\"[^\"\n]*\" { return STR; }
[a-zA-Z][a-zA-Z0-9]* { return ID; }
.
%%
Ein Beispiel für die Überdeckung ...
(1 1 1)
NUM
matched sexpr
NUM
matched sexpr
NUM
matched sexpr
(1 1
NUM
matched sexpr
NUM
matched sexpr
Was ist der Fehler hier?
edit: Der Fehler war im Lexer.
Was wie sieht Ihre Ausgabe aussehen, wenn sie analysiert die (1 1 Ich kann nicht sehen, wie es zu einem Punkt bekommt? das Schließen nicht erwartet). – Bearddo
Könnten Sie bitte auch Ihre Lex/Flex-Datei posten? Vielleicht gibt es einen Fehler. Auch sollten Sie keine Zeichen verwenden (in der Grammatik, wenn Sie einen Lexer verwenden, bin ich nicht wirklich sicher, wie diese miteinander auskommen.) – jpalecek
Was komisch ist, ist, dass selbst die gültige Liste (1 1 1) nicht erscheint eine Übereinstimmung für eine Liste. Ich würde zwei Dinge versuchen, zuerst machen Mitglieder rekursive: Mitglieder: Mitglieder sexpr | sexpr; Zweitens, tauschen Sie die Reihenfolge der Liste in sexpr: list | atom; Sehen, ob das funktioniert. – Bearddo