我的解析器中有以下规则用于解析不等式,这很好用:
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是否会自动从词汇表达式构建词法分析器?
这是完整的解析器:
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;
};
答案 0 :(得分:2)
根据boost::spirit
文档,alternative解析器尝试其操作数
从最左边的操作数
开始,在第一场比赛中逐一获胜
所以你可以简单地把你的&#39;&lt; =&#39;和&#39;&gt; =&#39; &#39;&lt;&#39;之前的解析器和&#39;&gt;&#39;。
另外,您可以制作&#39;&lt;&#39;和&#39;&gt;&#39;不匹配&#39;&lt; =&#39;和&#39;&gt; =&#39;使用前瞻性的not-predicate解析器。所以它看起来像:
('<' >> !char_('=') >> sum [_val = _val < _1])