flex中的正则表达式有错误

时间:2015-04-07 09:40:21

标签: c regex flex-lexer identifier lexical-analysis

我是flex的新手,我想使用flex设计扫描仪。

在这一步,我想使正则表达式与id匹配,但这里有一些条件:

  1. 下划线可以存在于id

  2. 您可以随时使用_,但如果您正在使用它们 因此,它最多可以是2个下划线,例如:

    a_b_c»»»»

    a ___ b»»»»false

    123abv»»»»false

  3. 整数不能位于id的开头

  4. 下划线不能存在于id

  5. 的末尾

    我为此写的正则表达式是:

    (\b(_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*)\b)
    

    但现在我有两个问题:

    1. 正则表达式是真的吗?我已经在rubular.com进行了测试,我认为这是真的,但我不确定?

    2. 另一个重要的问题是,当我在我的flex文件中写这个时,很遗憾没有识别出id。但我不知道为什么它不被认可

    3. 有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

这里的问题是你的ID正则表达式。您正在使用\b来匹配单词边界,但Flex的正则表达式没有内置支持来匹配单词边界。除此之外,你的正则表达式是合理的。我能够使用您的这个修改版本来使用您的代码:_{0,2}[A-Za-z][0-9A-Za-z]*(_{0,2}[0-9A-Za-z]+)*。 (我刚刚摆脱了\b,以及一些困扰我的括号。)

不幸的是,这会导致轻微的问题。假设你是lexing并遇到类似12_345的东西。 Flex会阅读12,假设它找到IC,然后阅读_。找不到匹配项,它会将其打印到stdout,然后将345视为另一个IC

为了避免这个问题(由Flex缺少单词边界引起),你可以做以下两件事之一:

  • 在末尾创建一个匹配任何字符(除了空格)的规则,并使其出错。这将在上面的示例中到达_时停止Flex。
  • 在末尾创建一个匹配字母,数字和下划线([_0-9A-Za-z]+)组合的规则。如果匹配,则给出错误。这将导致Flex在上面的示例中将整个令牌12_345作为错误返回。

另一个问题: ID正则表达式仍然不会匹配任何带有下划线的内容。这意味着您当前的正则表达式并不完美,您需要对其进行一些调整,但现在您知道不使用\b符号。 Here是Flex的正则表达式语法的参考,因此您可以找到其他要使用/避免的内容。

答案 1 :(得分:0)

我认为您的要求是:

  1. 标识符只能使用字母数字字符和_

  2. 标识符不能以数字开头

  3. 标识符不能以 _

  4. 结尾
  5. 标识符不能包含两个以上连续 _

  6. (当我第一次阅读你的问题时,我认为最后一个要求是标识符不能包含两个以上 _ ,但是看看提议的正则表达式,我认为上面的版本更准确。)

    基于以上所述,您应该能够使用以下两种Flex模式:

    ([[:alpha:]]|__?[[:alnum:]])(_?_?[[:alnum:]])*  { /* Handle an identifier */ }
    [[:alpha:]_][[:alnum:]_]* { /* Error */ }
    

    打破这一点:

    • ([[:alpha:]]|__?[[:alnum:]])匹配字母字符或一个或两个 _ 后跟一个字母数字字符。

    • (_?_?[[:alnum:]])*匹配 和字母数字字符串,最多两个 在字母数字字符之前。

    第二种模式将匹配任何以字母字符开头的内容或 后跟任意数量的字母数字或 。这将匹配所有有效标识符以及包含太多连续 或以 结尾的序列。如果两个模式匹配(即有效标识符),则第一个模式将获胜,因此将被正确识别。第二种模式将使用整个错误标识符,从而可以更容易地进行错误恢复。

    OP中的模式不起作用,因为flex将\b视为退格符(如C中所示)。 Flex没有实现单词边界断言,但在词法分析器中你几乎不需要这些;如有必要,可以使用上面的模式。