标签: boost-spirit

使用boost spirit语法(boost 1.43和g ++ 4.4.1)第二部分构建错误

我在编写一个小精神/ qi语法时遇到了问题.我正在使用boost 1.43和g ++ 4.4.1.

输入语法标题:构建错误似乎指向'指令'规则的定义,也许是'[sp :: _ val = sp :: _ 1]'以某种方式破坏了它,但这或多或少基于关于精神文档教程使用xml节点解析器做了什么

inputGrammar.h

#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_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>

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

namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;
//using namespace boost::spirit::arg_names;

namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;

using phoenix::at_c;
using phoenix::push_back;


template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> …
Run Code Online (Sandbox Code Playgroud)

c++ parsing boost-spirit

4
推荐指数
1
解决办法
1268
查看次数

Boost Spirit规则和语法中的模板参数中的括号

看看这个用于实现Spirit解析器的示例,当我尝试编写类似的东西时,有些事情让我感到困惑.

语法(std::map<std::string, std::string>())的属性模板参数和规则的签名模板参数(例如qi::rule<Iterator, std::string()> key, value)包含括号.

namespace qi = boost::spirit::qi;

template <typename Iterator>
struct keys_and_values
  : qi::grammar<Iterator, std::map<std::string, std::string>()> // <- parentheses here
{
    keys_and_values()
      : keys_and_values::base_type(query)
    {
        query =  pair >> *((qi::lit(';') | '&') >> pair);
        pair  =  key >> -('=' >> value);
        key   =  qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
        value = +qi::char_("a-zA-Z_0-9");
    }
    qi::rule<Iterator, std::map<std::string, std::string>()> query; // <- parentheses here
    qi::rule<Iterator, std::pair<std::string, std::string>()> pair; // <- parentheses here
    qi::rule<Iterator, std::string()> key, …
Run Code Online (Sandbox Code Playgroud)

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

4
推荐指数
1
解决办法
825
查看次数

如何在boost :: spirit :: lex基lexer中添加符号表接口?

要实现对typedef的支持,当lexer识别标识符并返回不同的标记时,您需要查找符号表.这在flex lexer中很容易完成.我试图使用boost Spirit来构建解析器并在示例中查看,但它们都没有在词法分析器和解析器之间传递任何上下文信息.在mini c编译器教程示例中,最简单的方法是什么?

boost boost-spirit boost-spirit-lex

4
推荐指数
1
解决办法
490
查看次数

Boost :: Spirit中的复合语法

我有以下符合预期的语法。

struct query_term {
    std::string term;
    bool is_tag;

    query_term(const std::string &a, bool tag = false): term(a), is_tag(tag) { } };

template<typename Iterator> struct query_grammar: grammar<Iterator, std::vector<query_term>(), space_type> {
    query_grammar():
        query_grammar::base_type(query) {

        word %= +alnum;
        tag  =  (omit[word >> ':'] >> word[_val = phoenix::construct<query_term>(_1, true)]);
        non_tag  =  word[_val = phoenix::construct<query_term>(_1, false)];
        query = (
                  (omit[word >> ':'] >> word[push_back(_val, phoenix::construct<query_term>(_1, true))])
                |
                  word[push_back(_val,
                            phoenix::construct<query_term>(_1))
                  ]
                ) % space;
    };

    qi::rule<Iterator, std::string(), space_type> word;
    qi::rule<Iterator, query_term, space_type> tag;
    qi::rule<Iterator, query_term, space_type> non_tag; …
Run Code Online (Sandbox Code Playgroud)

c++ parsing boost boost-spirit

4
推荐指数
1
解决办法
727
查看次数

尽管令牌不完整,但提升精神意味着成功解析

我有一个非常简单的路径构造,我试图用boost spirit.lex解析.

我们有以下语法:

token := [a-z]+
path := (token : path) | (token)
Run Code Online (Sandbox Code Playgroud)

所以我们这里只讨论冒号分隔的小写ASCII字符串.

我有三个例子"xyz","abc:xyz","abc:xyz:".

前两个应被视为有效.第三个,有一个尾随结肠,不应被视为有效.不幸的是,解析器我已经认识到这三个都是有效的.语法不应该允许空令牌,但显然精神就是这样做的.为了让第三个被拒绝,我错过了什么?

此外,如果您阅读下面的代码,则在注释中还有另一个版本的解析器要求所有路径以分号结尾.当我激活那些线时,我可以得到适当的行为(即拒绝"abc:xyz:;"),但这不是我想要的.

有人有主意吗?

谢谢.

#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 <iostream>
#include <string>

using namespace boost::spirit;
using boost::phoenix::val;

template<typename Lexer>
struct PathTokens : boost::spirit::lex::lexer<Lexer>
{
      PathTokens()
      {
         identifier = "[a-z]+";
         separator = ":";

         this->self.add
            (identifier)
            (separator)
            (';')
            ;
      }
      boost::spirit::lex::token_def<std::string> identifier, separator;
};


template <typename Iterator>
struct PathGrammar 
   : boost::spirit::qi::grammar<Iterator> 
{
      template <typename TokenDef>
      PathGrammar(TokenDef const& tok)
         : PathGrammar::base_type(path)
      {
         using boost::spirit::_val; …
Run Code Online (Sandbox Code Playgroud)

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

4
推荐指数
1
解决办法
904
查看次数

Boost :: spirit :: qi定义了计算器的nullaries

我正在尝试为数学表达式编写一个解析器,其中命名变量是boost::spirit(版本1_51_0)中的nullaries,我完全是新的.我定义typedef boost::function<double()> Value,我的规则将被声明如下:qi::rule<Iterator, Value()> expression, term, others, ...;

我用这个宏定义了nullaries上的二元运算符

#define BINARY_FUNCTOR(name, op)                        \
struct name                                             \
{                                                       \
  name(Value x, Value y): x_(x), y_(y) {}               \
  double operator()() { return x_() op y_(); }          \
  Value x_, y_;                                         \
}; 
Run Code Online (Sandbox Code Playgroud)

并且有ADD,SUB等从我所看到的例子,我期望的规则,这样的定义:

expression = term
             >> *( (lit('+') >> term[ADD(_val, _1)])
                 | (lit('-') >> term[SUB(_val, _1)])
                 );
Run Code Online (Sandbox Code Playgroud)

但这似乎不是正确的语法,因为我得到一个错误

boost/spirit/home/support/action_dispatch.hpp:162: error: no match for call to ‘(const<unnamed>::SUB) (boost::function<double ()()>&, boost::spirit::context<boost::fusion::cons<boost::function<double ()()>&, boost::fusion::nil>, boost::fusion::vector0<void> …
Run Code Online (Sandbox Code Playgroud)

c++ boost abstract-syntax-tree boost-spirit boost-spirit-qi

4
推荐指数
1
解决办法
406
查看次数

提升精神浮点数解析器的精度

在比较boost :: lexical_cast和boost spirit解析时,我注意到了一些奇怪的东西.我正在尝试将字符串解析为float.由于某种原因,精神给出了非常不精确的结果.例如:当使用lexical_cast解析字符串"219721.03839999999"时,我得到219721.03,这或多或少都可以.但是当我使用精神(见下面的代码)时,我得到了"219721.11",这远远不是好的.知道为什么会这样吗?

template<>
inline float LexicalCastWithTag(const std::string& arg)
{
    float result = 0;

    if(arg.empty())
    {
        throw BadLexicalCast("Cannot convert from to std::string to float");
    }

    auto itBeg = arg.begin();
    auto itEnd = arg.end();

    if(!boost::spirit::qi::parse(itBeg, itEnd, boost::spirit::qi::float_, result) || itBeg != itEnd)
    {
        throw BadLexicalCast("Cannot convert from to std::string to float");
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit lexical-cast

4
推荐指数
1
解决办法
1138
查看次数

boost spirit qi on_error通过引用传递error_handler结构

我和Spirit Qi有另一个阻碍问题.

我在一个名为error_handler的functor结构中实现了错误处理.这通过引用传递给语法构造函数(参见Qi的MiniC示例).

然后我on_error<fail>在语法的构造函数中定义了:

typedef boost::phoenix::function<error_handler<> > error_handler_function;
on_error<fail>(gr_instruction,
        error_handler_function(err_handler)(L"Error: Expecting ", _4, _3));
        // more on_error<fail>s...
Run Code Online (Sandbox Code Playgroud)

但是,我error_handler有私人会员.似乎每次都on_error被调用,err_handler对象被复制,因此一旦仿函数离开,局部变量就会被破坏.

我尝试通过引用传递处理程序:

typedef boost::phoenix::function<error_handler<>& > error_handler_function; // <--- Note the ampersand!

on_error<fail>(gr_instruction,
        error_handler_function(err_handler)(L"Error: Expecting ", _4, _3));
        // more on_error<fail>s...
Run Code Online (Sandbox Code Playgroud)

然而,问题仍然存在:on_error()适用于副本err_handler,而不是单个实例!

我也尝试过boost::phoenix::ref(err_handler)只有编译错误的变体.

当然,必须有一个简单的解决方案来通过引用传递处理程序?

我很感激任何意见.谢谢您的帮助.

c++ reference boost-spirit boost-phoenix boost-spirit-qi

4
推荐指数
1
解决办法
1978
查看次数

使用utf-32解析器处理Boost.Spirit中的utf-8

我有一个类似的问题,比如如何使用boost :: spirit来解析UTF-8?以及如何使用boost :: spirit匹配unicode字符?但这些都没有解决我面临的问题.我有一个std::stringUTF-8字符,我用它u8_to_u32_iterator来包装std::string和使用这样的unicode终端:

BOOST_NETWORK_INLINE void parse_headers(std::string const & input, std::vector<request_header_narrow> & container) {
        using namespace boost::spirit::qi;
        u8_to_u32_iterator<std::string::const_iterator> begin(input.begin()), end(input.end());
        std::vector<request_header_narrow_utf8_wrapper> wrapper_container;
        parse(
            begin, end,
            *(
                +(alnum|(punct-':'))
                >> lit(": ")
                >> +((unicode::alnum|space|punct) - '\r' - '\n')
                >> lit("\r\n")
            )
            >> lit("\r\n")
            , wrapper_container
            );
        BOOST_FOREACH(request_header_narrow_utf8_wrapper header_wrapper, wrapper_container)
        {
            request_header_narrow header;
            u32_to_u8_iterator<request_header_narrow_utf8_wrapper::string_type::iterator> name_begin(header_wrapper.name.begin()),
                                                                                          name_end(header_wrapper.name.end()),
                                                                                          value_begin(header_wrapper.value.begin()),
                                                                                          value_end(header_wrapper.value.end());
            for(; name_begin != name_end; ++name_begin)
                header.name += *name_begin;
            for(; value_begin != value_end; …
Run Code Online (Sandbox Code Playgroud)

c++ boost utf-8 boost-spirit

4
推荐指数
1
解决办法
1187
查看次数

在语义动作中提升精神改变变量值

我想在语义操作中更改局部变量值,如下所示:

#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 spirit = boost::spirit;
namespace ascii = boost::spirit::ascii;
using boost::phoenix::ref;
using boost::phoenix::bind;

void dummy(const std::vector<char>& v, int& var)
{
    var = 7;
}

template <typename Iterator>
struct x_grammar : public qi::grammar<Iterator, std::string(), ascii::space_type>
{
public:
    x_grammar() : x_grammar::base_type(start_rule, "x_grammar")
    {
        using namespace qi;
        int local_var = 0;
        start_rule = (+(char_ - ";"))[bind(dummy, _1, ref(local_var))];
        //repeat(ref(local_var))[some_rule];
    }
private:
    qi::rule<Iterator, std::string(), ascii::space_type> start_rule;
};

int main()
{
    typedef std::string::const_iterator …
Run Code Online (Sandbox Code Playgroud)

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

4
推荐指数
1
解决办法
1282
查看次数