Intento crear una gramática Lisp. Fácil, ¿verdad? Aparentemente no.Gramática Lisp en yacc
presento estas entradas y recibo errores ...
(1 1)
23 23 23
ui ui
Esta es la gramática ...
%%
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");}
;
%%
Hasta donde puedo decir, que necesito un solo no terminal definido como un programa, sobre el cual todo el árbol de análisis puede colgar. Pero lo intenté y no pareció funcionar.
edición - esta fue mi enfoque "terminal":
program: slist;
slist: slist sexpr | sexpr;
Pero permite que los problemas tales como:
(1 1
Edit2: El código FLEX es ...
%{
#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; }
.
%%
Un ejemplo de coincidencia excesiva ...
(1 1 1)
NUM
matched sexpr
NUM
matched sexpr
NUM
matched sexpr
(1 1
NUM
matched sexpr
NUM
matched sexpr
¿Cuál es el error aquí?
editar: El error estaba en el lexer.
¿Cómo se ve su salida como cuando se analiza el (1 1 No puedo ver cómo se llega a un punto de? sin esperar el cierre). – Bearddo
¿Podría publicar también su archivo lex/flex? Tal vez hay un error. Además, no debe usar caracteres '(' en la gramática si usa un lexer, no estoy seguro de cómo se llevan bien. – jpalecek
Lo extraño es que incluso la lista válida (1 1 1) no aparece como una coincidencia para una lista. Intentaría dos cosas, primero hacer que los miembros se vuelvan recursivos: miembros: miembros sexpr | sexpr; Segundo, cambiar el orden de la lista en sexpr: list | atom; ver si eso funciona. – Bearddo