将广泛的评论转化为答案:
如果第一个表达式已经被评估为 false,我如何告诉 Bison 不要评估第二个表达式?
进行评估的是您的代码,而不是 Bison;把“责备”归咎于它所属的地方。
你需要检测到你正在处理一个&&
评估 RHS 之前的规则。您可能需要在后面插入一些代码&&
在第二个之前int_expr
如果第一个则暂停评估int_expr
计算结果为 0。您还需要修改所有其他计算代码以检查并遵守“不计算”标志。
或者,您可以让 Bison 进行解析并创建一个程序,在解析完成时执行该程序,而不是在解析时进行评估。这是一系列更大的变化。
您确定要在第二个 int_expr 之前添加一些代码吗?我似乎找不到可行的方法来做到这一点。这是一个很好的技巧,但我找不到一种方法来真正告诉 Bison 不要评估第二个int_expr
,而不破坏整个评估。
您必须编写代码,以便在不应该计算的时候它不会计算。野牛语法是:
| int_expr '&&' {...code 1...} int_expr {...code 2...}
“代码 1”将检查$1
并安排停止评估(设置全局变量或类似的变量)。 “代码 2”将有条件地评估$4
(4 因为“代码 1”现在是 3 美元)。所有求值代码必须遵守“代码 1”的规定——如果“代码 1”表示“不求值”,则不得求值。或者你可以按照我的建议去做aselle https://stackoverflow.com/users/1067799/aselle 建议 https://stackoverflow.com/a/13661138/15168;分别解析和评估。
我赞同阿塞勒的建议UNIX 编程环境 https://rads.stackoverflow.com/amzn/click/013937681X。那里有一整章是关于开发计算器的(他们称之为hoc
对于高阶计算器)值得一读。但请注意,这本书出版于 1984 年,远远早于 C 标准。 C 代码中没有原型,并且(按照现代标准)它需要一些自由。我有hoc6
(最后一个版本hoc
他们描述;还有现代 C 中的版本 1-3) — 如果需要,请联系我(请参阅我的个人资料)。
这就是问题:我不能在规则中间停止评估,因为我不能使用return
(我可以,但没有用;它会导致程序退出)。| intExpr '&&' { if ($1 == 0) {/* turn off a flag */ } } intExpr { /* code */}
我退出后$3
the $4
正在自动评估。
您可以在规则中间停止计算,但您必须对表达式计算代码块进行编码以考虑这种可能性。当我说“停止评估”时,我的意思是“停止计算”,而不是“停止解析器”。解析必须继续;计算值的代码必须仅在需要计算时进行计算,而不是在不需要计算时进行计算。这可能是一个(呃!)全局标志,或者您可能有其他机制。
最好将解析器转换为代码生成器并在解析后执行代码。这种复杂性就是为什么这是一个好的策略。
@JonathanLeffler:你确实是国王!这应该是一个答案!
现在这是一个答案。