精神上似乎发生了一些变化::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) 我正在和一个朋友一起研究一种语言的解释器,我们从一个我猜不是那么明智的决定开始:我们首先制作了所有要执行的元素(实际上是一个由不同类组成的树);但是现在查看 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 …
在阅读文档时,我读到了这一点
对于用逗号分隔的双字符串,我们可以这样(我明白)
double_ >> * (',' >> double_)
要么 double_ %
但是下面的表达是什么意思呢.它应该将逗号分隔的字符串拆分为一个向量,它可以工作.如果有人能够澄清它,我将不胜感激.我对-
运算符感到困惑我相信它是一个差异运算符,但我无法弄清楚它在这里的作用
*(qi::char_ - ',') % ','
Spirit X3如此“无状态”的目的是什么?
回顾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)