解析一个'.'链式标识符列表,带有 qi::lexeme 并防止空格跳过

2023-11-29

我目前正在开发一个基于 Spirit 的表达式解析器,它应该允许最终(在遥远的未来)表达式,例如

"a*b*c"
"10+20*x.y.z"
"a.b.c[ a.b ][ e.c( d.e()*4 )].e.f( (a.b+23)*d, -23*b.e(a.b.c) ).x.y"

成员访问、数组订阅、函数调用和表达式的疯狂组合

[] -> subscription
() -> function call or expression bracket
. member chaining

目前我正在与成员链接上的空格跳跃作斗争

"a  . b  . c"

在我的世界中无效 - 但由于空格跳过功能而被解析

在线尝试我的减少样本:https://wandbox.org/permlink/o5kcYtUQEfKZqJgw

问题是第23行:

qi::rule<std::string::iterator, qi::blank_type, utree()> identifier_chain 
    = identifier >> *('.' >> identifier);

我不能在规则周围使用 qi::lexeme,我会得到一个 not Castable to Skipper 编译错误 但如果我将完整的标识符规则复制到identifier_chain规则中,它就会起作用

qi::rule<std::string::iterator, qi::blank_type, utree()> identifer_chain 
   = qi::lexeme[qi::ascii::alpha >> *(qi::ascii::alnum | '_') 
   >> *('.' >> qi::ascii::alpha >> *(qi::ascii::alnum | '_'))];

但这似乎非常多余,我认为当解析器不断增长时,复制会给我带来麻烦

知道如何使用词位或其他东西来保留我的“。”连接没有空格 使订阅端和成员链紧密相连

].a
a.b

这是我的解析器中唯一不需要空格的地方,其余的地方可以完美地减少解析器代码

感谢任何帮助/提示


这就是船长的工作方式(参见提升精神船长问题)

您的规则声明船长:

qi::rule<std::string::iterator, qi::blank_type, utree()> identifier_chain;

因此,为了抑制它,您可以用词位包围,但您也可以从声明中删除船长。实际上,标识符规则也是如此,因为它也完全包含在lexeme[].

建议的最小修复:

Live On Coliru

#include <iostream>
#include <iomanip>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_utree.hpp>

namespace qi = boost::spirit::qi;
using boost::spirit::utree;

int main() {
    auto tests = std::vector<std::string>{
        "a",       // ok
        "a.b",     // ok
        " a.b ",   // ok
        "a . b",   // error
        "a . b. c" // error
    };
    for (std::string const str : tests) {
        auto iter = str.begin(), end = str.end();

        qi::rule<std::string::const_iterator, utree()> 
            identifier = qi::ascii::alpha >> *(qi::ascii::alnum | '_'),
            identifier_chain = identifier >> *('.' >> identifier);

        utree ut;
        bool r = qi::phrase_parse(iter, end, identifier_chain >> qi::eoi, qi::blank, ut);

        std::cout << std::quoted(str) << " ";
        if (r) {
            std::cout << "OK: " << ut << "\n";
        } else {
            std::cout << "Failed\n";
        }
        if (iter!=end) {
            std::cout << "Remaining unparsed: " << std::quoted(std::string(iter,end)) << "\n";
        }
        std::cout << "----\n";
    }
    return 0;
}

Prints:

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

解析一个'.'链式标识符列表,带有 qi::lexeme 并防止空格跳过 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐