【问题标题】:Case-insensitive keyword matching不区分大小写的关键字匹配
【发布时间】:2013-06-28 18:39:50
【问题描述】:

我正在编写一个用于解析计算机语言的语法,它可以与Parse::Eyapp 一起使用。这是一个 Perl 包,它简化了为常规语言编写解析器。它类似于 yacc 和其他 LALR 解析器生成器,但有一些有用的扩展,例如根据正则表达式定义标记。

我要解析的语言使用关键字来表示部分并描述控制流。它还支持用作数据占位符的标识符。标识符永远不能与关键字同名。

现在,棘手的部分来了:我需要将关键字与标识符分开,但它们可能看起来很相似,所以我需要一个不区分大小写地匹配标识符的正则表达式模式,仅此而已。

我想出的解决方案如下:

  1. 每个关键字都由以下形式的标记标识:/((?i)keyword)(?!\w)/
    • (?i) 将为以下子模式应用不区分大小写的匹配
    • (?!\w) 将不接受关键字后面的任何单词字符(a-z、0-9 等)
    • 这些字符将不属于匹配项
  2. 与另一个关键字开头相同的关键字列在较长关键字之后,因此它们首先匹配
  3. 用于匹配标识符的标记位于最后,因此仅在没有识别关键字时才会匹配

到目前为止,我提出的标记定义和部分语法运行良好,但仍有很多工作要做。不过,这不是我的问题。

我想问的是,我是不是走在正确的轨道上;是否有更好、更简单的正则表达式来匹配这些关键字?我应该停止并完全使用不同的方法进行语言解析吗?

顺便说一句,使用标记器匹配整个字符串而不是单个字符的想法来自 Parse::Eyapp 文档。我首先从逐个字符的语法开始,但这种方法不是很优雅,而且似乎与解析器生成器的灵活性相矛盾。写起来也很麻烦。

【问题讨论】:

  • 这似乎属于codereview.se
  • 可能,但我不是在这里要求进行代码审查。我宁愿对为编程语言开发一个好的分词器和(也许)语法有一些提示。我想我应该更清楚一点。
  • 看来您走在了正确的轨道上。当我使用 lex/flex 时,我为我的关键字提出了类似的模式。最主要的是确保在关键字周围标记“单词边界”(您正在这样做),并在通用标识符之前匹配所有关键字标记。
  • 不确定,但也许您可以使用\b 代替(?!\w)
  • 感谢@HamZa 的提示。我想这也可以(而且会更优雅)。

标签: regex perl yacc


【解决方案1】:

如果您想解析一种语言,Marpa 可能更适合您。这是tutorial。你也可以使用regexp grammars

【讨论】:

  • 哇,它们看起来都非常强大。我花了几天时间弄脏了 yacc/yapp,但现在切换还为时不晚。
  • 自编写教程以来,Marpa 变得更易于使用且功能更强大。更多最新教程是marpa-guide.github.io/index.htmlmarpa-guide.github.io/index.htmlmarpa-guide.github.io/index.html
  • 到目前为止,我尝试过Regexp::Grammars。它的语法比Parse::Eyapp 更通用,我喜欢它基本上增强了Perl 的正则表达式。不幸的是,我打了一个big showstopper。那么让我们看看玛尔巴吧。
  • Marpa 看起来很有希望,除了在我的情况下它需要更明确的规则,因为量词限制为单语句规则。根据我最初的问题,有人可以提示我如何在 Marpa 中实现不区分大小写的关键字匹配吗?字符串匹配已经过时,但字符类也没有真正的帮助。我真的需要写类似 [kK][eE][yY][wW][oO][rR][dD] 的东西吗?
  • 我把我最后的评论变成了a question
猜你喜欢
  • 2014-09-07
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
相关资源
最近更新 更多