我试图延长计算器示例 ,这样的分析,而不是和评估的代数表达式,解析器将确定一个代数语句是真还是假。 我的意思是像语句1 + 5 * 5 - 10 = 19 - 3
(期望解析器结果为true
)和3 - 1 = 9
(期望解析器结果为false
)。
我得承认,我是新来boost::spirit
和它的所有种类的时刻压倒。 不过,我觉得我理解的计算器例子不够好,至少取得一些进展。
使用所提供的例子为出发点,语法如下:
calculator() : calculator::base_type(expression)
{
using qi::uint_;
using qi::_val;
using qi::_1;
expression =
term [_val = _1]
>> *( ('+' >> term [_val = _val + _1])
| ('-' >> term [_val = _val - _1])
);
term =
factor [_val = _1]
>> *( ('*' >> factor [_val = _val * _1])
| ('/' >> factor [_val = _val / _1])
);
factor =
uint_ [_val = _1]
| '(' >> expression [_val = _1] >> ')'
| ('-' >> factor [_val = -_1])
| ('+' >> factor [_val = _1]);
}
在那里我已经放弃了调试宏简洁。
为了限制问题的范围,我决定只允许每声明一个等号。 由于它是没有意义的(至少在常规意义上)具有平等的迹象出现一个封闭的圆括号内,我已经决定不让括号无论是。 这简化了factor
通过允许移除可选的-parser '(' >> expression [_val = _1] >> ')'
。
在这一点上我有点卡住了。 首先,我需要解析器接受一个等号。 其次,我需要的语义动作,以评估左手侧(LHS)和语句的右手边(RHS)单独,最后进行比较之前(或者所以这是我觉得做的需要)。
我想知道如果最简单的方法是建立两个独立的解析器,一个LHS和RHS一个由第三解析器匹配等号分开。 两个解析器LHS和RHS应该是相同的,除了语义动作其中,显然,需要给输入分离成两个不同的类别,以便这些最终进行比较。
尝试写两个单独的解析器LHS和RHS之前,我想学习如何修改原来的解析器,以便它保存在一个局部变量的计算的表达式。 (我甚至不知道这将是任何地方可行的道路,但它似乎是朝着正确方向迈出的一步。)
这是我的尝试:
int result;
expression =
term [result = _1]
>> *( ('+' >> term [result = result + _1])
| ('-' >> term [result = result - _1])
);
但是这使得我的编译器(苹果LLVM编译器4.2时,Xcode 4.6)想怎么样,大呼小叫的我,
分配给从不兼容的类型 'INT' '常量_1_type'(又名 'const的演员<参数<0>>')
事后看来,这使得课程的意义,因为_val
从来没有必然int
摆在首位(毕竟解析器AFAIU应该是通用的)。 换句话说,我需要找出如何定义要用于临时存储所评估解析的表达式的类型。
现在的问题是:任何人都可以给我在正确的方向轻推? 是否在LHS和RHS分裂似乎要走的路?
任何建议,非常感谢!