Boost :: Spirit占位符和替代解析器

时间:2014-12-15 19:15:58

标签: c++ boost boost-spirit boost-spirit-qi boost-phoenix

// 1    
Mexpression = Mterm >> *(
    '+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '+', _2)]
  | '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '-', _2)]
  );

Mterm = Mfactor >> *(   
    '*' >> Mfactor [qi::_val = phoenix::new_<BinaryNode>(_1, '*', _2)]
  | '/' >> Mfactor [qi::_val = phoenix::new_<BinaryNode>(_1, '/', _2)]
  );

Mfactor = Unpack 
    | '+' >> Mfactor [qi::_val = phoenix::new_<UnaryNode>('+', _1)] 
    | '-' >> Mfactor [qi::_val = phoenix::new_<UnaryNode>('-', _1)]
    | '(' >> Mexpression >> ')';`

`Error  2   error C2664: 'BinaryNode::BinaryNode(const BinaryNode &)' : cannot convert argument 3 from 'boost::mpl::void_' to 'anExpression *'  c:\boost_1_55_0\boost\spirit\home\phoenix\object\detail\new_eval.hpp    41  1   ConsoleApplication1
Error   1   error C2338: index_is_out_of_bounds c:\boost_1_55_0\boost\spirit\home\support\argument.hpp  103 1   ConsoleApplication1 `

c:\boost_1_55_0\boost\spirit\home\support\argument.hpp(166) : see reference to class template instantiation 'boost::spirit::result_of::get_arg<boost::fusion::vector1<Attribute &>,1>' being compiled with
[
Attribute=anExpression *
]

我正在为一个模型语言编写一个翻译器(有几个主要作品的ebnf作为一项任务。)并且在算术操作中处于某个地方。

(粘贴中见1)

这是一个解析数学'exprs的模型,

unpack是somenode,可以执行的东西,转换为anExpression *,并以arg形式给出BinaryNode

有以下规则。

    qi::rule<Iterator, anExpression *()> Unpack;
    qi::rule<Iterator, anExpression *()> Mexpression, Mterm, Mfactor; 

anExpression是一个抽象类(Binary和Unary是public anExpression)

在编译整个程序时,我遇到以下错误:

fig2

我认为错误2是最先解决的问题。

在构建日志中有类似的东西 图三


好吧,我认为错误在于我的语义行为方式。我认为_2占位符中没有Mterm(或Mfactor)。这种使用语义动作和替代解析器('|')

的方式我做错了

我很高兴听到你们的任何想法=)

1 个答案:

答案 0 :(得分:0)

Mexpression = Mterm >> *(
    '+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '+', _2)]
  | '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(_1, '-', _2)]
  );

确实无法工作。您需要临时存储lhs Mterm的结果属性。幸运的是,您应该能够使用规则本身的结果来执行此操作:

Mexpression = Mterm [qi::_val = qi::_1] >> *(
    '+' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(qi::_val, '+', qi::_1)]
  | '-' >> Mterm [qi::_val = phoenix::new_<BinaryNode>(qi::_val, '-', qi::_1)]
  );

但是,您可能必须在BinaryNode类型的构造函数中容纳此内容。

这说:

  • 我倾向于避免语义行为。只要您在语义操作中强制拼写每一步,使用像Spirit这样的解析器生成器的真正好处是什么?它不再适用于快速应用程序开发
  • 特别是进行动态分配的语义动作;在解析器回溯的情况下创建泄漏非常容易

那就是说,这种表达组合​​是关于我认为语义行为仍然可以被认为是精神中的惯用的唯一点。动态分配肯定不是。