如何在lex中使用向后查找断言?

3

我需要在lex (flex 2.5.35)中使用正向回顾断言。经过调查文档,我没有找到直接实现这一点的方法。它有类似于前瞻断言的东西(r/s语法),但没有后顾断言。如何以最佳方式实现相同的效果?

这里是一个例子:假设我在扫描器规范文件中有以下规则:

a         printf("matched a ");
b         printf("matched b ");
c         printf("matched c ");
d         printf("matched d ");

如何匹配跟在'b'后面的'd'和'b'本身,使得输入'abd'时我可以得到:

matched a matched b matched d following b

但是对于字符串 'acd'

matched a matched c matched d

规则如下:
bd        printf("matched d following b ");

显然这种方法行不通,因为它会消耗b;对于'abd',它输出:
matched a matched d following b

如果我有pcre lookbehinds,我可以这样写:
(?<=b)d   printf("matched d following b ");

如果所有都很好,但是Lex不支持这种操作。

3个回答

2

您可以通过起始条件来实现您想要的目标,但代价是需要使用更复杂的扫描器。 起始条件允许您根据先前匹配的内容有条件地启用规则。以下是一个示例:

%x matched_b
%%
<INITIAL,matched_b>{
    a       { printf("matched a\n"); BEGIN(INITIAL); }
    b       { printf("matched b\n"); BEGIN(matched_b); }
    c       { printf("matched c\n"); BEGIN(INITIAL); }
}

d       printf("matched d\n");
<matched_b>d    { printf("matched d following b\n"); BEGIN(INITIAL); }

通过这个扫描仪,我可以获得以下信息:

$ echo abcd | ./5615080
matched a
matched b
matched c
matched d

$ echo abdd | ./5615080
matched a
matched b
matched d following b
matched d

嗯,这看起来相当复杂,但我想没有其他办法了。谢谢你的帮助。 - justinrstout

1

如果你只有一个前瞻断言,我能想到两种可能性。

  1. 反转你的字符串,并搜索同样被反转的模式。原本在模式之前的现在在它之后。

  2. 我认为对于某些正则表达式语法,可以从右到左解析,也许这可以与你的前瞻一起帮助你。

否则,你应该发布一些示例字符串以及你期望的结果,也许可以在不使用后顾断言的情况下实现。


-1

对于pcre来说,向后查找的语法如下:

(?<= ... ) 表示正向查找
(?<! ... ) 表示否定查找

而且pcre要求固定长度的向后查找(无论是正向还是否定)。

如果lex有这种功能,那么它可能是这种形式。


1
Flex目前不支持这些功能。来源:http://web.archive.org/web/20160525061545/http://flex.sourceforge.net:80/manual/Patterns.html - starbeamrainbowlabs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接