flex中的正则表达式有错误

Regular expressions in flex has error

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

在这一步,我想做正则表达式来匹配id,但是有一些条件:

  1. id中可以存在下划线

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

    a_b_c »»»» 真

    a___b »»»» 错误

    123abv »»»» 假

  3. 整数不能在 id 的开头

  4. id 末尾不能有下划线

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

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

但现在我有两个问题:

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

  2. 另一个重要的问题是,当我在我的 flex 文件中写这个时,不幸的是没有识别出 id。但是不明白为什么不被识别

谁能帮帮我?

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

不幸的是,这会导致一个小问题。假设您正在对诸如 12_345 之类的内容进行词法分析和 运行。 Flex 将读取 12,假设它找到了一个 IC,然后读取 _。找不到匹配项,它会将其打印到标准输出,然后将 345 读取为另一个 IC.

为了避免这个问题(由 Flex 缺少单词边界引起),您可以执行以下两种操作之一:

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

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

的其他内容

我认为你的要求是:

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

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

  3. 标识符不能以 _

  4. 结尾
  5. 标识符不能超过两个连续_

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

基于以上内容,您应该可以使用以下两种 Flex 模式:

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

分解:

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

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

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

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