在 Bison 中为 && 和 || 启动短路规则运营

2023-12-28

我正在使用 C/C++ 在 Bison 和 Flex 中编写一个简单的计算器(逻辑在 Bison 中完成,C/C++ 部分负责数据结构,例如 STL 等)。

我有以下问题:

在我的计算器中美元符号$表示 i++ 和 ++i (前缀和后缀),例如:

int y = 3;
-> $y = 4
-> y$ = 4

当用户点击:int_expression1 && int_expression2 , if int_expression1被评估为0(即 false),那么我不想野牛评估int_expression2 !

例如 :

int a = 0 ; 
int x = 2 ;

用户点击:int z = a&&x$ ...

所以,变量a被评估为0,因此,我不想评价x,但它仍然增长 1 ...这是 bison/c++ 的代码:

%union
{
    int int_value;
    double double_value;
    char* string_value;
}

%type <int_value> int_expr
%type <double_value> double_expr
%type <double_value> cmp_expr

int_expr:

    | int_expr '&&' int_expr    { /* And operation between two integers */
                      if ($1 == 0) 
                        $$ = 0;
                      else  // calc
                        $$ = $1 && $3;          
                    }

如果第一个表达式已经被评估为 false (即,我如何告诉 bison 不要评估第二个表达式)0) ?


将广泛的评论转化为答案:

如果第一个表达式已经被评估为 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:你确实是国王!这应该是一个答案!

现在这是一个答案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Bison 中为 && 和 || 启动短路规则运营 的相关文章

随机推荐

  • Eclipse Java 模板在重新启动时重置

    有一次我需要在控制台中输入大量文本 所以我将 sysout 模板更改为 System out println word selection cursor 代替 System out println word selection cursor
  • Appcelerator Titanium:CSS 宽度不适用于百分比

    我在 Appcelerator 中制作了一个 HTML 项目 我想要一个全屏画布 所以在 CSS 中我将属性设置为100 不带引号 我发现它不适用于 Appcelerator 我试过了 100 带引号和Ti UI SIZE两者的尺寸都采用奇
  • 如何在不复制的情况下从字符串流中获取字符?

    在不使用 boost 的情况下从字符串流中提取一组字符的正确 C 11 方法是什么 如果可能的话 我想在不复制的情况下执行此操作 因为使用它的位置是在关键数据循环中 不过 std string 似乎不允许直接访问数据 例如 下面的代码从字符
  • 在 Ruby 中,在字符串开头而不是末尾“咀嚼”最简单的方法是什么?

    在 Ruby 中 有时我需要删除字符串开头的换行符 目前我所做的如下 我想知道做到这一点的最佳方法 谢谢 s naaaa nbbbb s sub n lstrip似乎是你想要的 假设应保留尾随空格 gt gt s naaaa nbbbb g
  • 使用核心服务创建具有元数据字段的多媒体组件

    我正在使用核心服务创建多媒体组件 一切正常 但是 当我在创建多媒体组件的多媒体架构上定义元数据架构字段时 我会收到以下错误 无法找到http www tridion com ContentManager 5 0 DefaultMultime
  • 为什么我收到 CS1012:“字符文字中的字符过多”和 CS0019?

    当尝试将某些内容上传到 Imgur 时 我必须输入授权 我使用WebRequest Headers但这给了我三个错误 2次CS1012错误 字符文字中的字符过多 和 1 次 CS0019 错误 运算符 不能应用于 char 和 method
  • C#源代码中使用特殊字符(例如“ñ”)是否错误?

    最近 使用 C 我刚刚使用拉丁字符声明了一个方法参数 我尝试构建 编译 我的整个解决方案并且它有效 因此我能够执行我的程序 但我很好奇是否在用C 编写的源代码中使用拉丁字符等特殊字符是错误的吗 如果错了 为什么 除此之外还有更多legibl
  • “ClassificationDataSet”中的“target”有什么用?

    我试图找出参数是什么target of ClassificationDataSet可以用来 但我还不清楚 我尝试过的 gt gt gt from pybrain datasets import ClassificationDataSet g
  • 简单的索引优化

    我最近参加了一个简单的技能测试 我得到了反馈 有一个小的索引优化可以改善 表现 技能测试涉及创建生日电子贺卡在线应用程序 用户注册 然后在他们生日那天向他们发送一封电子邮件 我假设这是在一台运行 mysql 数据库的 Linux 服务器上
  • 如何通过 CloudBees Jenkins“立即部署”功能部署非 Web Java 应用程序?

    CloudBees 现在支持 Java 应用程序的部署 是否可以使用 Jenkins 中的 部署到 CloudBees 中的构建后操作来部署您的应用程序 此外 我想使用 Maven程序集插件的 jar with dependations h
  • Google Data studio 中的 COUNTIFS 函数

    我有两列 分别称为大陆和完成度 我想根据以下数据计算每个大陆的完成百分比 这是在 Excel 中使用 COUNTIFS 函数定义的 我们可以在数据工作室中实现这一目标吗 完成百分比公式为 已关闭 状态总数 状态总数 状态值为 开放 进行中
  • 迭代时从映射中删除键/值

    我正在创建这样的地图 def myMap 映射基本上是一个键的对象和一个值的整数 当我迭代地图时 我会计算该值 如果它是 0 我会将其删除 我已经尝试过了myMap remove 但我得到了ConcurrentModificationErr
  • 未知文件类型 MIME?

    如果上传的文件没有扩展名 是否必须指定 MIME 类型 换句话说 是否有默认的通用 MIME 类型 您可以使用application octet stream对于未知类型 RFC 2046 http www rfc editor org r
  • 如何忽略带有特定注释的方法的 checkstyle javadoc 警告

    当我有一个没有 javadoc 的公共方法时 Checkstyle 会发出警告 这很好 当我重写公共方法时 我没有收到警告 因为 javadoc 已在该方法的父类中可用 例如 现在我的方法有另一个注释 MyEvent 现在我确实收到了警告
  • 根据两个数字之间的差异多次插入图像。 PHP

    编写一个脚本 计算从 API 检索到的日期之间的差异 我希望它在图像中放入与差异一样多的次数 d1 new DateTime 2012 04 04 d2 new DateTime 2012 03 31 interval d1 gt diff
  • 为什么 null 需要在这里进行显式类型转换? [复制]

    这个问题在这里已经有答案了 以下代码无法编译 int a int b int a 0 a null 为了编译 需要改为 int b a 0 a int null 既然两者b null and b a是合法的 这对我来说没有意义 为什么我们必
  • 在运行剩余的 javascript 之前检查有效的电子邮件

    我有一个文本框 要求用户在其中插入有效的电子邮件地址 当用户提交有效的电子邮件地址时 会在回发数据时出现加载图形 下面的代码可以很好地显示加载图形 但它不会首先检查电子邮件地址是否有效 有人可以帮忙吗 btnEmail1Submit liv
  • Ansible 查找模块不排除搜索中的文件夹

    这是我尝试找到的剧本test juli jar under app但是 我希望排除目录 app Patchbackup从搜索到的文件夹 以下是我的剧本 tasks name Find test home directories under
  • 实体框架查询很慢,但 SqlQuery 中的相同 SQL 很快

    我看到一些非常奇怪的性能 与使用 Entity Framework Code First 和 NET Framework 版本 4 的非常简单的查询相关 LINQ2Entities 查询如下所示 context MyTables Where
  • 在 Bison 中为 && 和 || 启动短路规则运营

    我正在使用 C C 在 Bison 和 Flex 中编写一个简单的计算器 逻辑在 Bison 中完成 C C 部分负责数据结构 例如 STL 等 我有以下问题 在我的计算器中美元符号 表示 i 和 i 前缀和后缀 例如 int y 3 gt