繁体   English   中英

jflex的最高效前瞻替代品

[英]The most efficient lookahead substitute for jflex

我在jflex中编写令牌生成器。 我需要匹配等词语interferon-a为一个令牌,并且词语等interferon-alpha三个。

显而易见的解决方案是先行,但它们不适用于jflex。 对于类似的任务,我编写了一个函数,该函数在匹配的模式之后匹配一个额外的通配符,检查它是否为Java代码中的空白,并在匹配字符串的一部分与否之间将其推回。

REGEX = [:letter:]+\\-[:letter:]\\.

从字符串interferon-alpha它将匹配interferon-al 然后,在Java代码部分中,它将检查匹配的最后一个字符是否为空格。 -al并非如此,所以-al将被推回, interferon返回。

interferon-a -a的情况下,空白将被推回而interferon返回。

但是,如果匹配的字符串没有任何后续内容,则此功能不起作用。 另外,它似乎很笨拙。 因此,我想知道是否有任何“更聪明”的方法可以确保后面的字符是一个空格,而无需实际匹配并返回它。

JFlex当然具有与(f)lex相同的超前功能。 与Java regex前瞻断言不同,JFlex前瞻只能在比赛结束时应用,但在其他方面相似。 JFlex手册的“ 语义”部分对此进行了描述:

在词法规则中,正则表达式r后面可以是前瞻表达式。 预读表达式可以是$ (行运算符的结尾)或/后跟任意正则表达式。 在这两种情况下,预读都不会被使用,也不包含在匹配的文本区域中,但是在确定哪个规则具有最长的匹配时考虑...

因此,您当然可以编写以下规则:

[:letter:]+\-[:letter:]/\s

但是,您不能将这样的规则放在宏定义中( REGEX = … ),因为该手册也提到了(在有关宏部分中 ):

右侧的正则表达式必须格式正确,并且不能包含^/$运算符。

因此,先行运算符只能在模式规则中使用。

请注意, \\s匹配任何空格字符,包括换行符,而.匹配. 与任何换行符都不匹配。 我认为这就是导致您评论REGEX = [:letter:]+\\-[:letter:]\\. “如果匹配的字符串没有任何后继内容,则不起作用”(我猜您是说“ 在同一行上没有任何后继内容,并且您打算编写.而不是\\. )。”

您可能(取决于您的语言)而不是测试是否遵循空格,而是测试非单词字符:

[:letter:]+\-[:letter:]/\W

或根据\\W的定义(也可在JFlex手册的链接部分中找到),将更精确的规范作为一组Unicode属性来制定。

说了这么多,我想重复我先前对您的类似问题回答中的建议:首先提出更具体的模式。 例如,使用以下一对模式将确保第一个模式选择带有单个字母后缀的单词,同时避免显式回推。

[:letter:]+(-[:letter:])?   { /* matches 'interferon' or 'interferon-a' */ }
[:letter:]+/-[:letter:]+    { /* matches only 'interferon' from 'interferon-alpha' */ }

当然,在这种情况下,您可以通过使用{2,}而不是+来进行第二次重复,从而轻松避免第二个模式与第一个模式之间的冲突,但是完全可以依靠模式排序,因为通常不方便保证模式不重叠。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM