用 boost 精神解析布尔表达式

2024-02-09

我正在尝试使用 boostspirit 编写布尔表达式的解析器。我在 stackoverflow.com 上找到了一个很好的例子,C++ 中的布尔表达式(语法)解析器 https://stackoverflow.com/questions/8706356/boolean-expression-grammar-parser-in-c,这帮助我很好地理解了精神语法和解析过程是如何工作的。

该代码在我的开发机器上编译并完美运行,这是一个安装了 2.6.32-5 bigmem 内核和 boost 1.42 (spirit 2.2) 的 debian 6 机器。我决定根据自己的目的修改代码,以便不仅解析“a 和 b 或 c”形式的表达式,还解析“sc[100] 和 cc[200] 或 fd[300]”形式的表达式,其中布尔运算的操作数也需要解析,以便获得我的项目需要的 ast。我选择了以下方法:

  • 添加另一个抽象数据类型

    struct op_or  {};
    struct op_and {};
    struct op_xor {};
    struct op_not {};
    struct r_sc  {};
    
    typedef std::string var;
    template <typename tag> struct binop;
    template <typename tag> struct unop;
    template <typename tag> struct rule;
    
    typedef boost::variant<
            var,
            boost::recursive_wrapper<unop<op_not>>,
            boost::recursive_wrapper<binop<op_and>>,
            boost::recursive_wrapper<binop<op_xor>>,
            boost::recursive_wrapper<binop<op_or>>,
            boost::recursive_wrapper<rule<r_sc>> > expr;
    
    template <typename tag> struct rule
    {
        explicit rule( const expr& lhs, const expr& rhs )
            :   oper1( lhs ),
                oper2( rhs )
        {
    
        }
    
        expr oper1, oper2;
    };
    
    
    
    template <typename tag> struct binop
    {
        explicit binop( const expr& lhs, const expr& rhs )
            :   oper1( lhs ),
                oper2( rhs )
        {
    
        }
    
        expr oper1, oper2;
    };
    
    
    
    template <typename tag> struct unop
    {
        explicit unop( const expr& rhs )
            :   oper1( rhs )
        {
    
        }
    
        expr oper1;
    };
    
  • 修改访问者以打印 ast

    struct printer : boost::static_visitor<void>
    {
        printer( std::ostream& outputStream )
            :   _outputStream( outputStream )
        {
    
        }
    
        std::ostream& _outputStream;
    
        //
        void operator()( const var& variable ) const
        {
            _outputStream << variable;
        }
    
        void operator()( const binop<op_and>& binaryOp ) const
        {
             printOp( " & ", binaryOp.oper1, binaryOp.oper2 );
        }
    
        void operator()( const binop<op_or>& binaryOp ) const
        { 
            printOp( " | ", binaryOp.oper1, binaryOp.oper2 );
        }
    
        void operator()( const binop<op_xor>& binaryOp ) const
        {
            printOp( " ^ ", binaryOp.oper1, binaryOp.oper2 );
        }
    
    void printOp( const std::string& operation, const expr& lhs, const expr& rhs ) const
    {
        _outputStream << "(";
            boost::apply_visitor( *this, lhs );
            _outputStream << operation;
            boost::apply_visitor( *this, rhs );
        _outputStream << ")";
    }
    
    void operator()( const unop<op_not>& uaryOp ) const
    {
        _outputStream << "(";
        _outputStream << "!";
            boost::apply_visitor( *this, uaryOp.oper1 );
        _outputStream << ")";
    }
    
    void operator()( const rule<r_sc>& rule ) const
    {
        printRule( " serviceCode ", rule.oper1, rule.oper2 );
    }
    
    void printRule( const std::string& rule, const expr& lhs, const expr& rhs ) const
    {
        _outputStream << "{";
            boost::apply_visitor( *this, lhs );
            _outputStream << rule;
            boost::apply_visitor( *this, rhs );
        _outputStream << "}";
    }
    };
    
  • 修改语法规则以生成规则对象

    template <typename It, typename Skipper = qi::space_type>
    struct parser : qi::grammar<It, expr(), Skipper>
    {
        parser()
            : parser::base_type( _expr )
        {
            using namespace qi;
            using boost::spirit::ascii::string;
    
            _expr  = _or.alias();
    
            _or = ( _xor >> "or" >> _or )[ _val = phx::construct<binop<op_or> >( _1, _2 ) ] |
                _xor   [ _val = _1 ];
    
            _xor = ( _and >> "xor" >> _xor )[ _val = phx::construct<binop<op_xor> >( _1, _2 ) ] |
                _and[ _val = _1 ];
    
            _and = ( _not >> "and" >> _and )[ _val = phx::construct<binop<op_and> >( _1, _2 ) ] |
                _not[ _val = _1 ];
    
            _not = ( "not" > _base )[ _val = phx::construct<unop<op_not> >( _1 ) ] |
                _base[ _val = _1 ];
    
            _base = ( ( '(' > _expr > ')' ) | _serviceCode[ _val = _1 ] );
    
            _serviceCode = ( +alnum >> "[" >> +alnum >> "]" )
                [ _val = phx::construct<rule<r_sc> >( _1, _2 ) ] |
                    _text;
    
            _text = qi::lexeme[ +( alnum ) ];
        }
    private:
    
            qi::rule<It, var() , Skipper> _text;
            qi::rule<It, expr(), Skipper> _not, _and, _xor, _or, _base, _expr, _serviceCode;
    };
    

我以为就是这样,但这个解决方案甚至无法编译。编译器抛出以下错误:

错误:模板参数列表中的解析错误 错误:不匹配‘operator>’ in ‘construct<<expression error> > > (boost::spirit::_1, boost::spirit::_2)’

由于我是提振精神的新手,有人可以告诉我我做错了什么吗?


None

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

用 boost 精神解析布尔表达式 的相关文章

  • 迭代变量并查找特定类型实例的技术

    我想迭代进程中内存中的变量 通过插件动态加载 并查找特定类型的实例 以前我可以找到特定类型 或内存中的所有类型 我可以创建类型的实例 我可以获取作为不同类型的字段包含的实例 但我无论如何都不知道只是 搜索 特定类型的实例 一种方法是使用 W
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • Azure 事件中心 - 按顺序接收事件

    我使用下面的代码从 Azure Event Hub 接收事件 https learn microsoft com en us azure event hubs event hubs dotnet framework getstarted s
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 当我“绘制”线条时,如何将点平均分配到 LineRenderer 的宽度曲线?

    我正在使用线条渲染器创建一个 绘图 应用程序 现在我尝试使用线条渲染器上的宽度曲线启用笔压 问题在于 AnimationCurve 的 时间 值 水平轴 从 0 标准化为 1 因此我不能在每次添加位置时都在其末尾添加一个值 除非有一个我不知
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检

随机推荐

  • 使用 __gnu_mcount_nc 捕获函数退出时间

    我正在尝试在支持不佳的原型嵌入式平台上进行一些性能分析 我注意到 GCC 的 pg 标志导致 thunks gnu mcount nc在每个函数的入口处插入 没有实施 gnu mcount nc是可用的 并且供应商没有兴趣提供帮助 但是由于
  • 为 Project Tango 开发设备设置开发环境时出现问题

    我有一个 Project Tango 开发套件 我对处理传感器的深度数据感兴趣 我的机器上有 ADB 设置 但 Eclipse android 模拟器未检测到 Tango Development 平板电脑 谁能建议我如何为设备进行设置 先感
  • 使我的文件可读为 Perl 或 HTML

    本着 Perl 序言 https stackoverflow com questions 2308874 explain the deviousness of the perl preamble 无论是由 shell 脚本解释器还是 Per
  • 从文本文件导入数据时 SQL 保留关键字导致错误

    我有以下代码 我正在尝试按照本网站上的一位用户的建议使用 php 将文本文件导入到 sql 表中 不幸的是 由于我的文本文件中包含 最大和最小 单词 我的导入中途出现错误 我试图找出我能做些什么来避免它 我发现的大部分内容都是关于在列名称中
  • nginx既是反向代理又是Web服务器

    我目前使用 nginx 和乘客来为我的 Rails 应用程序提供服务 考虑在方程式中加入缓存反向代理 我可以使用同一个 nginx 实例作为反向代理 在端口 80 上运行 提供静态和电子标记操作 还是需要不同的 nginx 实例或完全不同类
  • 如何子类化 vtkActor

    我希望当我选择一个时能够访问我的底层数据结构vtkActor 一个类派生自vtkActor将 ptr 保存到我的数据结构似乎是最简单的方法 我让子类编译得很好 但演员似乎没有添加到渲染器中 所以 这是我的课程 h include
  • DxScene 是“Delphi 的 WPF”吗?有人用过吗?

    我正在使用 DxScene 和 VxScene http www ksdev com dxscene index html http www ksdev com dxscene index html 它看起来非常漂亮和强大 3d 加速矢量图
  • 为什么边距填充在表 td 和 tr 中不起作用?

    table border 0 style padding 10px width 100 tbody tr td style padding 0 img src 8 jpg alt td td style padding 0 img src
  • 增加字符串值

    Java问题在这里 如果我有一个字符串 a 如何向该字符串 添加 值 以便得到 b 等等 就像 a String str abcde System out println getIncrementedString str Output bc
  • 为什么在此正则表达式中 \\ 不被解释为反斜杠?

    我正在学习使用 Java 的模式和匹配器 这是我书中的示例代码片段 正如作者所描述的那样 但我不明白为什么 最终是一个点 而不是反斜杠 部分 和点 部分 编译器不是从左到右读取的吗 import java util regex public
  • 给定 K 个排序列表,每个列表中最多包含 N 个元素,返回所有项目的排序迭代器

    Example List 1 1 4 5 8 9 List 2 3 4 4 6 List 3 0 2 8 Would yield the following result Iterator gt 0 1 2 3 4 4 4 5 6 8 8
  • AltGr 键不起作用,我必须使用 Ctrl+AltGr [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 I encountered this problem several times I want to use a character ac
  • 在 C++11 中实现复制和交换习惯用法的更好方法

    我看到很多代码在复制和交换方面实现了五规则 但我认为我们可以使用移动函数来替换交换函数 如下代码所示 include
  • 具有共享依赖项的嵌套ExternalProject_Add

    我正在尝试申请ExternalProject Add自动安装中型 C 项目的依赖项 事情进展顺利 直到我不得不安装一个使用的库ExternalProject Add安装它的依赖项之一 我自己的项目也恰好使用了它 如果我可以避免重建这个库 而
  • bash 多个命令行参数相互依赖

    我有一个脚本 其中接受以下参数 脚本 dph peh 第一个参数告诉脚本我是否需要使用生产脚本或开发脚本来执行它 第二个参数告诉脚本生成的报告的输出是否应作为电子邮件发送或应重定向到 html 页面 当我使用 getopts 时 我得到一个
  • 使用php将上传的excel文件转换为csv

    我正在尝试使用 php 创建一个网页 该网页使用浏览按钮上传 excel 文件并将其导入到 mysql 数据库中 我可以上传 csv 文件并将其导入数据库 html代码
  • 具有 MVC 4 或 5 的 MEF - 可插拔架构 (2014)

    我正在尝试使用 Orchard CMS 等可插入架构构建 MVC4 MVC5 应用程序 所以我有一个 MVC 应用程序 它将作为启动项目并负责身份验证 导航等 然后将有多个模块单独构建为 asp net 类库或剥离的 mvc 项目并具有控制
  • 字符串中包含的方法的调用名称

    如何根据 Groovy 中字符串的值调用方法 例如代替 switch val case one Obj one break case two Obj two break 我想做类似的事情obj val where val包含 one or
  • 如何列出 Android 10 上的所有 pdf 文件?

    由于更改与访问共享存储的授权相关 因此似乎不再可能通过这种方法搜索 pdf 类型的所有文档 使用 requestLegacyExternalStorage false ContentResolver cr context getConten
  • 用 boost 精神解析布尔表达式

    我正在尝试使用 boostspirit 编写布尔表达式的解析器 我在 stackoverflow com 上找到了一个很好的例子 C 中的布尔表达式 语法 解析器 https stackoverflow com questions 8706