gpt4 book ai didi

c++ - 求一个parser grammar,用boost spirit qi比较好

转载 作者:太空狗 更新时间:2023-10-29 20:37:28 25 4
gpt4 key购买 nike

我正在尝试使用 boost::spirit::qi 来解析表达式。

表达式简单,可以

  1. id,如x
  2. 对象的成员,例如 obj.x
  3. 数组的一个元素,如 arr[2]
  4. 函数调用的结果。 函数(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 % ",")

但它总是崩溃,我想也许某个地方有无限循环。

请给我一些关于如何解析这个语法的建议。

编辑跟进问题:谢谢卡德里安,它有效!

现在表达式可以正确解析了,但是我想引入一个新的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 示例:xx.yx()[12][21] >f(x, y, z).x[2]不是 ref_exp : f(), x.y(), x[12]()

最佳答案

boost::spirit::qi is a descending parser ;你的语法一定不能是递归的。

参见 this question .

这里你肯定有一个左递归语法:postfix_expr -> elem_expr -> postfix_expr

编辑解决此问题的一种方法。

在我看来,您的表达式是一串带有可能后缀的 ID:[]().

expression = id >> *cont_expr;
cont_expr = elem_expr | call_expr | member_expr
elem_expr = "[" >> qi::int_ >> "]";
call_expr = "(" >> expression_list >> ")";
member_expr = "." >> expression;
expression_list = -(expression % ",")

EDIT 2 如果您希望能够强制优先级——例如使用括号:

expression = prefix_expr >> *cont_expr;
prefix_expr = id | par_expr
par_expr = "(" >> expression >> ")"

这样你甚至可以编写像 x.(y[3].foo)[5](fun(), foo(bar)) 这样的表达式——如果这有意义的话。

EDIT 3 我在这里回答你的评论。

您需要赋值的左侧不是函数。这意味着您有一个特定的左 watch 达式后缀。让我们在您的评论中称该规则为 ref_exp

ref_exp = id >> -( *cont_expr >> cont_ref );
cont_ref = elem_expr | member_expr;

关于c++ - 求一个parser grammar,用boost spirit qi比较好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34648465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com