什么时候模糊的语法或生产规则可以吗? (野牛转移/减少警告)

时间:2009-03-01 12:56:52

标签: parsing bison shift-reduce-conflict

肯定有很多关于解决转移/减少错误的文档和方法。野牛文档建议正确的解决方案通常只是期望它们并处理它。

当你有这样的事情时:

S: S 'b' S | 't'

你可以像这样轻松解决它们:

S: S 'b' T | T
T: 't'

我的问题是:是否更好的方法是让语法模糊不清,%期望转移/减少问题,或者尝试调整语法以避免它们更好?我怀疑存在平衡,这是基于作者的需求,但我真的不知道。

4 个答案:

答案 0 :(得分:2)

您可以使用运算符优先级指导冲突解决。将'b'声明为左关联运算符或右关联运算符,并且至少涵盖了这种情况。

对于更复杂的模式,只要最终解析器在所有情况下都能产生正确的结果,警告就不用担心了。虽然如果你不能使用声明来获得正确的结果,你将不得不重写语法。

答案 1 :(得分:2)

当我读到它时,你的问题是“什么时候模糊的语法或制作规则好吗?”

首先考虑您所描述的语言。将含糊不清的生产规则纳入语言的含义是什么?

您的示例描述的语言可能包含以下表达式:t b t b t b t

在第二个示例中解析的表达式为(((( t ) b t) b t ) b t ),但在模糊的语法中,它也可能变为( t b ( t b ( t b ( t))))甚至( t b t ) b ( t b t )。哪个可能有效可能取决于语言。如果b运算符模型减法,它实际上不应该是模糊的,但如果它是加法,它可能没问题。这实际上取决于语言。

要考虑的第二个问题是,在解决冲突后,生成的语法源文件最终会是什么样子。与其他源代码一样,语法意味着人类阅读,其次也是计算机阅读。更喜欢能够更清楚地解释解析器尝试从语法中做什么的符号。也就是说,如果解析器正在执行一些可能未定义的行为,例如,以急切语言评估函数参数的顺序,则使语法看起来不明确。

答案 2 :(得分:1)

在我上一学期的编译课程中,我们使用了bison,并为pascal的子集构建了一个编译器。

如果语言足够复杂,您将会遇到一些错误。只要你明白为什么他们在那里,以及你需要做些什么来消除它们,我们发现它没问题。如果有什么东西存在,但是由于这种行为会像我们想要的那样起作用,并且需要很多思考和努力才能使其值得(并且还使语法复杂化),我们不管它。只要确保你完全理解错误,并将其记录在某个地方(即使是你自己),这样你就可以随时了解错误。

一旦事情真正涉及,这是一个成本/收益分析,但恕我直言,修复它应该被认为是第一,然后实际弄清楚工作将是什么(如果该工作打破别的东西,或使其他更难),从那里开始永远不要把它们当作普通的地方。

答案 3 :(得分:1)

当我需要证明语法是明确的时,我倾向于首先将其写为Parsing Expression Grammar,然后手动将其转换为我用于项目需要的工具集的任何语法类型。根据我的经验,这种证明水平的需求非常罕见,因为我遇到的大多数转移/减少冲突都是相当微不足道的,以显示(按照你的例子的顺序)的正确性。