标签: boost-spirit

使用Boost :: Spirit的简单表达式解析器示例?

是否有人知道在线资源,我可以找到如何使用Boost :: Spirit?编写简单的表达式解析器.

我不一定需要评估表达式,但我需要解析它并能够返回一个布尔值来指示表达式是否可解析(例如括号不匹配等).

我需要解析器能够识别函数名称(例如foo和foobar),所以这也是帮助我学习编写BNF表示法的有用示例.

表达式将是常规算术方程,即包括以下符号:

  1. 打开/关闭括号
  2. 算术运算符
  3. 识别函数名称,并检查其所需的参数

c++ expression boost-spirit

11
推荐指数
2
解决办法
1万
查看次数

用提升精神解析一对整体

我有以下代码:

std::string test("1.1");
std::pair<int, int> d;

bool r = qi::phrase_parse(
        test.begin(),
        test.end(),
        qi::int_ >> '.' >> qi::int_,
        space,
        d
        );
Run Code Online (Sandbox Code Playgroud)

所以我试图解析字符串测试并将结果放在std :: pair d中.但是它没有用,我怀疑它与复合属性规则有关.

有关如何使其工作的任何提示?

编译器错误如下:

错误:没有匹配函数来调用'std :: pair :: pair(const int&)'

c++ parsing boost boost-spirit

11
推荐指数
1
解决办法
1358
查看次数

Boost.Spirit:Lex + Qi错误报告

我正在编写一个解析器,用于使用缩进等非常复杂的配置文件.我决定使用Lex将输入分解为令牌,因为它似乎使生活更轻松.问题是我找不到任何使用Qi错误报告工具(on_error)的示例,其中解析器使用令牌流而不是字符进行操作.

要使用的错误处理程序on_error需要一些能够准确指示错误在输入流中的位置.所有示例都只是std::string从迭代器对构造并打印出来.但是如果使用Lex,则迭代器是标记序列的迭代器,而不是字符.在我的程序中,这导致std::string在我注意到无效的迭代器类型之前挂起构造函数.

据我所知,令牌可以将输入流的一对迭代器作为其值.这是默认属性类型(如果类型是这样lex::lexertl::token<>).但是,如果我想我的令牌包含一些解析(更多有用的int,std::string等等),这些迭代器都将丢失.

如何在使用带Qi的Lex时生成指示输入流中位置的人性化错误消息?有这种用法的例子吗?

谢谢.

c++ error-handling boost lex boost-spirit

11
推荐指数
1
解决办法
941
查看次数

如何在现代C++中解析文本数据文件?

我(经常)面临着必须解析文本数据文件的任务 - 在"每个人"使用XML之前使用的文本结构化数据表示 - 这是某种行业标准.(这些太多了.)

无论如何,基本任务总是采用文本文件并填充某种数据结构中的内容,以便我们的C++代码可以对信息做些什么.

现在,我已经手工实现了一些简单的(并且非常多样的)解析器,并且我几乎没有鄙视.:-)

所以 - 我想知道当我想要将结构化文本数据"解析"为内存中表示时的当前技术水平(想想:任意语言的XML数据绑定).

到目前为止我发现的是" 你推荐什么解析器生成器 ",但我不太确定我是在使用解析器生成器(如ANTLR)之后.

明显的候选人似乎是pegtlBoost.Spirit,但他们似乎都很复杂(但至少他们是语言),上次我尝试过Spirit,编译错误让我疯狂.(并且pegtl需要兼容C++ 11的编译器,这仍然是一个问题(VC++ 2005).)

所以我错过了一个简单的解决方案,只是为了得到类似的东西

/begin COMPU_METHOD
  DEC "  Decimal value"
  RAT_FUNC
  "%3.0"
  "dec"
  COEFFS 0 1.000000 0.000000 0 0.000000 1.000000
/end COMPU_METHOD
Run Code Online (Sandbox Code Playgroud)

进入C++数据结构?(这只是这个文件的一部分可能看起来的任意例子.对于这种格式,我可以(并且可能应该)购买一个库来解析它,因为它足够广泛 - 对于所有格式我都不是这样的情况遭遇.)

- 或者我应该选择 Boost.Spirit 的复杂性

c++ parsing dataformat boost-spirit

11
推荐指数
1
解决办法
1137
查看次数

Boost Spirit X3无法使用变量因子编译repeat指令

我试图使用Boost Spirit X3指令重复一个可变的重复因子.基本思想是标头+有效负载,其中标头指定有效负载的大小.一个简单的例子"3 1 2 3"被解释为header = 3,data = {1,2,3}(3个整数).

我只能从精神qi文档中找到例子.它使用boost phoenix引用来包装变量因子:http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html

std::string str;
int n;
test_parser_attr("\x0bHello World",
    char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl;  // will print "11,Hello World"
Run Code Online (Sandbox Code Playgroud)

我为精神x3写了以下简单的例子,没有运气:

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>

namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;

int main( int argc, char **argv )
{ …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

11
推荐指数
1
解决办法
1372
查看次数

在精神x3的解析器规则中终止左递归

我目前仍然坚持使用boost spirit x3解析的规则.对于我要解析的内容,这是te EBNF(使用精神列表中的%运算符):

type ::= class_type | lambda_type

lambda_type ::= more_arg_lambda | one_arg_lambda

more_arg_lambda ::= "(", type%",", ")", "=>", type

one_arg_lambda ::= type, "=>", type  <- here is the left recursion

class_type ::= identifier%"::", ["<", type%",", ">"]
Run Code Online (Sandbox Code Playgroud)

usng boost spirit x3,我试图解析下面的struct/variant:

typedef x3::variant<
        nil,
        x3::forward_ast<LambdaType>,
        x3::forward_ast<ClassType>
    > Type;

struct LambdaType {
        std::vector<Type> parameters_;
        Type return_type_;
    };
struct ClassType{
        std::vector<std::string> name_; 
        std::vector<Type> template_args_;
    };
Run Code Online (Sandbox Code Playgroud)

我有一个关于我目前在这里尝试的实例,它不起作用,我也尝试改变变体解析器的顺序,它没有帮助,我得到无尽的回忆,或者没有我期望(或希望)的行为.任何人都可以帮我调试这个解析器吗?我想我在解析器中有一些类型的左递归,是否有机会避免这种情况,或者没有机会重写语法?这个gramar甚至可以用boost spirit x3解析吗?

编辑:

我设法在这个语法中消除了左递归.现在te语法如下:

type ::= class_type | lambda_type

    lambda_type ::= more_arg_lambda | …
Run Code Online (Sandbox Code Playgroud)

c++ parsing boost-spirit boost-spirit-x3

11
推荐指数
1
解决办法
508
查看次数

如何增加gcc可执行堆栈大小?

当我尝试编译它时,我有大量的Boost/Spirit元程序正在吹gcc的堆栈.

如何增加gcc的堆栈大小,以便编译该程序?

注意:没有无限递归,但有足够的偶然递归来耗尽gcc的堆栈.

c++ gcc boost-spirit

10
推荐指数
1
解决办法
1万
查看次数

我无法获取令牌的字符串值

我尝试使用Boost Spirit为一个小编程语言实现一个Lexer.

我必须得到一个令牌的值,我得到一个bad_get异常:

在抛出'boost :: bad_get'的实例后调用终止
what():boost :: bad_get:失败的值得到使用boost :: get Aborted

这样做时我得到了这个例外:

std::string contents = "void";

base_iterator_type first = contents.begin();
base_iterator_type last = contents.end();

SimpleLexer<lexer_type> lexer;

iter = lexer.begin(first, last);
end = lexer.end();

std::cout << "Value = " << boost::get<std::string>(iter->value()) << std::endl;
Run Code Online (Sandbox Code Playgroud)

我的词法分析器定义如下:

typedef std::string::iterator base_iterator_type;
typedef boost::spirit::lex::lexertl::token<base_iterator_type, boost::mpl::vector<unsigned int, std::string>> Tok;
typedef lex::lexertl::actor_lexer<Tok> lexer_type;

template<typename L>
class SimpleLexer : public lex::lexer<L> {
    private:

    public:
        SimpleLexer() {
            keyword_for = "for";
            keyword_while = "while";
            keyword_if = "if";
            keyword_else = "else"; …
Run Code Online (Sandbox Code Playgroud)

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

10
推荐指数
1
解决办法
1687
查看次数

提升::精神表达解析器

我的boost :: spirit解析器还有另外一个问题.

template<typename Iterator>
struct expression: qi::grammar<Iterator, ast::expression(), ascii::space_type> {
    expression() :
        expression::base_type(expr) {
        number %= lexeme[double_];
        varname %= lexeme[alpha >> *(alnum | '_')];

        binop = (expr >> '+' >> expr)[_val = construct<ast::binary_op<ast::add>>(_1,_2)]
              | (expr >> '-' >> expr)[_val = construct<ast::binary_op<ast::sub>>(_1,_2)]
              | (expr >> '*' >> expr)[_val = construct<ast::binary_op<ast::mul>>(_1,_2)]
              | (expr >> '/' >> expr)[_val = construct<ast::binary_op<ast::div>>(_1,_2)] ;

        expr %= number | varname | binop;
    }

    qi::rule<Iterator, ast::expression(), ascii::space_type> expr;
    qi::rule<Iterator, ast::expression(), ascii::space_type> binop;
    qi::rule<Iterator, std::string(), ascii::space_type> varname;
    qi::rule<Iterator, …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-phoenix

10
推荐指数
1
解决办法
5264
查看次数

太多的部分,汇编程序错误,使用boost :: spirit

我正在为Java的一个子集编写编译器boost::spirit,用于lexing和解析.在编译词法分析器/解析器阶段期间,编译器消耗1.6GBRAM(g++ (GCC) 4.8.1),但这不是问题,因为这台机器上有足够的内存.

然而,问题在于,当编译器完成并且汇编程序开始运行(GNU assembler (GNU Binutils) 2.23.52.20130604)时,它会崩溃;

as: build/src/ast_generate.o: too many sections (33098)
/tmp/cc0ZyvKK.s: Assembler messages:
/tmp/cc0ZyvKK.s: Fatal error: can't write build/src/ast_generate.o: File too big
as: build/src/ast_generate.o: too many sections (33098)
/tmp/cc0ZyvKK.s: Fatal error: can't close build/src/ast_generate.o: File too big
scons: *** [build/src/ast_generate.o] Error 1
Run Code Online (Sandbox Code Playgroud)

添加'-Os'到我的编译器标志,允许汇编程序处理编译器输出,但正如我所看到的,这只是时间问题,直到我遇到同样的问题,即使使用小优化标志.

检查,使用大小优化的对象文件(ast_generate.o)objdump告诉我,我正在生成pe-x86-64,这是我在Windows上所期望的.

然而,2358生成的部分对我来说是一个震惊.主要是因为似乎已经为每个部分生成了一个部分boost::spirit;

 CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_DISCARD
 ...
 60 .pdata$_ZNK5boost5lexer6detail8end_node9unique_idEv 0000000c  0000000000000000 …
Run Code Online (Sandbox Code Playgroud)

c++ gcc boost-spirit object-files sections

10
推荐指数
1
解决办法
1683
查看次数