首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使调用了qi::on_error,qi::phrase_parse也会返回true

即使调用了qi::on_error,qi::phrase_parse也会返回true
EN

Stack Overflow用户
提问于 2016-01-30 00:43:27
回答 1查看 294关注 0票数 1
代码语言:javascript
复制
 bool EqnExprEvaluator::SetEqn(const std::string& eqnStr) {
     typedef std::string::const_iterator iterator_type;

     EquationExpr<iterator_type> eqnExpr;

     std::string::const_iterator iter = eqnStr.begin();
     std::string::const_iterator iterEnd = eqnStr.end();

     bool result;
     try {
         result = qi::phrase_parse(iter, iterEnd, eqnExpr, boost::spirit::ascii::space, *m_expressionAST);
         std::cout << "777777777777 ok, result = " << result << std::endl;
     }
     catch (const std::exception &e) {

         throw e;
     }
     catch (...) {
         throw std::runtime_error("Parser error");
     }

     return result;
 }


///////////////////////////////////////////////////////////////////////////
//  Equation grammar
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
    struct EquationExpr : qi::grammar<Iterator, ExpressionAST(),  ascii::space_type>
{
    static ExpressionAST make_binary_op(char op, const ExpressionAST &left,
            const ExpressionAST &right)  {

        ExpressionAST ast;
        ast.expr = binary_op(op,left,right);
        return ast;
    };
    //
    // Typedefs to make the code less verbose
    //
    typedef qi::rule<Iterator, std::string(), ascii::space_type> RuleString;
    typedef qi::rule<Iterator, ExpressionAST(), ascii::space_type> RuleAst;
    typedef qi::rule<Iterator, ExpressionAST(),
            qi::locals<ExpressionAST>,
            ascii::space_type>  RuleAstLocalVar;

    EquationExpr() : EquationExpr::base_type(expression_root,"equation") {
        boost::phoenix::function<negate_expr> neg;
        boost::phoenix::function<sqrt_expr> sqrtfunc;


        using qi::_val;
        using qi::_1;
        using qi::_2;
        using qi::_3;
        using qi::_4;
        using qi::double_;
        using qi::lit;
        using qi::_a;
        using qi::_pass;
        using qi::char_;
        using qi::string;
        using qi::alpha;
        using qi::alnum;
        using boost::phoenix::val;

        std::string varName;
        pow = lit("pow") > '(' >>  expression [_a = _1 ]
            > lit(",")
            > expression [_val = boost::phoenix::bind(make_binary_op,'^', _a,_1)]
            > ')'
            ;

        sqrt= lit("sqrt") > '(' >
            expression [_val = sqrtfunc(_1)]
            >> ')'
            ;

        expression_root = qi::eps >> expression;
        expression =
            term                            [_val = _1]
            >> *(   ('+' >> term            [_val += _1])
                    |   ('-' >> term            [_val -= _1])
                )
            ;

        term =
            factor              [_val = _1]
            >> *(   ('*' >> factor          [_val *= _1])
                    |   ('/' >> factor          [_val /= _1])
                )
            ;

        allowed_variable = '@' >
            (
             string("length") [_val = _1]
             | string("width") [_val = _1]
             | string("temperature") [_val = _1]
             | string("deltaT") [_val = _1]
            )
            ;
        illegal_variable = ! lit('@') >  alpha  > *alnum  [_val = _1 ] > !qi::eps [_pass]
            ;
        badPow = lit("pow") >> '(' >>  expression >> !lit(",") [_pass]
            ;
        factor =
            double_                         [_val = _1]
            | allowed_variable              [_val = _1]
            | pow                           [_val = _1]
            | sqrt                          [_val = _1]
            |   '(' >> expression           [_val = _1] >> ')'
            |   ('-' >> factor              [_val = neg(_1)])
            |   ('+' >> factor              [_val = _1])
            | badPow
            | illegal_variable              [_val = _1]
            ;

        //
        //  Naming the rules
        //
        pow.name("pow");
        sqrt.name("sqrt");
        expression_root.name("expression");
        term.name("term");
        allowed_variable.name("allowed_variable");
        factor.name("factor");

        //
        // Error handler
        //

        qi::on_error<qi::fail>
            (
             expression_root,
             std::cout << val("Error equation equation ")
             << boost::phoenix::construct<std::string>(_1,_2)
             << val ("\n")
            );
        qi::on_error<qi::fail>
            (
             badPow,
             std::cout << val("Error parsing function 'pow'.  Didn't find second argument ")
             << boost::phoenix::construct<std::string>(_1,_2)
             << val ("\n")
            );
        qi::on_error<qi::fail>
            (
             pow,
             std::cout << val("Error parsing function 'pow'  ")
             << boost::phoenix::construct<std::string>(_1,_2)
             << val ("\n")
            );

        qi::on_error<qi::fail>
            (
             allowed_variable,
             std::cout << val("Error parsing allowed variables  ")
             << val ("'\n")
             << val (" Allowed at @length, @width , @temperature, and @deltaT")
             << val ("'\n")
            );

        qi::on_error<qi::fail>
            (
             illegal_variable,
             std::cout << val("Error parsing variable   ")
             << val (" here: Got an illegal variable '")
             << "Arg " << boost::phoenix::construct<std::string>(_1,_2) << "'" << std::endl
             << "Arg4 " << _4 << std::endl 
             << boost::phoenix::construct<std::string>(_3,_2)
             << val ("'\n")
             << val (" Allowed at @length, @width , @temperature and @deltaT")
             << val ("'\n")
            );

    }

    RuleAst expression, term, factor,sqrt, expression_root;
    RuleString allowed_variable,illegal_variable;
    RuleAstLocalVar pow, badPow;
};

对于此语法,错误消息打印为qi::on_error<qi::fail> (illegal_variable,...,但phrase_parse返回true。有人能解释一下这是怎么回事吗?

错误打印是正常的,但在这种情况下,phrase_parse不应该返回false吗?

EN

回答 1

Stack Overflow用户

发布于 2016-01-30 01:25:25

on_error处理程序定义了您想要做的事情。

您希望在操作中设置qi::_pass = false

有关示例,请参阅例如how to make error handling work for boost::spirit

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35089696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档