不区分大小写的关键词匹配

3
我正在编写一个用于解析计算机语言的语法,可与Parse::Eyapp一起使用。这是一个Perl包,简化了为常规语言编写解析器的过程。它类似于yacc和其他LALR解析器生成器,但具有一些有用的扩展功能,例如通过正则表达式定义令牌。
我想要解析的语言使用关键字来表示部分并描述控制流。它还支持用作数据占位符的标识符。标识符永远不会与关键字同名。
现在,这里来了棘手的部分:我需要将关键字与标识符分开,但它们可能看起来相似,因此我需要一个正则表达式模式,以不区分大小写的方式匹配标识符,而不匹配其他内容。
我想到的解决方案如下:
  1. 每个关键字都由以下形式的令牌标识:/((?i)keyword)(?!\w)/
    • (?i)将对后续子模式应用不区分大小写的匹配
    • (?!\w)不接受关键字后面的任何单词字符(a-z,0-9等)
    • 这些字符不是匹配的一部分
  2. 与另一个关键字开头相同的关键字列在较长的关键字之后,以便它们首先匹配
  3. 匹配标识符的令牌最后出现,因此仅在没有识别到关键字时才会匹配

我想问的是,我现在的做法是否正确?是否有更好、更简单的正则表达式来匹配这些关键字?我应该停下来使用完全不同的语言解析方法吗?

顺便说一下,使用分词器匹配整个字符串的想法来自于Parse::Eyapp文档。我先从逐字符语法开始,但这种方法不太优雅,似乎与解析器生成器的灵活性相矛盾。它也很麻烦。


这似乎更适合在codereview.se上。 - Martin Ender
可能吧,但我在这里并不是要求代码审查。我更希望能得到一些有关开发良好的分词器和(也许)编程语言语法方面的提示。我想我应该把那个问题表述得更清楚些。 - onitake
看起来你的方向是正确的。当我使用lex/flex时,我会为我的关键字想出类似的模式。最重要的是确保在关键字周围标记“单词边界”(这是你正在做的)并且在一般标识符之前匹配所有关键字令牌。 - Joe Z
不确定,但也许你可以使用\b代替(?!\w) - HamZa
谢谢你的提示,@HamZa。我想那也可以(而且会更优雅)。 - onitake
1个回答

2

哇,它们看起来都非常强大。我已经花了几天时间熟悉yacc/yapp,但现在转换还不算太晚。 - onitake
自从那篇教程写出来以后,Marpa的使用变得更加容易且功能更加强大。更为实时的教程请参考http://marpa-guide.github.io/index.html,http://marpa-guide.github.io/index.html和http://marpa-guide.github.io/index.html。 - Jeffrey Kegler
到目前为止,我尝试了 Regexp::Grammars。它的语法比 Parse::Eyapp 更加灵活,我喜欢它基本上增强了 Perl 的正则表达式。不幸的是,我遇到了一个重大问题。那么,让我们来看看 Marpa。 - onitake
Marpa看起来非常有前途,但由于量词限制为单语句规则,在我的情况下需要更多明确的规则。与我的原始问题一致,有人可以给我一个提示,如何在Marpa中实现不区分大小写的关键字匹配?字符串匹配不行,但字符类也不是很有用。我真的要像这样编写[kK][eE][yY][wW][oO][rR][dD]之类的东西吗? - onitake
我把我的最后一条评论变成了一个问题。链接 - onitake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接