【问题标题】:unrecognized rule in lex when using '|' (or) regex使用“|”时 lex 中无法识别的规则(或)正则表达式
【发布时间】:2021-09-30 14:33:51
【问题描述】:

我正在制作一个使用 Lex 识别关键字、标识符、int、float 和运算符的程序,但即使没有任何问题,我也会不断出错。下面是我的代码。 (文件名为d.l

第6行,如果是几个关键字之一,则输出关键字,所以|用作 or 的正则表达式。

%%
[_a-zA-Z][_a-zA-Z0-9]{0,30} printf("identifier\n");
(if|then|else|end|repeat|read|until|write)  printf("keyword\n");
^[-+]?[0-9]*    printf("integer\n");
^[-+]?[0-9]*[.][0-9]*   printf("float\n");
(+|-|*|/) printf("operator");

当我执行 lex d.l 时,结果是错误消息:

d.l:6: unrecognized rule

我是第一次学习 lex 和正则表达式。任何帮助将不胜感激。

【问题讨论】:

  • 由于显示的第 6 行包含 (+|-|*|/)* 是 Lex 元字符,您可能需要对其进行转义 - \*'*' 可能会起作用。
  • 我想你会发现if被识别为一个标识符。另外,我认为输入0.123 将被识别为整数0,后跟一个不匹配的.(然后,可能是另一个整数123)。您可能需要稍微重新排序规则。
  • 感谢您的回复。我把它改成了 (+|-|*|/) ,但我得到了同样的错误。
  • 嗯——想想看,+ 不也是另一个 Lex 元字符吗?另外,我在您的评论中看不到您修改后的代码之间的区别。 (在 cmets 内的反引号内引用代码:code 输入为 …`code`…(或多或少)
  • @JonathanLeffler 您对关键字是正确的,但是浮动规则应该可以正常工作,因为浮动规则会产生更长的匹配。数字规则让我感到困惑的是,它们只识别行首的数字,但这看起来是故意的(为什么^ 会在那里?)。

标签: regex lex


【解决方案1】:
(+|-|*|/) printf("operator");

这里的问题不是你使用了|,而是你使用了+*/,它们是正则表达式中的特殊字符(但不在字符类中)。

您可以通过转义它们(通过在它们前面加上 \ 或将它们括在引号中)或使用字符类来解决此问题,这将是最惯用的解决方案。请注意,在字符类内部- 不是字符类中的第一项或最后一项时具有特殊含义(因此不要将- 放在中间或转义它)。

所以这些解决方案中的任何一个都可以工作(最后一个是最惯用的):

(\+|-|\*|\/) printf("operator");
("+"|-|"*"|"/") printf("operator");
[-+*/] printf("operator");

【讨论】:

  • 谢谢!!有用。 (if|then|else|end|repeat|read|until|write) printf("keyword\n");这里好像没有问题??我收到一条错误消息,提示找不到匹配规则(韩语)
  • @user9178840 关键字规则的问题在于 Jonathan Leffer 在评论中已经指出的顺序。由于标识符规则首先出现并且也匹配关键字,因此它具有优先权并且始终被选择在关键字规则之上。我建议您阅读最大咀嚼规则,以了解有关规则顺序何时以及如何重要的更多信息。
  • 好不容易解决了半天,但是谢谢你让我知道的很详细,很方便。我会研究它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多