我正在尝试使用boost::spirit::qi
来解析表达式。
这个表达式很简单,它可以是:
- 标识符,比如
x
- 对象的成员,比如
obj.x
- 数组的元素,比如
arr[2]
- 函数调用的结果,
func(x, y)
对象的成员可能是数组或函数类型,因此x.y[2]
、x.y()
都是合法的。
函数结果可能是数组或对象,因此func(x,y).value
、func(x)[4]
也是合法的。
数组元素可能是对象或函数类型,因此arr[5].y
、arr[3](x, y)
也是合法的。
将这些组合在一起,以下表达式应该是合法的:
x[1]().y(x, y, x.z, z[4].y)().q[2][3].fun()[5].x.y.z
所有这些[...]
、(...)
和.
具有相同的优先级,从左到右进行运算。
我的语法如下:
expression
= postfix_expr
| member_expr
;
postfix_expr = elem_expr | call_expr | id;
elem_expr = postfix_expr >> "[" >> qi::int_ >> "]";
call_expr = postfix_expr >> "(" >> expression_list >> ")";
member_expr = id >> *("." >> member_expr);
expression_list
= -(expression % ",")
但是它总是崩溃,我认为可能有无限循环的地方。
请给我一些关于如何解析这个语法的建议。
编辑 后续问题: 谢谢cadrian,它起作用了!
现在表达式可以正确解析,但我想引入一个新的 ref_exp ,它也是一个表达式,但不以 () 结尾,因为函数结果不能放置在赋值的左边。
我的定义是:
ref_exp
= id
| (id >> *postfix_exp >> (memb_exp | elem_exp))
;
postfix_exp
= memb_exp
| elem_exp
| call_exp
;
memb_exp = "." >> id;
elem_exp = "[" >> qi::uint_ >> "]";
call_exp = ("(" >> expression_list >> ")");
但是
boost::spirit::qi
无法解析这个表达式,我认为原因是 (memb_exp | elem_exp)
是 postfix_exp
的一部分,如何使其不解析所有内容,只匹配最后一个部分的 (memb_exp | elem_exp)
。
ref_exp
的例子: x
、x.y
、x()[12][21]
、f(x, y, z).x[2]
,而非 ref_exp
: f()
、x.y()
、x[12]()
。