我正在尝试构建一个Lisp语法.容易,对吗?显然不是.
我提出这些输入并收到错误......
( 1 1) 23 23 23 ui ui
这是语法......
%% 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");} ; %%
就像我所知,我需要一个非终端定义为一个程序,整个解析树可以挂起.但我尝试了它似乎没有用.
编辑 - 这是我的"顶级终端"方法:
program: slist; slist: slist sexpr | sexpr;
但它允许以下问题:
( 1 1
Edit2:FLEX代码是......
%{ #include#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; } . %%
过度匹配的一个例子......
(1 1 1) NUM matched sexpr NUM matched sexpr NUM matched sexpr (1 1 NUM matched sexpr NUM matched sexpr
这里的错误是什么?
编辑:错误发生在词法分析器中.
Lisp语法不能表示为无上下文语法,yacc无法解析所有lisp代码.这是因为lisp功能,如读取评估和可编程读取器.因此,为了只读取任意lisp代码,您需要运行完整的lisp.这不是一些模糊的,未使用的功能,但它实际上是使用的.例如,CL-INTERPOL,CL-SQL.
如果目标是解析lisp的子集,则程序文本是一系列sexprs.
错误实际上是词法分析器.你的括号最后成为最后一个"." 在词法分析器中,并不在解析器中显示为括号.
添加规则,如
\) { return RPAREN; } \( { return LPAREN; }
到词法分析器并在解析器中分别将'(',')'的所有出现更改为LPAREN和RPAREN.(另外,您需要#define LPAREN和RPAREN来定义您的令牌列表)
注意:我不确定语法,可能是反斜杠错了.