2

当语义操作代码发现问题时,我希望停止令牌解析器。

如果 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 )
            ]
        ;

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

    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 )
            ]
        ;

这行得通!

我对优雅并不感到兴奋。语法语法现在很难阅读,并且混合使用 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 )
            ]
        ;
4

1 回答 1

8

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

从我的一些代码:

variable_reference_impl_[_pass = lookup_symbol_(_1, false)][_val = _1]

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

于 2011-03-30T14:55:29.980 回答