提升精神带走关键字并忽略船长

2024-04-27

这是使用表达式的语法的一小部分。

 prefix =
     (lit(L"not") >> prefix) 
    |(lit('-') >> prefix)
    | postfix
    ;

我在 postfix 内部有某种方式纯名称获取标识符..

name_pure = lexeme[+(boost::spirit::standard_wide::alpha | '_') >> *(boost::spirit::standard_wide::alnum | '_')];

到目前为止一切都很好。可以写类似的东西

a=not b

但如果我开始使用not作为像这样的名称前缀

a=not notvarname 

我从 AST 得到一个解析器输出,如下所示

a=not not varname

这意味着not用作前缀规则而不是用作Name与规则名称_纯.

从我的角度来看,船长似乎没有正确参与。

这是我的船长

 template<typename Iterator>
  struct eol_skipper : public qi::grammar<Iterator> {

    eol_skipper() : eol_skipper::base_type(skip) 
    {

      using qi::eol;
      using qi::lit;
      using qi::char_;     
      skip = ascii::space -eol;
    }
    qi::rule<Iterator> skip;
  };

和上次一样,我不认为船长是你的问题。

也许是关于船长做什么的假设。

  1. space - eol只是blank.
  2. 词位不跳过(这就是定义):提升精神船长问题 https://stackoverflow.com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965
  3. PEG 语法是贪婪的、从左到右的。因此,如果您想避免匹配,则需要确保位于单词边界上"not"在纯名称中:防止 Boost Spirit Symbol 解析器过早接受关键字 https://stackoverflow.com/questions/21960167/prevent-the-boost-spirit-symbol-parser-from-accepting-a-keyword-too-early/21960899#21960899 or 如何在boostspirit中正确解析保留字 https://stackoverflow.com/questions/20131162/how-to-parse-reserved-words-correctly-in-boost-spirit/20133011#20133011

我会编写更加自我描述的规则(例如eol_skipper建议它跳过eol,但这正是它不会跳过的内容?)。

using Skipper = qi::blank_type;

然后,让你的identifier规则(纯名称?)隐式lexeme只需从声明中删除船长:

  private:
    qi::rule<Iterator, Ast::AssignmentStatement()> start;
    qi::rule<Iterator, Ast::AssignmentStatement(), Skipper> assignment;
    qi::rule<Iterator, Ast::Expr(), Skipper> expr;
    qi::rule<Iterator, Ast::Negated(), Skipper> negation;
    // implicit lexemes
    qi::rule<Iterator, Ast::Identifier()> identifier;

最后,使用!p解析器指令断言not在关键字/标识符边界上匹配:

    negation
        = lexeme [(lit("not") | '0') >> !(alnum|'_')] >> expr 
        ;

演示时间

Live On Coliru http://coliru.stacked-crooked.com/a/16aba7bbfebc410a

#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
namespace qi = boost::spirit::qi;

namespace Ast {
    using Identifier = std::string;
    struct Negated;

    using Expr = boost::variant<Identifier, boost::recursive_wrapper<Negated> >;

    struct Negated {
        Expr expr;
    };

    struct AssignmentStatement {
        Identifier lhs;
        Expr rhs;
    };
}

BOOST_FUSION_ADAPT_STRUCT(Ast::Negated, expr)
BOOST_FUSION_ADAPT_STRUCT(Ast::AssignmentStatement, lhs, rhs)

template <typename Iterator> struct parser : qi::grammar<Iterator, Ast::AssignmentStatement()> {
    using Skipper = qi::blank_type;

    parser() : parser::base_type(start) {
        using namespace qi;

        start      = skip(blank) [ assignment ];

        assignment = identifier >> '=' >> expr;

        expr       = negation | identifier;

        negation
            = lexeme [(lit("not") | '0') >> !(alnum|'_')] >> expr 
            ;

        identifier = char_("a-zA-Z_") >> *char_("a-zA-Z0-9_");
        // or:
        identifier = raw [ +(alpha | '_') >> *(alnum | '_') ];

        BOOST_SPIRIT_DEBUG_NODES((start)(expr)(assignment)(identifier)(negation))
    }

  private:
    qi::rule<Iterator, Ast::AssignmentStatement()> start;
    qi::rule<Iterator, Ast::AssignmentStatement(), Skipper> assignment;
    qi::rule<Iterator, Ast::Expr(), Skipper> expr;
    qi::rule<Iterator, Ast::Negated(), Skipper> negation;
    // implicit lexemes
    qi::rule<Iterator, Ast::Identifier()> identifier;
};

namespace Ast {
    std::ostream& operator<<(std::ostream& os, Negated const& o)             { return os << "NOT[" << o.expr << "]"; } 
    std::ostream& operator<<(std::ostream& os, AssignmentStatement const& a) { return os << a.lhs << " = " << a.rhs; } 
}

int main() {
    using It = std::string::const_iterator;
    for (std::string const input : {
            "a=not _b",
            "a=not not_var_name",
        })
    {
        It f = input.begin(), l = input.end();

        Ast::AssignmentStatement assignment;
        if (parse(f, l, parser<It>{}, assignment))
            std::cout << "Parsed " << assignment << "\n";
        else
            std::cout << "Parse failed\n";

        if (f!=l)
            std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
    }
}

Prints

Parsed a = NOT[_b]
Parsed a = NOT[not_var_name]

NOTE如何定义BOOST_SPIRIT_DEBUG如果您下次想要对规则进行故障排除,还会为您提供调试输出:

<start>
  <try>a=not b</try>
  <assignment>
    <try>a=not b</try>
    <identifier>
      <try>a=not b</try>
      <success>=not b</success>
      <attributes>[[a]]</attributes>
    </identifier>
    <expr>
      <try>not b</try>
      <negation>
        <try>not b</try>
        <expr>
          <try> b</try>
          <negation>
            <try> b</try>
            <fail/>
          </negation>
          <identifier>
            <try>b</try>
            <success></success>
            <attributes>[[b]]</attributes>
          </identifier>
          <success></success>
          <attributes>[[b]]</attributes>
        </expr>
        <success></success>
        <attributes>[[[b]]]</attributes>
      </negation>
      <success></success>
      <attributes>[[[b]]]</attributes>
    </expr>
    <success></success>
    <attributes>[[[a], [[b]]]]</attributes>
  </assignment>
  <success></success>
  <attributes>[[[a], [[b]]]]</attributes>
</start>
Parsed a = NOT[b]
<start>
  <try>a=not notvarname</try>
  <assignment>
    <try>a=not notvarname</try>
    <identifier>
      <try>a=not notvarname</try>
      <success>=not notvarname</success>
      <attributes>[[a]]</attributes>
    </identifier>
    <expr>
      <try>not notvarname</try>
      <negation>
        <try>not notvarname</try>
        <expr>
          <try> notvarname</try>
          <negation>
            <try> notvarname</try>
            <fail/>
          </negation>
          <identifier>
            <try>notvarname</try>
            <success></success>
            <attributes>[[n, o, t, v, a, r, n, a, m, e]]</attributes>
          </identifier>
          <success></success>
          <attributes>[[n, o, t, v, a, r, n, a, m, e]]</attributes>
        </expr>
        <success></success>
        <attributes>[[[n, o, t, v, a, r, n, a, m, e]]]</attributes>
      </negation>
      <success></success>
      <attributes>[[[n, o, t, v, a, r, n, a, m, e]]]</attributes>
    </expr>
    <success></success>
    <attributes>[[[a], [[n, o, t, v, a, r, n, a, m, e]]]]</attributes>
  </assignment>
  <success></success>
  <attributes>[[[a], [[n, o, t, v, a, r, n, a, m, e]]]]</attributes>
</start>
Parsed a = NOT[notvarname]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提升精神带走关键字并忽略船长 的相关文章

  • 为什么 PCRE 正则表达式比 C++11 正则表达式快得多

    一些示例代码 这是使用 cregex iterator 的 c 11 部分 std chrono steady clock time point begin0 std chrono steady clock now regex re
  • 在 C/C++ 中读取和写入二进制文件的中间部分

    如果我有一个大的二进制文件 假设它有 100 000 000 个浮点数 C 或 C 有没有办法打开文件并读取特定的浮点数 而不必将整个文件加载到内存中 即我如何快速找出第 62 821 214 个浮点是什么 第二个问题 有没有办法更改文件中
  • IssuerSigningKeyResolver 调用异步方法

    我们使用 IssuerSigningKeyResolver 它是 Microsoft IdentityModel Tokens 的一部分 用于令牌验证并接受非异步委托 我们调用一个异步方法 这将导致阻塞调用 因此想知道使用它的正确方法是什么
  • for 和 while 循环中没有循环条件

    while cond fine for cond fine 但是当我删除条件部分时 while syntax compilation error for Infinite loop 这些循环内部是如何实现的 或者 编译器 解析器 如何知道中
  • 我是否必须使用我的数据库训练 Viola-Jones 算法才能获得准确的结果?

    我尝试提取面部数据库的面部特征 但我认识到 Viola Jones 算法在两种情况下效果不佳 当我尝试单独检测眼睛时 当我尝试检测嘴巴时 运作不佳 检测图像的不同部分 例如眼睛或嘴巴 或者有时会检测到其中几个 这是不可能的情况 我使用的图像
  • 验证码怎么写?

    我正在开发一个注册表 我想放置验证码 我生成一个随机字符串 但如何将其转换为图像 否则我如何开发验证码或任何参考 谢谢 Try out 验证码 http recaptcha net plugins aspnet 或查看博客文章 使用 Asp
  • 无法运行bjam编译boost python教程

    我正在尝试跟随本教程 http www boost org doc libs 1 55 0 libs python doc tutorial doc html python hello html关于为 Windows 的 python 包装
  • C 中经过的时间

    include
  • 树结构的序列化/反序列化

    我试图找出保存 序列化 并稍后打开 反序列化 树结构的最佳方法 我的结构由具有不同属性的各种对象类型组成 但每个对象类型都继承自基本抽象 Node 类 每个节点都有唯一的 ID GUID 并且有一个 AddSuperNode Node nd
  • 如何从子窗口中加载的用户控件按钮关闭子窗口?

    这是我的 ChildWindow xaml 代码 1
  • WinForms TreeView - 如何手动“突出显示”节点(就像被单击一样)

    我需要知道如何让以编程方式选择的节点以图形方式处于 选定 状态 就像用户单击它一样 SelectedNode 仅使这一节点在内部被选中 非常感谢 它没有显示为突出显示的原因是由于树视图没有焦点 这是我的测试表单上的按钮单击事件 TreeVi
  • 如何检测机器是否加入域?

    如何检测计算机是否已加入 Active Directory 域 相对于工作组模式 如果没有必要的话 不要用 pinvoke 来愚弄 参考System DirectoryServices 然后调用 System DirectoryServic
  • GCC 和 -Wconversion

    让我们编译以下程序 int main uint16 t data 0 data uint16 t std round 3 14f return 0 with g Wconversion prog cpp 我们会得到warning conve
  • 如何在 MSBuild NuGet 包生成的 .nuspec 中注入自定义依赖项

    我正在尝试迁移到使用 MSBuildPack支持使用 csproj 生成项目 NuGet 包 其中在开发过程中使用本地 dll 来构建项目 但在使用 MSBuild 打包 项目时需要替换 交换它们以引用生成的 nuspec 中的外部 NuG
  • 在 C 或 C++ 中使用逗号作为宏名称

    我想做这样的事情 define define MAX 10 000 000 undef 有什么技巧可以做到吗 编辑 我知道 C 14 中的数字分隔符 我正在寻找一种技巧来对不兼容的编译器执行相同的操作 EDIT2 请考虑Variadic M
  • 在C中更改函数内的数组

    我正在学习 C 并且很困惑为什么在 main 中创建的数组不会在函数内部更改 我假设传递的数组是一个指针 并且更改指针应该更改数组 对吧 有人可以解释这种情况下发生了什么吗 谢谢你的帮助 int main int i length 10 i
  • 如何将 MouseDown 事件放入样式中?

    这有效 XAML
  • WCF - IsOneway 的行为不像 Oneway 操作

    我已在服务的某些方法上定义了 OneWay 属性 但它们的行为并不像 Oneway 调用 我的客户等待呼叫完成并从服务返回 我假设单向操作是非阻塞操作 并且客户端不关心被调用函数会发生什么 它只是调用并忘记它 这是对的吗 问题 调用 Ope
  • 如何包装实体框架以在执行前拦截 LINQ 表达式?

    我想在执行之前重写 LINQ 表达式的某些部分 我在将重写器注入正确的位置时遇到问题 实际上根本没有 查看实体框架源代码 在反射器中 它最终归结为IQueryProvider Execute在 EF 中 它通过以下方式耦合到表达式Objec
  • 提高批量请求的野兽内存使用率

    我运行这个boost beast 客户端 异步 ssl http www boost org doc libs develop libs beast example http client async ssl http client asy

随机推荐

  • 树视图上的 VirtualizingStackPanel 不是虚拟化

    我在这里遇到一个问题 我想在 TreeView 中显示一些项目 大约 100 000 个元素 如果我使用默认的 WPF TreeView 一切似乎都可以工作 但如果我使用自定义 TreeView 目前只有 ItemsControl 虚拟化似
  • 何时在 VBA 中使用 TextFrame 或 TextFrame2

    例如 在 Powerpoint 中 文本框对象 http msdn microsoft com en us library office bb265592 28v office 12 29 aspx 表示 Shape 对象中的文本框架 包含
  • NAudio 音调变换

    我正在使用 NAudio DLL 并且正在寻找音调变换声音的示例代码 有一个使用的例子NAudio https github com naudio NAudio用于开源中的音高变换Skype 变声器 https github com mar
  • 如何远程获取系统的网络共享和连接?

    我正在寻找一种远程获取类似于以下控制台应用程序的信息的方法 net use 净份额 网络统计 ano 但是 我需要能够在系统上运行第三方应用程序的情况下执行此操作 这有效地排除了使用 psexec 远程执行命令 因为 psexec 将作为服
  • .NET:十进制到舍入字符串

    如果我有一个decimal 如何获得带有两位小数的字符串版本 这不起作用 Math Round myDecimal 2 ToString 0 00 不要使用大括号 它们用于使用以下命令将格式化值嵌入到较长的字符串中string Format
  • Swift NSSet 和 CoreData

    我正在尝试将目标 C 和 CoreData 应用程序移动到 Swift 和 iOS 但在迭代 NSSet 对象时遇到了困难 Xcode 已生成这些类 class Response NSManagedObject NSManaged var
  • ruby 2.0.0 捆绑包在 Gemfile 上失败并显示“key: value”

    我正在尝试使用 Gemfile 更新我的 gem 但总是在同一行失败 Gemfile group doc do gem sdoc require false end Command bundle update 我总是收到这个错误 Gemfi
  • 对齐顶部两个具有不同字体大小的文本视图

    我使用约束布局 我想实现以下目标 app layout constraintBaseline toBaselineOf 属性底部对齐两个文本视图 有什么方法可以使两个顶部对齐吗 由于大小差异 常规的 app layout constrain
  • 为什么枚举可以有包私有构造函数?

    既然枚举构造函数只能由其常量调用 为什么允许它是包私有的呢 构造函数实际上不是包私有的 它是隐式的private接口方法的隐式方式public即使您不添加关键字 JLS 的相关部分 8 8 3 http docs oracle com ja
  • Git“预接收”挂钩和“git-clang-format”脚本可以可靠地拒绝违反代码风格约定的推送

    让我们立即从一个片段开始pre receive我已经写过的钩子 bin sh format bold 033 1m format red 033 31m format yellow 033 33m format normal 033 0m
  • INotifyPropertyChanged 与线程

    我有一个 BindingList
  • 如何在 OpenAPI (Swagger) 中参数化 API 基本路径?

    我有一个像这样的网址 id idnumber status 在这个网址中 id idnumber 是 API 基本路径 并且 status是资源 我知道 OpenAPI Swagger 允许在路径中使用参数 如下所示 paths id nu
  • 在 R 4.0.2 中安装 rsvg 库 (conda-forge)

    我在下载 r 包时遇到困难rsvg 我首先使用 conda 为最新的 R 版本 4 0 2 创建了一个环境 如下所示指示 https anaconda org conda forge r base 我能够毫无问题地下载许多其他 R 包和生物
  • Highcharts 在导出时添加图像

    我使用具有导出功能的 Highcharts 根据我的理解 将图像添加到图表中 我可以使用渲染器 该渲染器工作正常 但我不希望图像 徽标 出现在应用程序中的图表上 我希望它出现仅在出口时 我该如何做到这一点 你应该使用图表选项 http ap
  • 循环遍历每一列和行,做一些事情

    我认为这是描述我想做的事情的最佳方式 df column lt ifelse is na df column TRUE 0 1 但其中的列是动态的 这是因为我有大约 45 列 全部具有相同类型的内容 而我想做的就是检查每个单元格 如果其中有
  • 使用 istream_iterator 范围构造时无法访问向量

    我尝试编译此代码片段 但出现编译器错误 使用 Visual Studio 2010 进行编译 include
  • 推导具有两个以上参数的 std::function

    我想知道为什么std function http en cppreference com w cpp utility functional function只知道有两个参数的函数 我已经编写了一些运行良好的代码 但存在许多限制 欢迎任何反馈
  • 即使在回发后也保持用户检查 radiobtn 检查

    我有以下无线电控件 默认选中 全部 如果用户检查其他一些单选按钮并提交 在回发时我想保留选中的按钮 以便用户可以看到他们单击的内容 如何保留使用 jquery 选择的内容 我正在使用的是
  • C#中判断HDD是GPT还是MBT

    如何用 C 判断硬盘类型是 GPT 还是 MBR 我查看了Win32 DiskDrive 似乎没有它 您想要使用 PInvoke 请参阅http pinvoke net http pinvoke net with CreateFile De
  • 提升精神带走关键字并忽略船长

    这是使用表达式的语法的一小部分 prefix lit L not gt gt prefix lit gt gt prefix postfix 我在 postfix 内部有某种方式纯名称获取标识符 name pure lexeme boost