Parsing 找到一个等价的LR语法

Parsing 找到一个等价的LR语法,parsing,compiler-construction,grammar,context-free-grammar,lr,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 --> + | - (大写字是变量,小

我正在尝试为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)等价物呢?

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

导致LR(0)冲突的不仅仅是第一个产品。在LR(0)语法中,您必须能够预测是移位还是缩减(以及要缩减的产品),而无需咨询先行符号。这是一个非常严格的要求

尽管如此,有一种语法可以识别同一种语言。它不是一个等价的语法,因为它不产生相同的解析树(或者任何有用的解析树),所以这取决于你认为等价的。
EXPR → TERM | EXPR OP TERM
TERM → num | id | '(' EXPR ')' | addop TERM
OP   → addop | mulop | realop
上述操作忽略了运算符优先级;它只将表达式视为正则语言
术语(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
正是
+
-

谢谢你的回复,你的注释是正确的,但我真的不明白为什么语法是LR(1)。@Arashdn:我不知道如何回应;这是LR(1),因为如果使用标准算法生成LR(1)机器,它就可以工作。您可以说它解决了LR(0)语法中的S/R冲突,因为先行符号(比如,
+
)足以决定是否必须减少左侧参数,或者是否可以在进行减少之前移动运算符(然后是另一个非终端)。@Arashdn:如果您手头没有LR(k)生成器,你可能会喜欢和我一起玩。它并不完美——LALR(1)算法至少有一个错误,它无法找到有效的LALR(1)机器——但它确实生成了可以帮助您可视化的转换表。