【发布时间】:2011-02-07 06:38:15
【问题描述】:
我正在尝试学习 shift-reduce 解析。假设我们有以下语法,使用强制操作顺序的递归规则,受到ANSI C Yacc grammar 的启发:
S: A;
P
: NUMBER
| '(' S ')'
;
M
: P
| M '*' P
| M '/' P
;
A
: M
| A '+' M
| A '-' M
;
我们想使用 shift-reduce 解析来解析 1+2。首先,将 1 作为数字移位。我的问题是,它是否会被简化为 P,然后是 M,然后是 A,最后是 S?它怎么知道在哪里停下来?
假设它确实一直减少到 S,然后移动“+”。我们现在有一个堆栈,其中包含:
S '+'
如果我们移动“2”,则减少可能是:
S '+' NUMBER
S '+' P
S '+' M
S '+' A
S '+' S
现在,在最后一行的任一侧,S 可以是 P、M、A 或 NUMBER,并且在任何组合都是文本的正确表示的意义上,它仍然是有效的。解析器是如何“知道”它的
A '+' M
这样它就可以将整个表达式简化为A,然后是S?换句话说,它如何知道在移动下一个令牌之前停止减少?这是 LR 解析器生成的关键难点吗?
编辑:以下是对问题的补充。
现在假设我们解析1+2*3。一些移位/减少操作如下:
Stack | Input | Operation
---------+-------+----------------------------------------------
| 1+2*3 |
NUMBER | +2*3 | Shift
A | +2*3 | Reduce (looking ahead, we know to stop at A)
A+ | 2*3 | Shift
A+NUMBER | *3 | Shift (looking ahead, we know to stop at M)
A+M | *3 | Reduce (looking ahead, we know to stop at M)
这是正确的(当然,它还没有完全解析)?此外,是否提前 1 符号也告诉我们不要将 A+M 减少到 A,因为这样做会导致读取 *3 后不可避免的语法错误?
【问题讨论】:
-
“1+2”不会对您提供的语法产生移位/减少冲突吗?
-
不。 Bison 毫无怨言地接受了它(当然,在用 %token NUMBER\n%%\n...\n%% 包装之后)。
标签: parsing theory context-free-grammar formal-languages shift-reduce