标签: boost-spirit

Boost Spirit X3:“属性没有达到预期的大小”还原

精神上似乎发生了一些变化::x3 破坏了我奇特的小 asdl 解析器。当我从 Qi 移植它时(在最初的 x3 错误修复进入 Fedora 后),它工作得很好,但现在失败了:

/usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:143:9:错误:静态断言失败:属性没有预期的大小。

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

#include "asdl.h"

typedef boost::variant<asdl::ast::Product, asdl::ast::Sum> type_variant;
typedef std::vector<asdl::ast::Field> field_vec;

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Module,
    (std::string, id)
    (std::vector<asdl::ast::Type>, dfns))

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Type,
    (std::string, name)
    (type_variant, value))

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Field,
    (std::string, type)
    (boost::optional<char>, flag)
    (boost::optional<std::string>, name))

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Constructor,
    (std::string, name)
    (boost::optional<field_vec>, fields))

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Sum,
    (std::vector<asdl::ast::Constructor>, types)
    (boost::optional<field_vec>, attributes))

BOOST_FUSION_ADAPT_STRUCT(
    asdl::ast::Product,
    (field_vec, fields))

namespace asdl
{

namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;

x3::rule<class module,      ast::Module     > const module      = "module";
x3::rule<class …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit

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

虚拟类作为带有 Spirit 的 AST 节点

我正在和一个朋友一起研究一种语言的解释器,我们从一个我猜不是那么明智的决定开始:我们首先制作了所有要执行的元素(实际上是一个由不同类组成的树);但是现在查看 boost 示例,我对如何合并两者感到很困惑。我知道从什么开始(语法),我知道要达到什么(实例化的类彼此拥有),我不知道如何达到它。

我们从没有变量的表达式开始,因此我们查看了精神计算器示例;但我不明白什么时候实例化元素。

表达项示例:

namespace exp
{
class op
    {
    private:
    public:
        virtual double exec(function_scope &fs);

    };

class operand : public op
    {
    private:
        double value;

    public:
        operand(double value);
        double exec(function_scope &fs);
    };

class op_bin : public op
    {
    private:
    public:
        op * ll;
        op* rr;
        op_bin(op* ll, op* rr);
        ~op_bin();
    };

namespace bin
    {
    class sum : public op_bin
        {
        public:
            sum(op* ll, op* rr);
            double exec(function_scope &fs);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

忽略 exec 函数,它在运行时使用。

例如,代码 5 + (2 …

c++ abstract-syntax-tree boost-spirit

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

理解精神语法

在阅读文档时,我读到了这一点

对于用逗号分隔的双字符串,我们可以这样(我明白)

double_ >> * (',' >> double_) 要么 double_ %

但是下面的表达是什么意思呢.它应该将逗号分隔的字符串拆分为一个向量,它可以工作.如果有人能够澄清它,我将不胜感激.我对-运算符感到困惑我相信它是一个差异运算符,但我无法弄清楚它在这里的作用

*(qi::char_ - ',') % ','

c++ boost boost-spirit

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

Spirit V2和X3的状态

Spirit X3如此“无状态”的目的是什么?

Spirit V2中“状态”的不良方面

回顾Spirit V2,“语法”在许多方面在概念上都是有状态的。这是因为语法是类实例。

基本上,使语法(甚至任何一条规则)变得有状态有很多不良方面:

  • 它可能会使您的语法不可重入;
  • 它可能会给您的语法实例增加线程安全性;
  • 自我管理的“标志”是一场灾难。

从理论上讲,添加外部状态会使您的语法变得不平凡。

真的不需要状态吗?

相反,您可以说任何解析器都是有状态的(因为它解析当前上下文并且上下文是状态)。下面是程序员添加其他“上下文”的一个好例子:

quoted_string_ = as_string [omit [char_("'\"") [_a = _1]] >> *(char_ - lit(_a)) >> lit(_a)]
Run Code Online (Sandbox Code Playgroud)

qi::locals是非外部国家的好兆头。

程序员可以在语法中添加一些“外部状态”,并且在大多数情况下,它们只是在做错误的事情:

func_call_ = func_name_ >> lit('(') >> eps [ref(is_inside_function_call) = true] >> ...
Run Code Online (Sandbox Code Playgroud)

但是,在某些极端情况下,外部状态很有用。

macro_type_1_ =
    lit("{{{") [PUSH_STATE(macro_ctx, Macro::Type1)] >> (
        ((any_expr_ - end_of_macro_ctx_) >> lit("}}}") >> eps [POP_STATE(macro_ctx)]) |
        (eps [POP_STATE(macro_ctx)] >> eps [_pass = false])
    )
;
macro_type_2_ =
    lit("[[[") [PUSH_STATE(macro_ctx, Macro::Type2)] >> (
        ((any_expr_ - end_of_macro_ctx_) >> …
Run Code Online (Sandbox Code Playgroud)

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

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