ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 在语义动作中添加到精神qi符号表

2019-08-26 06:07:31  阅读:246  来源: 互联网

标签:boost-spirit-qi c boost-spirit


按照boost::spirit::qi::symbols documentation的开头段落,我假设从语义动作中添加符号到qi ::符号并不太难.不幸的是,它似乎并不像我想象的那么简单.

以下测试代码表明了问题:

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>

namespace qi = boost::spirit::qi;

typedef qi::symbols<char, unsigned int> constants_dictionary;

template <typename Iter> struct parser : public qi::grammar<Iter, qi::space_type> {

    parser(constants_dictionary &dict) : parser::base_type(start) {

        start = qi::lit("@") >> ((+qi::char_) >> qi::uint_)[dict.add(qi::_1, qi::_2)];
    }

    qi::rule<Iter> start;
};

int main() {
    constants_dictionary dict;
    parser<std::string::const_iterator> prsr(dict);
    std::string test = "@foo 3";
    parse(test.begin(), test.end(), prsr, qi::space);
}

从VS2010中提供与qi :: _ 2相关的类型错误:

C:\Users\k\Coding\dashCompiler\spirit_test.cpp(12) : error C2664: 'const boost::
spirit::qi::symbols<Char,T>::adder &boost::spirit::qi::symbols<Char,T>::adder::o
perator ()<boost::spirit::_1_type>(const Str &,const T &) const' : cannot conver
t parameter 2 from 'const boost::spirit::_2_type' to 'const unsigned int &'
        with
        [
            Char=char,
            T=unsigned int,
            Str=boost::spirit::_1_type
        ]
        Reason: cannot convert from 'const boost::spirit::_2_type' to 'const uns
igned int'
        No user-defined-conversion operator available that can perform this conv
ersion, or the operator cannot be called
        C:\Users\k\Coding\dashCompiler\spirit_test.cpp(10) : while compiling cla
ss template member function 'parser<Iter>::parser(constants_dictionary &)'
        with
        [
            Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
        ]
        C:\Users\k\Coding\dashCompiler\spirit_test.cpp(21) : see reference to cl
ass template instantiation 'parser<Iter>' being compiled
        with
        [
            Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
        ]

(为令人讨厌的VS2010错误风格道歉)

我应该使用什么语法来添加(以及稍后删除)此表中的符号?

解决方法:

这个问题has been answered before.但是,你发布的代码存在很多问题,所以我会逐一修复它们,以免你不必要地盯着错误信息页面.

工作代码(加上输出验证)是here on liveworkspace.org.

笔记:

>语义动作必须是凤凰演员,即你需要

> boost :: bind,phoenix :: bind,std :: bind
> phoenix :: lambda<>或者phoenix :: function<>
>一个函数指针或多态可调用对象(根据文档)

我推荐phoenix :: bind(在这种特殊情况下),我在下面给出

>解析器的队长和启动规则之间存在不匹配
> qi :: char_吃掉所有字符.结合船长,结果
 在解析失败时,因为(显然)值中的数字也是
 吃了qi :: char_.基于qi :: lexeme [qi :: graph],我向您展示了许多解决方案之一
>使用qi :: lexeme’绕过’船长(即阻止qi :: graph切割)
跨越空白,因为船长,好吧,跳过它)
> qi :: parse不带船长;使用qi :: phrase_parse(
它似乎起作用的原因是任何尾随的“可变参数”参数都是
绑定到解析器的公开属性,在本例中是
未指定,因此qi :: unused_type).
>如果你想直接传递test.begin()和test.end()
qi :: phrase_parse,你需要明确你想要const迭代器.该
更典型的解决方案是引入明确类型的变量
(例如,第一个和最后一个)

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>

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

typedef qi::symbols<char, unsigned int> constants_dictionary;

template <typename Iter> struct parser : qi::grammar<Iter, qi::space_type> 
{
    parser(constants_dictionary &dict) : parser::base_type(start) 
    {
        start = qi::lit("@") >> (qi::lexeme [+qi::graph] >> qi::uint_)
            [ phx::bind(dict.add, qi::_1, qi::_2) ]
            ;
    }

    qi::rule<Iter, qi::space_type> start;
};

int main() {
    constants_dictionary dict;
    parser<std::string::const_iterator> prsr(dict);
    const std::string test = "@foo 3";

    if (qi::phrase_parse(test.begin(), test.end(), prsr, qi::space))
    {
        std::cout << "check: " << dict.at("foo") << "\n";
    }
}

标签:boost-spirit-qi,c,boost-spirit
来源: https://codeday.me/bug/20190826/1726989.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有