找到一个等效的LR语法

时间:2015-12-30 06:15:50

标签: parsing compiler-construction grammar context-free-grammar lr

我正在尝试为pascal找到LR(1)或LR(0)语法。这是我的语法的一部分,它不是LR(0),因为它有转移/减少冲突。

EXPR --> AEXPR | AEXPR realop AEXPR
AEXPR --> TERM | SIGN TERM | AEXPR addop TERM
TERM --> TERM mulop FACTOR | FACTOR
FACTOR --> id | num | ( EXPR )
SIGN --> + | - 

(大写单词是变量和小写单词,+, - 是终端)

如您所见,EXPR --> AEXPR | AEXPR realop AEXPR导致LR(0)解析的转换/减少冲突。我尝试添加一个新变量,以及其他一些方法来为此找到一个等效的LR(0)语法,但我没有成功。

我有两个问题。

首先:这个语法是LR(1)语法吗?

第二:是否有可能找到这个语法的LR(0)等价物? LR(1)相当于什么?

1 个答案:

答案 0 :(得分:2)

是的,你的语法是LR(1)语法。 [见下面的注释]

这不仅仅是导致LR(0)冲突的第一个生产。在LR(0)语法中,您必须能够在不咨询先行符号的情况下预测是否移位或减少(以及减少哪些生产)。这是一项限制性很强的要求。

尽管如此,有一种语法可以识别同一种语言。它不是一个等价语法,因为它不会产生相同的解析树(或任何有用的解析树),所以它取决于你认为等价的东西。

EXPR → TERM | EXPR OP TERM
TERM → num | id | '(' EXPR ')' | addop TERM
OP   → addop | mulop | realop

以上工作忽略了运算符优先级;它将表达式简单地视为常规语言TERM (op TERM)*。 (我将+ | -更改为addop,因为我无法看到您的扫描仪如何工作,但这并不重要。)

通常用于使LR(1)表达式语法适合LL(1)解析的转换,但由于允许LL(1)检查先行字符,因此能够以正常方式处理运算符优先级。 LL(1)"等价物"语法不会生成具有正确运算符关联性的解析树 - 所有运算符都变为右关联 - 但可以通过简单的树旋转来恢复正确的解析树。

在LR(0)语法的情况下,运算符优先级已经丢失,树转换几乎等同于重新分析输入,使用诸如分流码算法之类的东西来创建真正的解析树。

注意

我不相信所呈现的语法是正确的语法,因为它使得一元加号和减号绑定比乘法更紧密,结果-3*4被解析为-(3*4)。碰巧的是,大部分时间都没有语义差异,但对我来说仍然感觉不对。我会把语法写成:

EXPR   → AEXPR  | AEXPR realop AEXPR
AEXPR  → TERM   | AEXPR addop  TERM
TERM   → FACTOR | TERM  mulop  FACTOR
FACTOR → num | id | '(' EXPR ')' | addop FACTOR

这使得一元运算符更紧密地绑定。 (如上所述,我假设addop正好是+-。)