2016-01-29 36 views
1
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返回true,即使齊:: ON_ERROR被稱爲

錯誤打印OK,但不應該phrase_parse對於這種情況下的回報false

+0

這是可悲的,你不包括實際SSCCE。所有的代碼都非常接近,但我不能輕易地使它工作(即在晚餐前4分鐘)。所以我會把它留給你 – sehe

回答

相關問題