![]() |
1
4
下面是一个简化的语法,它显示了相同的问题。 为了建造它,我删除了
我还简化了大部分规则。我这样做是为了说明如何构建 minimal, complete, verifiable example ,正如StackOverflow指南所建议的那样,这使得在仍然允许实际试验的情况下更容易关注问题。(我用的是bison,不是happy,但语法非常相似。)
现在,让我们使用解析器,并假设我们(以某种方式)确定了一个可以匹配的前缀
此时,我们无法判断
如果我们已经完成了属性并即将开始函数,那么现在我们必须减少空的非终结符
在这样的情况下,通过将选项分解到使用非终端的地方来删除空产品通常很有用:
但只是移除
在这种特殊情况下,我们可以做的是巧妙地结合使用左递归和右递归:
通过使第一个列表左递归,第二个列表右递归,我们避免了减少两个列表之间的空非终结符的需要。这反过来又允许解析器决定一个短语是否是
然而,由于许多原因,该解决方案不是很好,其中最重要的原因是它只适用于两个可选列表的串联。如果我们想添加另一个不同类型项目的列表,也可以从
许多语言使用的最简单的方法是允许程序员混合各种列表元素。您可能会认为这是一种糟糕的样式,但并不总是需要通过将其设置为语法错误来惩罚糟糕的样式。 一个简单的解决方案是:
但这并没有将一个块限制为最多一个构造函数,这似乎是一个语法要求。但是,只要
|
![]() |
Kris · Flex-新行无法识别 7 年前 |
![]() |
omn_1 · yylineno为错误报告提供意外结果 7 年前 |
![]() |
lluisrojass · 为什么Yacc/野牛规则没有用? 7 年前 |
![]() |
gornvix · 分析多个文件时出现错误的lex状态 10 年前 |
![]() |
Jason Kleban · 语法规范解决移位/减少冲突 12 年前 |
![]() |
footy · 如何解决2+2和2++2冲突 12 年前 |
![]() |
KAction · Bison意外的标识符错误 12 年前 |