标签: boost-spirit

混合"替代"与"选项"时的Boost.Spirit错误?

我只使用Boost.Spirit(来自Boost 1.44)三天,试图通过RFC2822中的确切语法解析原始电子邮件.我以为我开始理解它并到达某个地方,但后来我遇到了一个问题:

#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
using qi::omit;
using qi::repeat;
using std::cout;
using std::endl;

typedef qi::rule<std::string::const_iterator, std::string()> strrule_t;

void test(const std::string input, strrule_t rule) {
    std::string target;
    std::string::const_iterator i = input.begin(), ie = input.end();

    if (qi::parse(i, ie, rule, target)) {
        cout << "Success: '" << target << "'" << endl;
    } else {
        cout << "Failed to match." << endl;
    }
}

int main() {
    strrule_t obsolete_year = omit[-qi::char_(" \t")] >> repeat(2)[qi::digit] >>
        omit[-qi::char_(" \t")];
    strrule_t …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
736
查看次数

如何使用boost :: spirit :: lex实现include指令?

我有一个简单的配置文件解析器,由spirit :: lex和spirit :: qi构建.当词法分析器到达模式时,include "path"我希望包含文件的文本.您可能知道,spirit :: lexer :: begin()启动扫描过程:

// Read file contents into a std::string
...

// _first and _last are const char*
_first = _contents.c_str();
_last  = &_first[_input.size()];

// _token is a lexer::iterator_type for the current token
_token = _lexer.begin(_first, _last);
Run Code Online (Sandbox Code Playgroud)

我的想法是有一个存储lexer状态的堆栈表示为结构:

struct LexerState
{
    const char* first;
    const char* last;
    std::string contents;
};
Run Code Online (Sandbox Code Playgroud)

词法分析器将识别模式,include "path"并在语义动作中提取包含文件的路径.然后,将当前词法分析器状态推入堆栈,将文件的内容加载到字符串中,并使用lexer :: begin()按上述方式初始化新状态.

当词法分析器找到EOF字符时,弹出堆栈并使用先前的词法分析器状态变量调用lexer :: begin().

可以这样重复调用lexer :: begin()吗?如何让lex :: lexer识别include "path"模式和EOF字符而不将令牌返回到qi解析器?

最后,有没有其他或更好的方法来实现这一目标?

c++ boost boost-spirit boost-spirit-lex

6
推荐指数
1
解决办法
505
查看次数

为什么这个boost :: spirit :: qi规则与输入不匹配?

我尝试继续处理我之前的示例并扩展规则.我的问题是,使用ID_IDENTIFIER的规则不起作用 - 虽然我知道词法分析器正在工作(使用单元测试).

这是一个例子:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>

namespace qi  = boost::spirit::qi;
namespace lex = boost::spirit::lex;

enum LexerIDs { ID_IDENTIFIER, ID_WHITESPACE, ID_INTEGER, ID_FLOAT, ID_PUNCTUATOR };

template <typename Lexer>
struct custom_lexer : lex::lexer<Lexer>
{
    custom_lexer()
        : identifier    ("[a-zA-Z_][a-zA-Z0-9_]*")
        , white_space   ("[ \\t\\n]+")
        , integer_value ("[1-9][0-9]*")
        , hex_value     ("0[xX][0-9a-fA-F]+")
        , float_value   ("[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?")
        , float_value2  ("[0-9]+\\.([eE][+-]?[0-9]+)?")
        , punctuator    ("\\[|\\]|\\(|\\)|\\.|&>|\\*\\*|\\*|\\+|-|~|!|\\/|%|<<|>>|<|>|<=|>=|==|!=|\\^|&|\\||\\^\\^|&&|\\|\\||\\?|:|,")// [ ] ( ) . &> ** * + - ~ ! / % << >> < > <= >= == != ^ & …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi boost-spirit-lex

6
推荐指数
1
解决办法
216
查看次数

提升精神将整个比赛作为一个字符串

我正在尝试使用boost精神框架来定义自己的语法,并且我正在定义这样的匹配规则:

value = (
        char_('"') >>
        (*qi::lexeme[
                char_('\\') >> char_('\\') |
                char_('\\') >> char_('"')  |
                graph - char_('"') |
                char_(' ')
        ])[some_func] >>
        char_('"')
);
Run Code Online (Sandbox Code Playgroud)

我想将一个动作 - some_func - 分配到它的一部分,并将整个匹配的字符串作为参数传递.但不幸的是,我会得到类似的东西vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...>.我可以以某种方式将整个数据作为char*,std :: string甚至void*与大小?

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
2096
查看次数

Boost Spirit Qi自定义同步属性(通过语义操作设置struct属性的特定成员)

假设我有一个我想用Spirit Qi解析的结构,定义如下:

struct data_
{
    bool export;
    std::wstring name;

    data_() : export(false) {}
};
Run Code Online (Sandbox Code Playgroud)

另外,假设结构已适应融合,如下所示:

BOOST_FUSION_ADAPT_STRUCT(
    data_,
    (bool, export)
    (std::wstring, name)
)
Run Code Online (Sandbox Code Playgroud)

相关规则是:

qi::rule<Iterator, data_(), skipper<Iterator> > rule_data;

rule_data = -lexeme["SpecialText" >> !(alnum | '_')] [ boost::phoenix::at_c<0> = true ] // If this string is found, , set "export" to true
            > lexeme["Name" >> !(alnum | '_')] // this is supposed to go into the "name" member
Run Code Online (Sandbox Code Playgroud)

到目前为止,这编译得非常好.但是,"名字"现在保持空白!

基本上,我问:鉴于"SpecialText"在"Name"之前,我如何正确地合成"export"的布尔属性,而不是字符串?

编辑 把我的头发拉出来之后,我随机偶然发现了"匹配[]"解析器,这似乎做了我想要的.

尽管如此,问题仍然存在于一般形式中,例如,如果我想返回某个字符串或其他数据类型而不是bool.本质上,如何通过语义操作设置struct属性的特定成员.

c++ attributes boost-spirit boost-spirit-qi synthesize

6
推荐指数
1
解决办法
1428
查看次数

了解Boost.spirit的字符串解析器

#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
int main ()
{
    using qi::string;

    std::string input("a");
    std::string::iterator strbegin = input.begin();
    std::string p;
    bool ok = qi::phrase_parse(strbegin, input.end(),
            ((string("a")  >> string("a")) | string("a")),
            qi::space,                  
            p);                               

    if (ok && strbegin == input.end()) {
        std::cout << p << std::endl;
        std::cout << p.size() << std::endl;
    } else {
        std::cout << "fail" << std::endl;
        std::cout << std::string(strbegin, input.end()) << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

该计划输出aa.这怎么可能?输入字符串是a.解析器应匹配aaa.我写的string("a")只是测试运营商.

使用时char_ …

c++ parsing boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
1139
查看次数

防止Boost Spirit符号解析器过早接受关键字

如何在使用有效关键字(符号)启动时阻止Boost Spirit符号解析器接受关键字(符号).我希望构造失败解析'ONEMORE'作为一个整体而不能成功解析'ONE',因为这是一个有效的关键字,然后在'MORE'失败.

以下是代码的实际输出:

Keyword as a number: 1
Keyword as a number: 2
Keyword as a number: 1
Invalid keyword: MORETHREE
Run Code Online (Sandbox Code Playgroud)

这就是我喜欢的:

Keyword as a number: 1
Keyword as a number: 2
Invalid keyword: ONEMORE
Keyword as a number: 3
Run Code Online (Sandbox Code Playgroud)

代码只是一个示例来获得重点.

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

void printNumber( unsigned u )
{
    cout << "Keyword as a number: " << u << endl;
}

void printInvalidKeyword( …
Run Code Online (Sandbox Code Playgroud)

c++ boost symbols boost-spirit

6
推荐指数
1
解决办法
561
查看次数

使用Alternative解析器提升精神表现不佳

我已经问过这个问题.但由于没有答案,我现在再次询问完整的可编辑源代码片段.

由于boost :: variant move semantic存在一些问题,因此应该使用no std = c ++ 11选项编译此代码段.只是'g ++ -Wall -pedantic'.

在此代码段中,您将找到"// Comment here"行.您可以在下面的句子中发表评论,直到"//这里-----".如果取消注释此块,则此程序的性能非常差.

所以只要我能看到瓶颈就是替代解析器.我需要的是一些关于改进/改变我的语法以提高解析性能的建议.谢谢.

码:

#include <string>
#include <vector>
#include <iostream>

#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>
#include <boost/array.hpp>
#include <boost/variant/apply_visitor.hpp>

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

namespace client {
  typedef std::string::iterator input_iterator_type;

  struct op_and {}; 
  struct op_or …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
503
查看次数

使用boost :: spirit将其解析为vector <vector <double >>

我的目的是将逗号分隔的值列表解析为嵌套向量.这个清单是二维的.基本问题是:

是否可以使用boost :: spirit解析为向量的向量?

像"牵引"下的表格:

' 
' RPM
0,5000,10000,15000,20000,25000
'
' Temp
'
-40.,0.,20.,40.
'
' Traction
200.,175.,170.,165.,160.,150.
200.,175.,170.,165.,160.,150.
165.,165.,160.,155.,145.,145.
160.,155.,150.,145.,145.,140.
'
Run Code Online (Sandbox Code Playgroud)

在接下来的步骤中,我想阅读4维数据,但是现在我正在努力解决第二个问题.数据结构如下:

struct table {
    std::vector<double>  index;
    std::vector<double>  index2;
    std::vector<std::vector<double> > base;
};
Run Code Online (Sandbox Code Playgroud)

语法是恕我直言,非常简单如下:

comment %= qi::lexeme[ '\'' >> *(qi::standard::char_ - qi::eol)] >> qi::eol;
commentblock = comment >> *(comment);
doublevector = qi::double_ % ',' >> qi::eol ;
vectorblock = *doublevector;
start = commentblock            >>
        doublevector            >>
        commentblock            >>
        doublevector            >>
        commentblock            >>
        vectorblock             >>
        commentblock            >>
        qi::eoi
        ;
Run Code Online (Sandbox Code Playgroud)

到目前为止,我解析这两个向量 …

c++ boost boost-spirit stdvector

6
推荐指数
1
解决办法
442
查看次数

了解Boost.Spirit中的列表运算符(%)

你能帮助我理解Boost.Spirit中a % b解析器和它的扩展a >> *(b >> a)形式之间的区别吗?即使参考手册指出它们是等效的,

列表运算符a % b是一个二元运算符,它匹配a由出现次数分隔的一个或多个重复的列表b.这相当于a >> *(b >> a).

以下程序根据使用的结果产生不同的结果:

#include <iostream>
#include <string>
#include <vector>

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>

struct Record {
  int id;
  std::vector<int> values;
};

BOOST_FUSION_ADAPT_STRUCT(Record,
  (int, id)
  (std::vector<int>, values)
)

int main() {
  namespace qi = boost::spirit::qi;

  const auto str = std::string{"1: 2, 3, 4"};

  const auto rule1 = qi::int_ >> ':' >> (qi::int_ % ',')                 >> …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
2
解决办法
847
查看次数