标签: boost-spirit

使用boost :: spirit,我如何要求部分记录在自己的行上?

我有一个记录解析器,它会抛出几个异常中的一个来指示哪个规则失败了.

前面的事:

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>

using namespace boost::spirit;
using namespace boost::spirit::ascii;
using namespace boost::spirit::qi;
using namespace boost::spirit::qi::labels;

using boost::phoenix::function;
using boost::phoenix::ref;
using boost::spirit::qi::eol;
using boost::spirit::qi::fail;
using boost::spirit::qi::lit;
using boost::spirit::qi::on_error;

using BOOST_SPIRIT_CLASSIC_NS::file_position;
using BOOST_SPIRIT_CLASSIC_NS::position_iterator;
Run Code Online (Sandbox Code Playgroud)

我们使用position_iterator来自Spirit.Classic,因此以下流插入运算符非常方便.

std::ostream&
operator<<(std::ostream& o, const file_position &fp)
{
  o << fp.file << ": " << fp.line << ',' << fp.column;
  return o;
}
Run Code Online (Sandbox Code Playgroud)

模板会err_t因为抛出与不同形式的解析失败相关的异常而触发样板.

template <typename Exception>
struct err_t { …
Run Code Online (Sandbox Code Playgroud)

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

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

提升精神和Lex解析器问题

我一直在努力尝试(逐步)修改文档中的示例代码,但没有太大的不同,我没有得到我期望的行为.具体来说,"if"语句在(我的意图是)它应该传递时失败(有一个"else"但是在调试期间删除了部分解析器).赋值语句工作正常.我有一个"while"语句,它与"if"语句有同样的问题,所以我相信如果我能得到帮助来弄清楚为什么一个不工作它应该很容易让另一个去.它必须是一种微妙的,因为这几乎是逐字逐句的,其中一个例子.

#include <iostream>
#include <fstream>
#include <string>

#define BOOST_SPIRIT_DEBUG
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#include <boost/spirit/include/phoenix_container.hpp>

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

inline std::string read_from_file( const char* infile )
{
    std::ifstream instream( infile );
    if( !instream.is_open() )
    {
        std::cerr << "Could not open file: \"" << infile << "\"" << std::endl;
        exit( -1 );
    }
    instream.unsetf( std::ios::skipws );
    return( std::string(
                std::istreambuf_iterator< char >( instream.rdbuf() ),
                std::istreambuf_iterator< char >()
          ) );
}

template< typename …
Run Code Online (Sandbox Code Playgroud)

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

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

Boost :: Spirit简单的语法示例

我正在阅读Boost Spirit(和Boost Fusion)教程(版本1.48.0).我一直在玩玩具员工的例子.链接到源是这里:

http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/employee.cpp

这是示例的语法:

employee_parser() : employee_parser::base_type(start)
    {
        using qi::int_;
        using qi::lit;
        using qi::double_;
        using qi::lexeme;
        using ascii::char_;

        quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];

        start %=
            lit("employee")
            >> '{'
            >>  int_ >> ','
            >>  quoted_string >> ','
            >>  quoted_string >> ','
            >>  double_
            >>  '}'
            ;
    }

    qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
    qi::rule<Iterator, employee(), ascii::space_type> start;
Run Code Online (Sandbox Code Playgroud)

我的修改删除了引号的处理,只解析分隔符之间的任何字符,并将其分配给解析器映射到的结构.

        //quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
        start %=
            lit("employee")
            >> '{'
            >>  int_ >> ','
            >>  +(char_) …
Run Code Online (Sandbox Code Playgroud)

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

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

使用Boost.Spirit编译一个简单的解析器

我正在攻击的一个简单的骨架实用程序的一部分我有一个语法来触发文本中的替换.我认为这是一种很好的方式来适应Boost.Spirit,但模板错误是一种独特的喜悦.

以下是完整的代码:

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

namespace bsq = boost::spirit::qi;

namespace {
template<typename Iterator>
struct skel_grammar : public bsq::grammar<Iterator> {
    skel_grammar();

private:
    bsq::rule<Iterator> macro_b;
    bsq::rule<Iterator> macro_e;
    bsq::rule<Iterator, bsq::ascii::space_type> id;
    bsq::rule<Iterator> macro;
    bsq::rule<Iterator> text;
    bsq::rule<Iterator> start;
};

template<typename Iterator>
skel_grammar<Iterator>::skel_grammar() : skel_grammar::base_type(start)
{
    text = bsq::no_skip[+(bsq::char_ - macro_b)[bsq::_val += bsq::_1]];
    macro_b = bsq::lit("<<");
    macro_e = bsq::lit(">>");
    macro %= macro_b >> id >> macro_e;
    id %= -(bsq::ascii::alpha | bsq::char_('_'))
        >> +(bsq::ascii::alnum | bsq::char_('_'));
    start = *(text | macro); …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit

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

解析许多其他命名集的命名集

所以我想用boost :: spirit :: qi编写一个......那么......不那么简单的解析器.我知道提升精神的基本知识,在过去的几个小时里第一次熟悉它.

基本上我需要解析这个:

# comment

# other comment

set "Myset A"
{
    figure "AF 1"
    {
        i 0 0 0
        i 1 2 5
        i 1 1 1
        f 3.1 45.11 5.3
        i 3 1 5
        f 1.1 2.33 5.166
    }

    figure "AF 2"
    {
        i 25 5 1
        i 3 1 3
    }
}

# comment

set "Myset B"
{
    figure "BF 1"
    {
        f 23.1 4.3 5.11
    }
}

set "Myset C"
{
    include "Myset …
Run Code Online (Sandbox Code Playgroud)

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

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

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中定义使用子解析器参数化的解析器

我想将一些旧的手写解析代码转换为Boost Spirit,并在此过程中学习(更多)精神.旧代码使用流和模板来解析某些数据类型和某些容器的定义.

一些典型的格式:

VECTOR[number_of_items,(item_1, item_2 .... item_n)]
PAIR(p1, p2)
RECT[(left,top)-(right,bottom)]
Point( x, y )
Size( x, y )
Run Code Online (Sandbox Code Playgroud)

解析函数是模板,其中项目的类型作为模板参数,并使用流作为输入,例如

 template<class T> std::istream& operator>>(std::Stream& in, std::vector<T>& v);

 template<class T1, class T2> std::istream& operator>>(std::istream& in, std::pair<T1, T2>& p);

 template<class T1, class T2> std::istream& operator>>(std::istream& in, RectType<T>& r);
 etc.
Run Code Online (Sandbox Code Playgroud)

向量的解析器(流提取器)调用解析器以获取模板类型.

使用这些可以解析整数矩形,双矩形以及字符串和整数对的向量的定义.

是否有可能使用Spirit编写模板解析器来调用模板类型的子解析器?

c++ templates boost-spirit parser-generator boost-spirit-qi

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

了解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将其解析为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
查看次数

提升精神(X3)符号表,产生UTF8字符串

我正在尝试将LaTeX转义码(例如\alpha)解析为Unicode(数学)字符(即U+1D6FC).

现在这意味着我正在使用这个symbols解析器(规则):

struct greek_lower_case_letters_ : x3::symbols<char32_t>
{
  greek_lower_case_letters_::greek_lower_case_letters_()
  {
    add("alpha",   U'\u03B1');
  }
} greek_lower_case_letter;
Run Code Online (Sandbox Code Playgroud)

这很好,但意味着我得到了std::u32string一个结果.我想要一种优雅的方法来保持代码中的Unicode代码点(可能是未来的自动化)和维护原因.有没有办法让这种解析器解析为UTF-8 std::string

我想过将symbolsstruct解析为a std::string,但这样效率非常低(我知道,早期优化bla bla).

我希望有一些优雅的方式,而不是通过一堆箍来使这工作(symbols将结果附加到字符串).

我担心使用代码点值并想要UTF8会产生转换的运行时成本(或者是否有constexprUTF32-> UTF8转换?).

c++ boost boost-spirit c++14 boost-spirit-x3

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