首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Boost Spirit Qi解析器在分解到qi::语法中时无法工作

Boost Spirit Qi解析器在分解到qi::语法中时无法工作
EN

Stack Overflow用户
提问于 2017-08-01 09:47:39
回答 1查看 36关注 0票数 1

我正在尝试使用Spirit解析器来解析像id 1234这样的字符串。它可以很好地处理内联start = qi::lit("id") >> qi::int_;,但是如果我想把它放到一个单独的基于qi::语法的结构中,就不行了。请参见以下示例中的案例1、2和3:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <iostream>
#include <fstream>

namespace qi  = boost::spirit::qi;
namespace phoenix = boost::phoenix;

struct Context{};

template <typename Iterator, typename SkipParser>
struct IdGrammar : qi::grammar<Iterator, SkipParser>
{
    explicit IdGrammar(Context& out) : IdGrammar::base_type(start, "IdGrammar")
    {
        start = qi::lit("id") >> qi::int_;
    }

    qi::rule<Iterator, SkipParser> start;
};

template <typename Iterator, typename SkipParser>
struct MyGrammar : qi::grammar<Iterator, SkipParser>
{
    explicit MyGrammar(Context& out)
        : MyGrammar::base_type(start, "MyGrammar")
    {
        IdGrammar<Iterator, SkipParser> idGrammar(out);
//      start = idGrammar >> *(',' >> idGrammar); // 1 = Parsing fails
        start = idGrammar; // 2 = Parsing fails
//      start = qi::lit("id") >> qi::int_; // 3 = Parsing succeeds

        start.name("the start");
        qi::on_error<qi::fail>(
            start,
            phoenix::ref(std::cout) << phoenix::val("Parsing error: expecting ") << qi::_4 // what failed?
                                    << phoenix::val(" here: \"")
                                    << phoenix::construct<std::string>(qi::_3, qi::_2) // iterators to error-pos, end
                                    << phoenix::val("\"")
                                    << std::endl);
    }

    qi::rule<Iterator, SkipParser> start;
};

int main()
{
    typedef std::string::const_iterator iterator_type;
    Context ctx;
    MyGrammar<iterator_type, qi::space_type> roman_parser(ctx); // Our grammar

    std::string str = "id 5012";

    iterator_type iter = str.begin(), end = str.end();
    bool r = phrase_parse(iter, end, roman_parser, qi::space);

    if (r && iter == end)
    {
        std::cout << "Parsing succeeded\n";
    }
    else
    {
        std::string rest(iter, end);
        std::cout << "Parsing failed\n";
        std::cout << "stopped at: \"" << rest << "\"\n";
    }
}

Run example on Coliru

失败案例(1和2)的输出为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Parsing failed
stopped at: "id 5012"

是什么造成了这里的差异?请记住,我删除了整型结果的所有赋值,以保持示例的最小化-假设这与问题无关。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-01 11:45:54

idGrammar的生命周期必须比构造函数作用域更长。将其设置为成员变量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template <typename Iterator, typename SkipParser>
struct MyGrammar : qi::grammar<Iterator, SkipParser>
{
    explicit MyGrammar(Context& out)
        : MyGrammar::base_type(start, "MyGrammar")
          , idGrammar(out)
    {
      start = idGrammar >> *(',' >> idGrammar); // 1 = Now parsing succeeds
//        start = idGrammar; // 2 = Now parsing succeeds
//      start = qi::lit("id") >> qi::int_; // 3 = Parsing succeeds

        start.name("the start");
        qi::on_error<qi::fail>(
            start,
            phoenix::ref(std::cout) << phoenix::val("Parsing error: expecting ") << qi::_4 // what failed?
                                    << phoenix::val(" here: \"")
                                    << phoenix::construct<std::string>(qi::_3, qi::_2) // iterators to error-pos, end
                                    << phoenix::val("\"")
                                    << std::endl);
    }

    qi::rule<Iterator, SkipParser> start;
    IdGrammar<Iterator, SkipParser> idGrammar;
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45434476

复制
相关文章
Boost.Spirit 初体验
使用代码生成代码是一件十分美妙的事情,于是有了各种代码生成器。但是生成代码,意味着要有对生成规则的分析和处理。 Boost.Spirit 就是这么一个语法分析工具,它实现了对上下文无关文法的LL分析。支持EBNF(扩展巴科斯范式)。 Boost.Spirit 的使用真的是把模板嵌套用到了极致。确实这么做造成了非常强的扩展性,生成的代码也非常高效,但是嵌套的太复杂了,对于初学者而言真心难看懂。 你能想象在学习阶段一个不是太明白的错误导致编译器报出的几十层模板嵌套错误信息的感受吗?而且,这么复杂的模板嵌套还直接导致了编译速度的巨慢无比。 其实在之前,我已经使用过Spirit的Classic版本,即1.X版本,但是过多的复制操作让我觉得当时用得很低效,还好分析的内容并不复杂所以没。体现出来 这回就来研究下功能更强劲的2.X 版本。
owent
2023/03/06
9110
Boost.Spirit 初体验
使用代码生成代码是一件十分美妙的事情,于是有了各种代码生成器。但是生成代码,意味着要有对生成规则的分析和处理。 Boost.Spirit 就是这么一个语法分析工具,它实现了对上下文无关文法的LL分析。支持EBNF(扩展巴科斯范式)。 Boost.Spirit 的使用真的是把模板嵌套用到了极致。确实这么做造成了非常强的扩展性,生成的代码也非常高效,但是嵌套的太复杂了,对于初学者而言真心难看懂。 你能想象在学习阶段一个不是太明白的错误导致编译器报出的几十层模板嵌套错误信息的感受吗?而且,这么复杂的模板嵌套还直接导致了编译速度的巨慢无比。 其实在之前,我已经使用过Spirit的Classic版本,即1.X版本,但是过多的复制操作让我觉得当时用得很低效,还好分析的内容并不复杂所以没。体现出来 这回就来研究下功能更强劲的2.X 版本。
owent
2018/08/01
3.3K0
无线充qi协议c语言详解,无线充电Qi协议正向通信FSK的解调设计[通俗易懂]
摘 要: 无线充电Qi协议提出发射器和接收器通过频率调制(FSK)方式进行正向通信,进而建立完整的通信状态控制。接收器可采用测宽法进行频率解调,然而由于电磁耦合变化、负载变化、载波占空比变化、测量量化等引起的误差,该方法无法满足实际应用的要求。该文针对传统测宽法抗干扰能力弱的问题,提出一种窗口滤波算法,通过参考相邻脉冲频率确定当前脉冲的有效频率,极大地提高了测宽法的抗干扰能力。经实例分析,改进后的测宽法抗干扰能力强、逻辑简单,为无线充电正向通信FSK解调提供一种可行的方法。
全栈程序员站长
2022/07/04
2.8K0
无线充qi协议c语言详解,无线充电Qi协议正向通信FSK的解调设计[通俗易懂]
无线充电原理与QI协议详解[通俗易懂]
一 、无线充电基本原理 无线充电的基本原理就是我们平时常用的开关电源原理,区别在于没有磁介质耦合,那么我们需要利用磁共振的方式提高耦合效率,具体方法是在发送端和接收端线圈串并联电容,是发送线圈处理谐振状态,接收端线圈也是如此
全栈程序员站长
2022/07/21
8.1K0
无线充电原理与QI协议详解[通俗易懂]
Qi v1.2.4协议 之 定频调压方案
工作原理:通过改变工作频率从而调节发射功率;在某些发射频段会对手机电路造成一定干扰;
全栈程序员站长
2022/06/25
6900
遇到这几个 JS “神(qi)奇(pa)“写法也是醉了......
本篇译自:https://javascript.plainenglish.io/5-trickiest-javascript-interview-questions
掘金安东尼
2022/09/19
4750
遇到这几个 JS “神(qi)奇(pa)“写法也是醉了......
《超越C++标准库:Boost库导引》:Boost库简介-字符串和文本处理
正则表达式对于解决相当数量的模式匹配(pattern-matching)问题是至关重要的。它们经常被用于处理长字符串、非精确地查找子字符串、根据某些格式tokenize字符串,或者依照某个标准对字符串进行修改。以前C++缺少对于正则表达式的支持,用户不得不求助于其它对正则表达式有强有力支持的语言,比如Perl,awk和sed。Regex对于正则表达式提供高效有力的支持,它遵循与标准模板库(STL)相同的设计理念,这使得它的用法相当直观。Regex已经被即将到来的(标准)库技术报告所采纳。更多信息请参阅“Library 5: Regex”。
用户7886150
2021/01/16
8850
App内购(IAP)的价格优(qi)化(pian)策略
  App的内购的优化很重要。或者说,凡是移动端的购买转化优化都很重要。  这么说有一点同意反复的啰嗦,但app与web不同,app用于说服(或者影响)消费者的空间比较有限,篇幅不能太长,画面不能太多,而且也不可能总是弹出窗口骚扰消费者。   所以app中实现转化的难度我觉得总体要比web高很多,实现app的转化不能拖泥带水,试错的机会不多,需要在洞察消费者心理之后一击必中。   但是,普遍的一个感觉困惑的地方在于,消费者的心理很难把握,尤其是对于消费者愿意接受的价格的把握。如何将价格优化到正好合适的地方
iCDO互联网数据官
2018/03/02
1.8K0
App内购(IAP)的价格优(qi)化(pian)策略
对于Qi和百度,不需要再猜测和臆想
我也是最近才开始去搜索和了解Qi,然后我就被Qi的工作能力、自律性、责任心、人格魅力以及对Ai将改变世界的执着所折服。
后端技术探索
2018/08/10
2290
对于Qi和百度,不需要再猜测和臆想
SignalR 在IE中无法工作 - Internet Explorer
运行基于SignalR的超线程上载器的代码,发现SignalR 在IE 9上居然没法工作了,提示如下: 提示很明显,需要json2.js的支持。 使用Nuget 搜索json2.js 并安装: 在引用
张善友
2018/01/29
3.3K0
SignalR 在IE中无法工作 - Internet Explorer
redis 复制很简单? 树上qi个猴,一枪还剩几个猴
相对比使用RDS ,NOSQL 数据库的虽使用,但被忽视的不少,相对于数据库之间的复制,(物理复制, 逻辑复制),redis 的复制,不少人认为还是比较简单的。那下面有一些问题
AustinDatabases
2020/02/21
5240
redis  复制很简单? 树上qi个猴,一枪还剩几个猴
【说站】PDF如何更改页面尺寸大小,QI插件改变PDF页面大小
2、Quite Imposing plus3 PDF拼版插件中文汉化破解版(Acrobat Pro DC的QI插件)
很酷的站长
2022/11/24
2.8K0
【说站】PDF如何更改页面尺寸大小,QI插件改变PDF页面大小
LLT工作总结与Gherkin语法解析器简单应用
这几天产品线这里要搞LLT(Low level Test)重点工作,保障版本的高质量发布。工作当然包括一系列的规范、培训、编码、检视,不过具体看下来主要还是提取了下面的一些度量要点:
mythsman
2022/11/14
9310
LLT工作总结与Gherkin语法解析器简单应用
SAP QM 启用04检验类型的物料,工单上STOCK TYPE不是QI?
SAP QM 启用04检验类型的物料,工单上STOCK TYPE不是QI? 比如物料号:F000047628 04检验类型是激活的, 我们执行事务代码COR1创建了工单,并下达工单。
SAP虾客
2021/04/14
5900
SAP MM 没有启用QM的前提下可以从QI库存里退货给Vendor?
SAP MM 没有启用QM的前提下可以从QI库存里退货给Vendor? 经过验证是可以的。比如如下退货采购订单, 数量是10,勾选了”Return Items”选项, VL10B,创建交货单, 交货单 2107935574, 看交货单item里的stock type,是X,如下图: 后续使用一个质检库存发货,成功了,如下图示: 看物料凭证号数据, -完- 2020-5-20 写于苏州市。
SAP虾客
2021/01/09
3400
WBS工作分解法
工作分解结构(Work Breakdown Structure,简称WBS)跟因数分解是一个原理,就是把一个项目,按一定的原则分解,项目分解成任务,任务再分解成一项项工作,再把一项项工作分配到每个人的日常活动中,直到分解不下去为止。
PM吃瓜
2020/07/09
1.6K0
WBS工作分解法
基于解析器组合子的语法解析器(上)
语法,在语言学中是指任意自然语言中句子、短语以及词汇等语法单位的语法结构与语法意义的规律,本质上即音义结合体之间的结合规律。在程序语言的范畴上,描述的则是基于文本的源码以特定规则放置,来表达其特有的语义内涵。
黄啊码
2022/06/20
2.7K0
点击加载更多

相似问题

优化boost::spirit::qi解析器

13

boost::spirit::qi::double_和boost::spirit::qi::int_

10

使用boost::spirit::qi::symbols

11

使用lookahead解决boost::spirit::qi语法歧义

10

boost::spirit::qi -可选匹配

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文