【问题标题】:Unix Flex Regex for Multi-Line Comments用于多行注释的 Unix Flex 正则表达式
【发布时间】:2011-06-12 23:03:03
【问题描述】:

我正在 Unix 上使用 Flex 制作词法分析器。如果您在知道之前使用过它,那么您主要只是为您正在为其编写词法分析器的任何语言的标记定义正则表达式。我被困在最后一部分。我需要正确的多行 cmets 正则表达式,允许类似

/* This is a comment \*/

但也允许

/* This **** //// is another type of comment */

有人可以帮忙吗?

【问题讨论】:

  • 您可以编辑您的问题以改进“问题”示例吗?他们需要换行符来正确表达您遇到的问题,但我无法弄清楚他们丢失的地方。 (缩进 4 个空格使一个段落成为示例代码部分。)

标签: regex unix flex-lexer


【解决方案1】:

你不能用 Flex 中的简单正则表达式匹配 C 风格的 cmets;它们需要基于起始状态的更复杂的匹配方法。 Flex FAQ 说明了如何(嗯,他们为 /*...*/ 表单做的;在 <INITIAL> 状态下处理其他表单应该很简单)。

【讨论】:

  • 啊,我想有一个关于它的常见问题解答! :) +1
  • @Bart:前几天我在回答一个 SO 问题时发现了它(关于解析 XML CDATA 部分,在解析术语时遇到了一个非常相似的问题,除了它更重要 i> 以正确的方式进行操作,因为结尾部分的序列长度为三个字符)。
  • 如果只需要 RegEx,,"/*"( [^*] | (*+[^*/]) )*\*+\/ 就可以了。我已经在stackoverflow.com/a/32320759/3000919 中进行了更详细的解释
  • @DonalFellows 请将该页面的答案添加到您的答案中。答案现在可能会丢失。
【解决方案2】:

如果您只需要使用正则表达式,那么确实有一个不太复杂的解决方案:


"/*"( [^*] | (\*+[^*/]) )*\*+\/
该正则表达式的完整解释和推导在here 上得到了很好的阐述。
简而言之:
  • "/*" 标记注释的开始
  • ( [^*] | (\*+[^*/]) )* 表示接受所有不是 * 的字符( [^*] )或接受一个或多个 * 的序列,只要序列后面没有 '*' 或 /' ((*+[^*/]))。这意味着除了 *****/ 之外的所有 ******... 序列都将被接受,因为您无法在其中找到不带 * 或 / 的 * 序列。
  • 然后 *******/ 情况由 RegEx 的最后一位处理,该位匹配任意数量的 *,后跟 / 以标记注释的结尾,即 \*+\/
  • 【讨论】:

      【解决方案3】:

      http://www.lysator.liu.se/c/ANSI-C-grammar-l.html 会:

      "/*"            { comment(); }
      
      comment() {
          char c, c1;
      
      loop:
          while ((c = input()) != '*' && c != 0)
              putchar(c);
      
          if ((c1 = input()) != '/' && c != 0) {
              unput(c1);
              goto loop;
          }
      
          if (c != 0)
              putchar(c1);
      }
      

      也可以解决这个问题的问题是How do I write a non-greedy match in LEX / FLEX?

      【讨论】:

      • 如果有人能猜出为什么投反对票,我很想听听。
      • 这里不是反对票 - 但即使是星号也会失败: /** hello ****/ printf("lol"); /** hmmm */ 原因是 *[^/] 如果 * 后面没有 / 会一次消耗两个 *
      • @AbrahamPhilip 谢谢!我的正则表达式是错误的,而你的似乎是正确的。从答案中删除它。
      • np,很高兴能帮上忙 :)
      【解决方案4】:

      我不知道 flex,但我知道正则表达式。 /\/\*.*?\*\//s 应该匹配这两种类型(在 PCRE 中),但如果您需要在分析器中区分它们,您可能需要迭代匹配列表以查看它们是否是 /\*\*\s+\/{4}/ 的第二种类型

      【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2011-01-28
      • 1970-01-01
      • 2016-07-20
      • 2019-12-25
      • 2011-02-04
      • 2013-04-20
      • 2014-11-07
      相关资源
      最近更新 更多