我一直在使用lex和yacc编写一个命令式语言的编译器,今天我完成了语法,事情是我一直在网上阅读每个语法都有一些转移/减少冲突,特别是如果它有if / else语句,通常被称为悬挂if-else,而我的确有if / elsif / else语句但它在编译时没有引发任何冲突,问题是
¿这是否意味着这个语法有缺陷只是因为它没有抛出任何转移/减少冲突?我没有太多经验这样做,但我发现它没有任何问题
如果你想要更多的信息,这个语法中的if / elsif / else语句的产生是这样的:
statement -> ...
------------| initial_conditional_stmt
initial_conditional_stmt: conditional_stmt
-----------------------| conditional_stmt 'else' block
conditional_stmt -> 'if' '(' expression ')' block
------------------| conditional_stmt elsif '(' expression ')' block
块只是括号{}
中的语句列表答案 0 :(得分:3)
没有转变/减少冲突意味着你在语言设计方面做得非常好,而且从不模棱两可。
干得好,给自己轻拍一下,放松一下,从冰箱里取一杯啤酒。
答案 1 :(得分:2)
你没有在这里悬挂其他东西的原因是因为你正在使用一个块而不是正常的声明。
对于你的语法你不能做
if (cond)
if (cond) {
[stuff]
}
else
{
}
你必须这样做
if (cond)
{
if (cond) {
[stuff]
}
else
{
}
}
每个嵌套的if语句必须在匹配{}内。在你的情况下,这会以牺牲一点点陌生的语法为代价来消除悬空。与普通"正常"相比语法"阻止"将是"声明"这也可能是另一个if语句,从而导致经典的转移/减少冲突。
答案 2 :(得分:0)
您最好使用以下代码:
%nonassoc XIF
%nonassoc ELSE
stmt: IF expr stmt %prec XIF
| IF expr stmt ELSE stmt
这是一种改变if和else之间优先级冲突的方法。
希望它有所帮助。