我有一个Yacc程序来检查数字是否为0 ^ n 1 ^ n。
%start S
%%
S:'0' S '1' {printf("Success\n");}|;
%%
(所有标记都在lex文件中定义)
我得到的输出如下
0011
Success
Success
syntax error
1100
syntax error
我理解为什么成功打印两次,但第一次输出中的语法错误是什么?
此外,bison
,LALR(1)解析器生成器如何执行此任务?
答案 0 :(得分:1)
语法错误来自于您的语法无法识别空字符串这一事实,因此一旦减少了所有'1' S '0'
制作,就无法取得进展。
Bison拒绝接受这种语法,但很容易解决:
%start S
%%
S: '1' S '0'
| ;
%%
只要看一下语法,就应该清楚如何用一个令牌前瞻来解析字符串。实际上,语法是LL(1);你只需要遇到1
的堆栈(或计数器)。如果这不是一个充分的解释,请启用bison的跟踪功能并观察解析。
答案 1 :(得分:1)
问题是你的语法只匹配无限的字符串 - 你的语法所描述的语言中没有有限的字符串。
您需要添加一个带有限字符串的“基本案例”,因此它可以接受从中构建的字符串或字符串。显而易见的情况是空字符串(对于n = 0):
S : /* empty */
| '0' S '1'
;