在语义操作中发现错误时停止解析器

rav*_*int 2 c++ boost boost-spirit

我希望在语义动作代码发现问题时停止令牌解析器.

如果x> 10

在语法上是正确的,但如果x不存在,解析器应该停止

语法规则和语义动作看起来像这样

    condition
        =   ( tok.identifier >> tok.oper_ >> tok.value )
            [
                boost::phoenix::bind( &cRuleKit::AddCondition, &myRulekit, 
                        boost::spirit::_1, boost::spirit::_2, boost::spirit::_3 )
            ]
        ;
Run Code Online (Sandbox Code Playgroud)

所以现在我添加一个检查标识符的存在

    condition
        =   ( tok.identifier[boost::bind(&cRuleKit::CheckIdentifier, &myRulekit, ::_1, ::_3 ) ] 
               >> tok.oper_ >> tok.value )
            [
                boost::phoenix::bind( &cRuleKit::AddCondition, &myRulekit,
                      boost::spirit::_1, boost::spirit::_2, boost::spirit::_3 )
            ]
        ;
Run Code Online (Sandbox Code Playgroud)

这有效!

我并不为优雅而激动.语法语法现在很难阅读,混合使用boost :: bind和boost :: phoenix :: bind非常令人困惑.

我怎样才能改进它?我想从phoenix :: bind获取'hit'参数,以便我可以在cRuleKit :: AddCondition()中进行检查,因此保持语法和动作分离并避免使用boost :: bind.


答案是使用占位符_pass

    condition
        =   ( tok.identifier >> tok.oper_ >> tok.value )
            [
                boost::phoenix::bind( &cRuleKit::AddCondition, &myRulekit, 
                        boost::spirit::_pass, boost::spirit::_1, boost::spirit::_2, boost::spirit::_3 )
            ]
        ;
Run Code Online (Sandbox Code Playgroud)

rlc*_*rlc 8

Spirit具有一个特殊的值,您可以在语义操作中使用它来使解析失败.它被调用_pass,您应该将其设置为false.

从我的一些代码:

variable_reference_impl_[_pass = lookup_symbol_(_1, false)][_val = _1]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,lookup_symbol是一个Phoenix函子,true如果找到符号则返回,false如果没有,则返回.