在 LPeg 中匹配具有特定结尾的字符串

Matching a string with a specific end in LPeg

我正在尝试捕获包含 a 和 b 的组合但始终以 b 结尾的字符串。换句话说:

local patt = S'ab'^0 * P'b'

匹配 aaabbbabb 但不匹配 aaabba。然而,以上内容与任何内容都不匹配。这是因为 S'ab'^0 贪婪匹配了最后的 b 吗?我是这么认为的,除了可能诉诸 lpeg.Cmt 之外想不出任何替代方案,这似乎有点矫枉过正。但也许不是,有人知道如何匹配这样的模式吗?我看到 this question 但解决方案的问题在于它会在第一个结束标记处停止(即 'cat' 那里, 'b' 在这里)并且在我的情况下我需要接受中间'b's.

P.S。 我实际上想做的是匹配最外层规则是函数调用的表达式。 例如

func();
func(x)(y);
func_arr[z]();

全部匹配但

exp;
func()[1];
4 + 5;

没有。我的其余语法有效,我很确定这归结为同一个问题,但为了完整起见,我正在使用的语法看起来像:

top_expr = V'primary_expr' * V'postfix_op'^0 * V'func_call_op' * P';';
postfix_op = V'func_call_op' + V'index_op';

同样,V'postfix_op'^0 吃掉了我最后期待的 func_call_op

是的,没有回溯,所以你已经正确地发现了问题。我认为解决方案是列出有效的 postfix_op 表达式;我会将 V'func_call_op' + V'index_op' 更改为 V'func_call_op'^0 * V'index_op' 并将最后的 V'func_call_op' 更改为 V'func_call_op'^1 以允许最后调用多个函数。

更新:如评论中所建议,a/b 问题的解决方案是 (P'b'^0 * P'a')^0 * P'b'^1

这个怎么样?

local final = P'b' * P(-1)
local patt =  (S'ab' - final)^0 * final

模式final是我们在字符串末尾所需要的。

模式 patt 与集合 'ab' 匹配,除非 它后面跟着最终序列。然后它断言我们有最终序列。这阻止了最后的 'b' 被吃掉。

这并不能保证我们得到任何 a(但问题中的模式也不会)。

抱歉,我的回答来得太晚了,但我认为值得给这个问题一个更正确的答案。

据我了解,您只需要 非盲 贪婪匹配。但不幸的是,LPeg 的“官方文档”只告诉我们如何使用 LPeg 进行 blind 贪婪匹配(或重复)。但是这种模式可以用解析表达式文法来描述。对于规则 S,如果你想匹配尽可能多的 E1,然后是 E2,你需要写

S <- E1 S / E2

a/b问题的解决方案变为

S <- [ab] S / 'b'

您可能希望通过在第一个选项中插入一些 a 来优化规则

S <- [ab] 'a'* S / 'b'

这将大大减少递归。至于你真正的问题,这是我的答案:

top_expr   <- primary_expr p_and_f ';'
p_and_f    <- postfix_op p_and_f / func_call_op
postfix_op <- func_call_op / index_op