2015-10-16 73 views
0

我有我的解析器解析不平等,工作正常以下规则:解析C风格的关系运算符与精神齐

rel = sum [ _val = _1 ] 
    >> *(('<' >> sum [_val = _val < _1]) 
     | ('>' >> sum [_val = _val > _1])); 

现在,我想补充的<=>=运营商。所以我尝试以下方法:

rel = sum [ _val = _1 ] 
    >> *(('<' >> sum [_val = _val < _1]) 
     | ('>' >> sum [_val = _val > _1]) 
     | (lexeme["<="] >> sum [ _val = _val <= _1]) 
     | (lexeme[">="] >> sum [ _val = _val >= _1])); 

然而,这无法解析表达式像x >= y,大概是因为解析器不能向前看一个字符找到>=

我该如何修改此解析器以支持<=>=运算符?

Spirit Qi是否会自动从lexeme表达式中构建一个词法分析器?

下面是完整的解析器:

template <typename Iterator> 
struct grammar : qi::grammar<Iterator, expression_ast(), ascii::space_type> 
{ 

    grammar() : grammar::base_type(expr) { 

    using qi::lexeme; 
    using qi::double_; 
    using qi::lit; 
    using qi::_val; 
    using qi::_1; 
    using qi::_2; 
    using qi::_3; 

    var = lexeme[qi::alpha >> *qi::alnum]; 

    expr = eq [_val = _1] >> *(('?' >> expr >> ':' >> expr) [_val = cond(_val, _1, _2)]); 

    eq = rel [ _val = _1] 
     >> *(lexeme["=="] >> rel [_val = equal(_val, _1)]); 

    rel = sum [ _val = _1 ] 
     >> *(('<' >> sum [_val = _val < _1]) 
      | ('>' >> sum [_val = _val > _1]) 
      | (lexeme["<="] >> sum [ _val = _val <= _1]) 
      | (lexeme[">="] >> sum [ _val = _val >= _1])); 

    sum = term [_val = _1] 
     >> *(('+' >> term [_val += _1]) 
      | ('-' >> term [_val -= _1])); 

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

    exp = factor [_val = _1] 
      >> *('^' >> factor [ _val = power(_val, _1)]); 

    factor = '-' >> atom [_val = neg(_1)] 
      | atom [_val = _1]; 

    atom = double_ [_val = _1] 
     | var [_val = _1] >> -('(' >> exprlist [_val = call(_val, _1)] >> ')') 
     | '(' >> expr [_val = _1] >> ')'; 

    exprlist = expr % ','; 

    } 

    qi::rule<Iterator, std::string(void), ascii::space_type> var; 
    qi::rule<Iterator, expression_ast(), ascii::space_type> expr, eq, rel, factor, sum, term, exp, atom; 
    qi::rule<Iterator, std::vector<expression_ast>(), ascii::space_type> exprlist; 

}; 
+1

我绝对不是一个专家的boost ::精神,但你尝试过简单地把你的'<=' and '> =''_before_'<' and '>所以它试图匹配那些第一? – Rostislav

+1

否则,您可以使用[not-predicate parser](http://www.boost.org/doc/libs/1_51_0/libs/spirit/doc/html/spirit/qi/reference/operator/not_predicate.html)因为你的'<' and '>'规则,这是前瞻性的,并在那里出于特定的原因。 – Rostislav

+0

你知道,我其实认为我会把这个作为答案,因为我很确定它会解决你的麻烦。 – Rostislav

回答

2

boost::spirit文档中,alternative解析器尝试操作数

一个接一个的第一,比赛获胜的基础,从最左边的操作数

开始

所以你可以简单地把'< ='和'> ='分析器放在' <'和'>'。

或者,通过使用向前看的not-predicate解析器,您可以使'<'和'>'与'< ='和'> ='不匹配。因此,它看起来像:

('<' >> !char_('=') >> sum [_val = _val < _1])