解析中缀表示法的表达式的算法是什么?

2023-11-27

我想在 PHP 中解析布尔表达式。如:

A and B or C and (D or F or not G)

这些术语可以被视为简单的标识符。它们会有一些结构,但解析器不需要担心这一点。它应该只识别关键字and or not ( )。其他一切都是一个术语。

我记得我们在学校写过简单的算术表达式求值器,但我不记得它是如何完成的了。我也不知道要在 Google/SO 中查找哪些关键字。

一个现成的库会很好,但据我记得该算法非常简单,因此自己重新实现它可能会很有趣且有教育意义。


递归下降解析器是写起来很有趣 and 易于阅读。第一步是写出你的语法。

也许这就是您想要的语法。

expr        = and_expr ('or' and_expr)*
and_expr    = not_expr ('and' not_expr)*
not_expr    = simple_expr | 'not' not_expr
simple_expr = term | '(' expr ')'

将其转变为递归下降解析器非常容易。只需为每个非终结符编写一个函数即可。

def expr():
    x = and_expr()
    while peek() == 'or':
        consume('or')
        y = and_expr()
        x = OR(x, y)
    return x

def and_expr():
    x = not_expr()
    while peek() == 'and':
        consume('and')
        y = not_expr()
        x = AND(x, y)
    return x

def not_expr():
    if peek() == 'not':
        consume('not')
        x = not_expr()
        return NOT(x)
    else:
        return simple_expr()

def simple_expr():
    t = peek()
    if t == '(':
        consume('(')
        result = expr()
        consume(')')
        return result
    elif is_term(t):
        consume(t)
        return TERM(t)
    else:
        raise SyntaxError("expected term or (")

这并不完整。您必须提供更多代码:

  • 输入功能。 consume, peek, and is_term是您提供的功能。使用正则表达式很容易实现它们。consume(s)读取输入的下一个标记,如果不匹配则抛出错误s. peek()只是返回对下一个令牌的查看而不消耗它。is_term(s)返回 true 如果s是一个术语。

  • 输出功能。 OR, AND, NOT, and TERM每次成功解析表达式的一部分时都会调用。他们可以做任何你想做的事。

  • 包装函数。而不是仅仅打电话expr直接,您需要编写一个小包装函数来初始化使用的变量consume and peek,然后调用expr,最后检查以确保没有未消耗的剩余输入。

即使如此,代码量仍然很小。在Python中,完整的程序有84行,其中包括一些测试。

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

解析中缀表示法的表达式的算法是什么? 的相关文章

  • 使用 .htaccess 启用 PHP 短标签

    我在自己的 Centos 服务器上设置了 Apache 并具有多个虚拟 Web 服务器 并且我希望仅为位于以下位置的其中一个 Web 服务器启用 PHP 短标记 var www ostickets html 我可以通过添加成功启用短标签sh
  • header() 错误未在 php 中显示

    我写了一个PHP程序 我用session start and header 函数 我知道在向客户端发送任何内容之前应该使用此函数 没关系 但是为了测试 我向客户端发送了一条测试消息echo test 在使用 header 之前 但我没有收到
  • 使用 strtotime() 计算时间差(以小时和分钟为单位)[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions time1
  • 如何将自定义类型数组传递给 Postgres 函数

    我有一个自定义类型 CREATE TYPE mytype as id uuid amount numeric 13 4 我想将它传递给具有以下签名的函数 CREATE FUNCTION myschema myfunction id uuid
  • 如何防止 CakePHP 中重复表单提交?

    我发现 CakePHP 中的安全组件通过将令牌作为隐藏值添加到表单中来帮助防止 CSRF 我想知道是否有办法防止使用此组件或其他组件 帮助器重复表单提交 在之前的项目中 我使用了保存在会话中的唯一哈希值 该哈希值会在提交时读取并删除 重复提
  • 通过jquery传递搜索参数

    我有一个表单 如果用户输入搜索查询 其参数应通过 jquery 传递 并在获取结果后将结果加载到 div 容器中 由于我不太熟悉 jquery 我该怎么做 html currently the data is being displayed
  • 智能位置表单字段

    我的用户注册表单上有一个文本字段location 我本质上希望这个字段能够根据 Google 地图 或同等地图 进行验证 只允许有效位置通过 最好采用类似的格式滑铁卢 伦敦 or 伦敦 英国 要求 除了位置名称之外 我还想返回该位置中心的坐
  • 如何让 shell_exec 在 IIS 6.0 上运行

    问题 我有一个 PHP 脚本 它使用shell exec运行 pdf 到文本转换器 为了简化问题 我创建了一个简短的脚本 使用shell exec只是回显的输出dir命令 当我在 Apache 服务器上运行它时 一切都按预期运行 当我切换到
  • 使用 PhpStorm 删除 CakePHP 中的插件后出现“成员有私人访问错误”

    从我的 CakePHP 框架中删除插件以及与其关联的所有代码行后 我在以下位置收到错误getInitializer的功能autoload static php in my vendor gt composer folder public s
  • 访问 public_html 级别之外/以下的文件

    如何通过 url 访问文件 home uzair etc index php 即使我运行域 something com 它显示了 home uzair public html index php 这个文件 任何人请帮助我如何访问放置在 ho
  • Facebook Graph API v3.1 开发人员访问令牌权限限制

    如您所知 Facebook 将其 API 升级到了 V3 1 现在正在慢慢地淘汰旧的 API 和应用程序 因此我们必须迁移到新的 API 他们做出了一些艰难的决定 这对垃圾邮件网站来说是好事 但对开发人员来说也很难 提醒 Graph API
  • Node.js 进行 rsa 加密的正确方法?

    我正在尝试创建一个 WS 来发出肥皂请求 在消息正文中有一个包含加密文本的字段 我有公钥来加密文本 但我获得的唯一结果是文本无法识别 我使用节点的加密模块来发出请求 并且文本已加密 但我不知道为什么没有正确加密 PS我用 openssl p
  • PHP 相等变量

    我想知道是否有任何方法可以检查大量变量是否相等 如果我只有几个变量 我可以这样做 if a b a c b c 但是 如果我有 20 个变量 则需要一些时间来编写所有组合 还有其他方法吗 if count array unique arra
  • 如何在无法重启的服务器(Apache)上使用gettext?

    我在服务器故障上问了这个问题 https serverfault com questions 104224 how do you use gettext on server apache you cant restart但我没有得到任何回应
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Laravel 8、Sanctum、Fortify /logout 在 Postman 中抛出“CSRF 令牌不匹配”

    我安装了 L8 Sanctum 和 Fortify 进行身份验证 我以前可以 login 使用了Pre request Script设置X XSRF TOKEN 我什至得到了 api user成功地 但当我这样做时 logout 我在 Po
  • PHP 时间间隔

    我正在寻找一个看起来应该非常简单的解决方案 但似乎我不能在这里找到任何好的答案 而且我自己似乎无法让它发挥作用 我正在寻找的是设置开始时间 结束时间 然后迭代给定时间间隔之间的一组时间 例如 上午 9 00 下午 5 00 是开始时间 这些
  • 通过ajax执行后期操作时如何克服CORS重定向问题?

    我可以通过外部登录表单中的 post 方法类型提交表单来登录 roundcube 实例 托管在另一台服务器上 我收到此错误 通过 ajax 签名时 XMLHttpRequest 无法加载https 192 168 0 7 mail http
  • 如何使用 PHP 从 MySQL 检索特定值?

    好吧 我已经厌倦了 过去一周我花了大部分空闲时间试图解决这个问题 我知道 SQL 中的查询已更改 但我无法弄清楚 我能找到的所有其他帖子似乎都已经过时了 如果有人能帮助我 我将非常感激 我想做的就是使用手动输入数据库的唯一 密码 来检索行的
  • 如何显示 PHP 对象

    我有这样的代码 dataRecord1 client gt GetRecord token table filter echo pre print r dataRecord1 echo pre foreach dataRecord1 gt

随机推荐

  • 删除未使用的运行时函数,这些函数会使可执行文件膨胀(GCC)

    我已经为 ARM cortex m3 构建了 GCC4 7 1 交叉工具链 现在我正在链接来自 C C 代码的可执行文件 该代码肯定不使用某些某些 STL 类 例如std string 此外 异常和 RTTI 也被关闭 虽然当我寻找目标 E
  • 如何找到访问SQL Server的用户名和机器名

    我的工作公司有一台 MSSQL Server 2005 我有两个关于查找当前日志用户以及发送警告消息的方法的问题 第一个问题是是否有任何T SQL或SP可用于找出当前登录用户名和机器名 如果用户使用SQL Server sa名称远程访问SQ
  • 如何在HttpResponse中发送文件?

    在我的应用程序中 用户可以在单击链接后下载文件 文档是用代码生成的 PDF RTF 我用 byte downloadBytes some pdf document bytes System Web HttpResponse response
  • pyspark用另一个值替换数据框中的所有值

    我的 pyspark 数据框中有 500 列 有些是字符串类型 有些是 int 有些是布尔类型 100 个布尔列 现在 所有布尔列都有两个不同的级别 是和否 我想将它们转换为 1 0 对于字符串 我有三个值 通过 失败和空 如何用 0 替换
  • 将 itertools 数组转换为 numpy 数组

    我正在创建这个数组 A itertools combinations range 6 2 我必须用 numpy 操作这个数组 例如 A reshape 如果尺寸 A 较高 则命令list A 太慢了 如何将 itertools 数组 转换
  • 对一个 switch case 语句使用两个值

    在我的代码中 程序根据用户输入的文本执行某些操作 我的代码如下所示 switch name case text1 blah break case text2 blah break case text3 blah break case tex
  • 在Windows窗体上显示pdf?

    在vb net中是否可以在表单上显示pdf文件 如果您希望在客户端计算机上不安装 Acrobat Reader 的情况下显示 PDF 请查看以下内容 未安装 Acrobat Reader 的 PDF 查看器控件 我还没有尝试过 但可能会尝试
  • 命名元组的 Python 语法

    我看到命名元组的 Python 语法是 Point namedtuple Point x y 为什么不像这样更简单 Point namedtuple x y 它不太冗长 一般来说 对象不知道它们被分配给什么变量 Create three v
  • 如何在c#中连接access数据库[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我有一个包含 7 个表的访问数据库文件 但我不知道如何连接并显示所有表 如果有人可以帮助
  • 如何检索.Net WinForms图表控件中选定的范围?

    我正在使用 C 内置 Winforms 图表控件 System Windows Forms DataVisualization Charting Chart 具有让用户选择范围的内置功能 我想做的是读回用户选择的范围 当然一定有一些简单的方
  • 将多维数组转换为 XML

    在您评论这可能是重复的之前 请先阅读下面的粗体行 这与 SimpleXML 无关 让我首先展示应如何布置 XML 请忽略命名空间
  • 在 PHP 中按子数组的值对数组进行排序

    我有一个由数组组成的数组 我想根据子数组的属性对父数组进行排序 这是一个例子 array 2 0 gt array 3 0 gt string 6 105945 1 gt string 10 First name 2 gt float 0
  • innerHTML:如何避免

    我正在编写一个插件 它将表情符号转换为特定网站文本块中的图像 简单的答案是使用正则表达式来检测innerHTML上的触发文本并插入img标签 然后将字符串通过管道传回中的dom元素内部HTML部分 DOM 元素块可能已经有锚点 a 和 或文
  • 如何在 VC++ 项目中关闭 Unicode?

    我在 Visual Studio 2008 中有一个 VC 项目 它在编译器命令行上定义 unicode 的符号 D UNICODE D UNICODE 即使我没有在项目的预处理器部分中打开此符号 因此 我针对所有 Win32 库函数的 U
  • ZeroMQ - 多个发布者和监听器

    我刚刚开始了解并尝试 ZeroMQ 我不清楚如何在两个以上的参与者 发布者和订阅者 之间进行双向通信 以便每个组件都能够在 MQ 上读取和写入 这将允许创建事件驱动的架构 因为每个组件都可以侦听一个事件并回复另一个事件 有没有办法直接使用
  • 如何在 WPF 中从 C# 获取超链接文本?

    我有一个WPFHyperlink我正在尝试从中获取文本内容 例如
  • 如何将 gitlab 备份迁移到具有最新 gitlab 版本的新服务器

    我正在尝试将旧服务器的 gitlab 备份迁移到新服务器 我的旧服务器有 gitlab gitlab 6 5 1 0 我的新服务器有 gitlab 版本 gitlab 6 6 5 omnibus 我使用以下命令从旧服务器进行备份 bundl
  • 从嵌套 for 循环继续 while

    我有以下循环结构 while reader Read eq true row for i 0 i lt reader FieldCount i if something continue with while do more stuff 现
  • 如何在 SSIS 中为 Excel 文件设置动态文件路径?

    文件名随月份而变化 每个月您都会有一个新文件 I Test Data 201303 xlsx 如何设置可使用可变文件路径的连接管理器 在连接管理器上查找 表达式 属性 这就是您将其设置为 USER VariableName 的地方 更详细
  • 解析中缀表示法的表达式的算法是什么?

    我想在 PHP 中解析布尔表达式 如 A and B or C and D or F or not G 这些术语可以被视为简单的标识符 它们会有一些结构 但解析器不需要担心这一点 它应该只识别关键字and or not 其他一切都是一个术语