我试图理解,bison如何为这个简单的语法构建表格:
input: rule ;
rule: rule '+' '1'
| '1' ;
我能够计算LR(1)转换表和项目集,但我不了解状态3是如何构建和运行的:
State 3
1 input: rule . [$end]
2 rule: rule . '+' '1'
'+' shift, and go to state 5
$default reduce using rule 1 (input)
对于默认的减少规则,我应该放置' r1'进入每个符号的GOTO表的所有单元格。但是对于转换规则,我应该放置' s5'进入' +'的列终端(此单元格已包含' r1')。对我来说,这看起来像转移/减少冲突。但不适合野牛。请解释一下' [$ end]' lookahead symbol出现在此状态,以及LR状态机整体处理此状态的方式。
答案 0 :(得分:0)
default
表示“其他一切”,而非“一切”。换句话说,首先填写指定的操作,然后对任何其他前瞻符号使用默认操作。
如果没有默认操作,则任何未指定的超前符号的操作都是错误。默认的reduce操作通常用于减少表大小,否则算法会触发错误。此优化可能会导致延迟报告错误,但在消耗另一个输入之前将始终检测到错误,正是因为错误操作永远不会被默认移位替换。 (实际上,许多解析器生成器根本不使用默认的移位操作。)
如果您查看.output
文件开头显示的语法,您会看到它已经通过制作进行了扩充:
0 $accept: input $end
Yacc / bison总是添加类似的产品,以确保完整输入与开始符号匹配。 (当然,非终端input
将被用%start
指令声明的任何起始符号或语法中的第一个非终结符替换。)
除了减少$accept
符号导致输入被接受之外,此规则没有什么特别之处。 (你可以在状态4中看到。)
$end
是检测到EOF时自动生成的特殊终端符号。 (更准确地说,它是令牌值为0的终端,扫描器返回以指示文件结束:(f)lex生成的扫描器自动执行此操作。