jFlex 中的正则表达式具有硬编码异常



我需要jFlex中的一个正则表达式来匹配字符串文字,其中包含一些字符,后跟一个连字符,后跟一个单词。但是,有一些硬编码的异常。我的 jFlex 版本是 1.6.1

我的正则表达式是:

SUFFIXES = labeled|deficient
ALPHANUMERIC = [:letter:]|[:digit:]
AVOID_SUFFIXES = {SUFFIXES} | !({ALPHANUMERIC}+)
WORD = ({ALPHANUMERIC}+([-/.]!{AVOID_SUFFIXES})*)

字符串"MXs12-labeled"应标记为'MXs12', '-', 'labeled'(稍后由不同的正则表达式捕获连字符),并"MXs12-C123"'MXs12-C123',因为 C123 不在后缀列表中。

但是,我获得的令牌是"MXs12-labele"- 比例外禁止的令牌少一个字母。

一个明显的解决方案是在正则表达式中包含额外的非{ALPHANUMERIC}字符,但这也会将此字符添加到匹配项中。

另一种解决方案似乎是使用负面的前瞻性,但是每次我尝试解析它们时,它们都会返回语法错误 - jFlex似乎不支持它。(Flex 似乎不支持正则表达式前瞻断言(快速 lex 分析器))

有谁知道如何在jFlex中解决这个问题?

正如你所观察到的,使用正匹配比处理负匹配要容易得多。(显然,labele不匹配labeled,而且它是labeled的最长前缀,不匹配labeled,所以如果你尝试匹配一个!labeled的单词,你会得到labele匹配是合乎逻辑的。

JFlex 没有实现负面的前瞻断言,这些断言略有不同,但仍然存在问题。一个否定的前瞻性断言肯定会拒绝MXs12-labeled中的后缀,但它也会拒绝MXs12-labeledblack中的后缀,我认为这会有点令人惊讶。

但是,如果您用积极的匹配来改写这一点,那真的很简单。这个想法是指定每个正匹配需要做什么。在这种情况下,我们要对-labeled的正匹配所做的是将其放回输入流中,这可以通过yypushback.这将建议这样的规则:

{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* "-labeled"  { yypushback(8); /* return the WORD */ }
{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* "-deficient"  { yypushback(10); return /* return the WORD */ }
{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* { return /* return the WORD */ }

请注意,顺序很重要,因为序列依赖于前两个模式,其优先级高于最后一个模式。(与前两种模式之一匹配的输入也将匹配最后一个模式,但按照指示的顺序排列规则,最后一个模式不会获胜。

这可能是也可能不是你真正想要的。它将按照您的问题MXs12-labeledMXs12-C123处理。MXs12-labeledblackMXs12-labeled-black都将报告为单个令牌;我完全不清楚你对这些输入的期望是什么。

Rici的回答解决了这个问题 -yypushback()这正是我所需要的。截至目前

  1. jflex 捕获所有字符串,带或不带后缀
  2. 在ACRONYMS的输出部分中有额外的Java正则表达式,检查字符串是否有后缀,如果是,则使用yypushback()

使用额外的 java 正则表达式,我可以涵盖上述边缘情况,例如"\-labeled$"确保后缀位于传递的字符串的末尾,并且MXs12-labeled-black将作为一个标记返回,而MXs12-labeled作为三个标记返回。谢谢!

相关内容

  • 没有找到相关文章

最新更新