Compiler construction 简单求和乘法语法的反向求导问题

Compiler construction 简单求和乘法语法的反向求导问题,compiler-construction,grammar,sablecc,Compiler Construction,Grammar,Sablecc,我在理解如何使用自下而上的解析器(例如,输入字符串1+2*3)从“底部”到“顶部”时遇到了一些困难 下面是我使用的语法(我认为它是正确的,因为它是在制作编译器时发现的) 这是我的反向推导: int(1) T(1) E(1) E(1) plus int(2) E(1) plus T(2) E(1) plus E(2) E(1) plus E(2) times int(3) E(1) plus E(2) times E(3) <-- can't do anything here int(1)

我在理解如何使用自下而上的解析器(例如,输入字符串
1+2*3
)从“底部”到“顶部”时遇到了一些困难

下面是我使用的语法(我认为它是正确的,因为它是在制作编译器时发现的)

这是我的反向推导:

int(1)
T(1)
E(1)
E(1) plus int(2)
E(1) plus T(2)
E(1) plus E(2)
E(1) plus E(2) times int(3)
E(1) plus E(2) times E(3) <-- can't do anything here
int(1)
T(1)
E(1)
E(1)加整数(2)
E(1)加T(2)
E(1)加上E(2)
E(1)加上E(2)乘以int(3)

E(1)加上E(2)乘以E(3)移位-减少冲突是语法中最常见的冲突类型。在你的例子中,T(2)可以减少到E(2),或者时间可以改变。默认情况下,大多数解析器生成器更喜欢移位而不是缩减。但是他们仍然会把T(1)减少到E(1),因为他们知道在T之后再加一个加号是没有意义的。

移位-减少冲突是语法中最常见的冲突类型。在你的例子中,T(2)可以减少到E(2),或者时间可以改变。默认情况下,大多数解析器生成器更喜欢移位而不是缩减。但是他们仍然会将T(1)减少到E(1),因为他们知道在T之后没有加号移位。

我想我明白你的意思,但是我仍然不太确定解析器会发生什么。对于任何给定的状态,解析器是否会尝试所有可能的反向派生,如果至少有两个提供有效派生,则会引发shift-reduce错误,而如果只有一个有效派生,则不会引发问题?我不确定您所说的尝试所有可能的反向派生是什么意思。在你移动int之后,你知道你需要减少到T,但是你可以使用lookahead;如果你看到了一个时间,那么你就转换,否则你就降到E,你也需要在这里使用前瞻;您希望看到一个加号(当您移位时)或一个EOF(当您减少时,在这种情况下意味着终止)。(如果一个更高级的解析器在T后面看到一个int,它会标记一个错误,而不是减少到E,然后注意到错误。)我想我明白你的意思,但我仍然不太确定解析器会发生什么。对于任何给定的状态,解析器是否会尝试所有可能的反向派生,如果至少有两个提供有效派生,则会引发shift-reduce错误,而如果只有一个有效派生,则不会引发问题?我不确定您所说的尝试所有可能的反向派生是什么意思。在你移动int之后,你知道你需要减少到T,但是你可以使用lookahead;如果你看到了一个时间,那么你就转换,否则你就降到E,你也需要在这里使用前瞻;您希望看到一个加号(当您移位时)或一个EOF(当您减少时,在这种情况下意味着终止)。(更高级的解析器如果在T之后看到int,则会标记错误,而不是减少到E,然后注意到错误。)
int(1)
T(1)
E(1)
E(1) plus int(2)
E(1) plus T(2)
E(1) plus E(2)
E(1) plus E(2) times int(3)
E(1) plus E(2) times E(3) <-- can't do anything here