标签: boost-spirit

使用 Boost::Spirit (V2.4) 解析到容器中

我刚刚开始深入研究 Boost::Spirit,目前最新版本——V2.4。我的问题的本质如下:

我想解析像“1a2”“3b4”这样的字符串。所以我使用的规则是:

  (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);
Run Code Online (Sandbox Code Playgroud)

规则的属性必须是“vector <double>”。我正在将其读入容器中。

完整代码:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

int main(int argc, char * argv[])
{
    using namespace std;
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    using boost::phoenix::arg_names::arg1;

    char const * first = "1a2";
    char const * last  = first + std::strlen(first);
    vector<double> h;

    rule<char const *, vector<double>()> or_test;
    or_test %=    (double_ >> lit('b') >> …
Run Code Online (Sandbox Code Playgroud)

stl boost-spirit

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

20多种变体的Boost Spirit如何使用?

我正在使用 Boost Spirit 解析一个相当复杂的语法,并且遇到了一个具有 20 多种类型(此处为 21 种)的变体的问题:

namespace eddic { namespace ast {

typedef boost::mpl::vector<
            Integer,
            IntegerSuffix,
            Float,
            Litteral,
            VariableValue,
            DereferenceValue,
            Expression,
            Unary,
            Null,
            True,
            False,
            ArrayValue,
            FunctionCall,
            MemberFunctionCall,
            Cast,
            BuiltinOperator,
            Assignment,
            SuffixOperation,
            PrefixOperation,
            Ternary
        > types_initial;

typedef boost::mpl::push_back<types_initial, New>::type types;
typedef boost::make_variant_over<types>::type Value;

}}
Run Code Online (Sandbox Code Playgroud)

Boost Spirit 无法识别使用push_back 添加的最后一个类型(eddic::ast::New)。当我解析具有此元素的内容时,它会失败并出现以下错误:

eddic: /usr/include/boost/variant/detail/visitation_impl.hpp:264: 类型名称 Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; 步骤0 = boost::detail::variant::visitation_impl_step、boost::mpl::v_item、boost::mpl::v_item、boost::mpl::v_item、boost::mpl::v_item、boost::mpl: :v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item , boost::mpl::v_item, boost::mpl::v_item, 0>, …

c++ boost-spirit boost-mpl

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

阻止 X3 符号匹配子字符串

如何防止 X3 符号解析器匹配部分标记?在下面的示例中,我想匹配“foo”,但不匹配“foobar”。我尝试将符号解析器放入指令中,lexeme就像处理标识符一样,但没有任何匹配。

感谢您的任何见解!

#include <string>
#include <iostream>
#include <iomanip>

#include <boost/spirit/home/x3.hpp>


int main() {

  boost::spirit::x3::symbols<int> sym;
  sym.add("foo", 1);

  for (std::string const input : {
      "foo",
      "foobar",
      "barfoo"
        })
    {
      using namespace boost::spirit::x3;

      std::cout << "\nParsing " << std::left << std::setw(20) << ("'" + input + "':");

      int v;
      auto iter = input.begin();
      auto end  = input.end();
      bool ok;
      {
        // what's right rule??

        // this matches nothing
        // auto r = lexeme[sym - alnum];

        // this matchs …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit c++11 boost-spirit-x3

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

X3 解析规则无法编译

我正在通过编写一个解析器来解析 NAMS 使用的两种十六进制数变体来学习 Boost Spirit:

  1. 用的任一后缀十六进制数0x/0h或前缀h/ x
  2. 前缀为$and 的十六进制数字后必须跟一个十进制数字。

这是我到目前为止和Coliru Session 提出的内容

//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/spirit/include/support_extended_variant.hpp>

namespace x3 = boost::spirit::x3;

namespace ast {
    struct hex_data : std::string {};
    struct pascal_hex_data : std::string {};

    struct declared_data : boost::spirit::extended_variant<hex_data, pascal_hex_data>
    {
        declared_data () : base_type ()                              { std::cout << "ctor default\n";               } 
        declared_data (hex_data const& rhs) : base_type (rhs)        { std::cout << "ctor …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

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

boost::spirit 属性赋值:struct is_nullary:基类型不能是结构或类类型

我有一个boost::spirit解析器,它应该简单地分配一个指向其属性的指针:

rule<CompoundExpression *(Scope &)> var_ref = var<CompoundExpression>()(_r1) [
    _val = new_<Reference<Variable<CompoundExpression>>>(_1)
];
Run Code Online (Sandbox Code Playgroud)

wherevar<CompoundExpression>()是一个 just 函数,它返回对执行实际解析的静态规则的引用。我Reference<Variable<T>>在整个代码中对模板的其他实例使用相同的赋值操作,这很好,除了使用CompoundExpression参数的那个。

字面 GCC 错误是这样的:

In file included from /usr/include/boost/phoenix/core/actor.hpp:20,
                 from /usr/include/boost/phoenix/core.hpp:12,
                 from /usr/include/boost/spirit/include/phoenix_core.hpp:11,
                 from /usr/include/boost/spirit/home/support/argument.hpp:18,
                 from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:29,
                 from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
                 from /usr/include/boost/spirit/include/qi_nonterminal.hpp:16,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/utilities.h:7,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.h:4,
                 from /home/ich/sync/ConTrAkt/gologpp/src/parser/compound_expression.cpp:1:
/usr/include/boost/phoenix/core/is_nullary.hpp: In instantiation of ‘struct boost::phoenix::result_of::is_nullary<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::attribute<0> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::new_, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::target<gologpp::Reference<gologpp::Variable<gologpp::TypedExpression<gologpp::CompoundType> > > > >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2>, void>’:
/usr/include/boost/phoenix/core/actor.hpp:178:13:   required from ‘struct boost::phoenix::result_of::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-phoenix

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

Spirit X3,这种错误处理方法有用吗?

在阅读了 Spirit X3 关于错误处理的教程和一些实验之后。我得出了一个结论。

\n\n

我相信 X3 中的错误处理主题还有一些改进的空间。从我的角度来看,一个重要的目标是提供有意义的错误消息。首先也是最重要的是添加一个将_pass(ctx)成员设置为 false 的语义操作,\xe2\x80\x99 不会这样做,因为 X3 会尝试匹配其他内容。仅抛出 anx3::expectation_failure会提前退出解析函数,即不尝试匹配其他任何内容。所以剩下的就是解析器指令expect[a]和解析器operator>以及手动抛出x3::expectation_failure从语义操作中手动抛出。我确实相信有关此错误处理的词汇量太有限。请考虑以下 X3 PEG 语法行:

\n\n
const auto a = a1 >> a2 >> a3;\nconst auto b = b1 >> b2 >> b3;\nconst auto c = c1 >> c2 >> c3;\n\nconst auto main_rule__def =\n(\n a |\n b |\n c );\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在对于表达式a我不能使用expect[]or operator>,因为其他替代方案可能是有效的。我可能是错的,但我认为 X3 要求我拼写出可以匹配的备用错误表达式,如果它们匹配,它们可以抛出x3::expectation_failure这很麻烦。

\n\n

问题是,是否有一种好方法可以使用当前的 X3 设施通过 …

c++ boost-spirit boost-spirit-x3

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

How do you get a string out of a Boost Spirit X3 lexeme parser?

What is the simplest way to make a semantic action that extracts a string from a typical identifier parser based on boost::spirit::x3::lexeme?

I thought it might be possible to bypass needing to unpack the attribute and just use iterators into the input stream but apparently x3::_where does not do what I think it does.

The following yields output being empty. I expected it to contain "foobar_hello".

namespace x3 = boost::spirit::x3;

using x3::_where;
using x3::lexeme;
using x3::alpha;

auto ctx_to_string = …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

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

Boost.Spirit 将表达式转换为 AST

使用 Boost.Spirit 将某些表达式转换为 AST 的正确方法是什么?

我试图构建它,但我认为它很混乱并且可以简化很多。

https://godbolt.org/z/VXHXLY

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

namespace ast {
  struct unary_operator;
  struct binary_operator;

  struct expression {
    typedef boost::variant<
      double,
      std::string,
      boost::recursive_wrapper<unary_operator>,
      boost::recursive_wrapper<binary_operator>,
      boost::recursive_wrapper<expression>
    > type;

    expression() {

    }

    template<typename Expr>
    expression(const Expr &expr)
      : expr(expr) {

    }

    expression &operator+=(expression rhs);
    expression &operator-=(expression rhs);

    expression &operator*=(expression rhs);
    expression &operator/=(expression rhs);

    expression &and_(expression rhs);
    expression &or_(expression rhs);

    expression &equals(expression rhs);
    expression &not_equals(expression rhs);

    expression &less_than(expression rhs);
    expression &less_equals(expression rhs);
    expression &greater_than(expression rhs);
    expression &greater_equals(expression rhs);

    expression &factor(expression …
Run Code Online (Sandbox Code Playgroud)

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

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

我无法在Boost Spirit的词法分析器功能中进行语义操作来编译

所以,我正在使用boost 1.47.0并且我一直在尝试组合一个词法分析器.

我的目标是为我的词法分析器的一些标记添加一个包含语义的动作 spirit::lex::_pass = spirit::lex::pass_flags::pass_ignore.但是,我无法编译任何语义操作.我在下面添加了一个(或多或少)最小的例子.我正在编译OS X 10.7.1上的clang.

编译命令

clang++ -DBOOST_SPIRIT_DEBUG -DBOOST_SPIRIT_LEXERTL_DEBUG -DBOOST_SPIRIT_USE_PHOENIX_V3 -c input.cc
Run Code Online (Sandbox Code Playgroud)

编译的代码

#include <boost/phoenix.hpp>
#include <boost/spirit/home/lex.hpp>
#include <boost/spirit/home/lex/lexer/lexertl/lexer.hpp>

namespace phoenix = boost::phoenix;
namespace spirit = boost::spirit;

struct vhdl_lexer : spirit::lex::lexer< spirit::lex::lexertl::lexer<> > {
    vhdl_lexer() {
        num = "[0-9]";
        any = ".";

        this->self
                = num
                | any
                ;
    }

    spirit::lex::token_def<> num, any;
};
Run Code Online (Sandbox Code Playgroud)

不编译的代码

#include <boost/phoenix.hpp>
#include <boost/spirit/home/lex.hpp>
#include <boost/spirit/home/lex/lexer/lexertl/lexer.hpp>

namespace phoenix = boost::phoenix;
namespace spirit = boost::spirit;

struct vhdl_lexer : spirit::lex::lexer< spirit::lex::lexertl::lexer<> > {
    vhdl_lexer() …
Run Code Online (Sandbox Code Playgroud)

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

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

解析成类(不是结构)

下面我展示了一个不编译的编辑灵魂员工示例.我想解决的问题是解析为不是结构的类.我知道,除了公共/私人之外,它是完全相同的.但是我需要在将类/结构存储到向量之前使用构造函数.如何更改BOOST_FUSION_ADAPT_STRUCT?

我怎么能让它运行?

// STD HEADER
#include <iostream>
#include <string>
#include <complex>

// BOOST HEADER
#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/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>

namespace client
{
    namespace qi = boost::spirit::qi;

    namespace ascii = boost::spirit::ascii;

    class employee
    {
    public:
        employee (
            int _age
          , std::string _surname
          , std::string _forename
          , double _salary
        );

    private:
        int age_;
        std::string surname_;
        std::string forename_;
        double salary_;
    };

    employee::employee (
        int _age
      , std::string _surname
      , std::string _forename
      , double _salary …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-fusion

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