I am trying to use boost::spirit::qi
to parse an expression.
The expression is simple, it can be
- id, like
x
- member of an object, like
obj.x
- an element of an array, like
arr[2]
- a result of function call.
func(x, y)
A member of object can be array or function type so
x.y[2]
, x.y()
are legal.
A function result might be an array or object
so func(x,y).value
, func(x)[4]
are legal too.
An array element might be object or function type
so arr[5].y
, arr[3](x, y)
are legal.
Combined together, the following expression should be legal:
x[1]().y(x, y, x.z, z[4].y)().q[2][3].fun()[5].x.y.z
All these [...]
(...)
and .
has same precedence and from left to right.
My grammar like this
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 % ",")
but it always crashes, I think maybe somewhere has infinity loop.
Please give me some suggestion on how to parse this grammar.
EDIT FOLLOW UP QUESTION: thanks cadrian, it works!
now expression can parse correctly, but I want to introduce a new ref_exp
which is an expression too, but not end with ()
because function result cannot be placed to left of assignment.
my definition is :
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 >> ")");
but boost::spirit::qi
cannot parse this,
I think the reason is (memb_exp | elem_exp)
is part of postfix_exp
, how to make it not parse all, and leave the very last part to match (memb_exp | elem_exp)
ref_exp
examples: x
, x.y
, x()[12][21]
, f(x, y, z).x[2]
not ref_exp
: f()
, x.y()
, x[12]()