我正在编写一个用于解析计算机语言的语法,可与Parse::Eyapp一起使用。这是一个Perl包,简化了为常规语言编写解析器的过程。它类似于yacc和其他LALR解析器生成器,但具有一些有用的扩展功能,例如通过正则表达式定义令牌。
我想要解析的语言使用关键字来表示部分并描述控制流。它还支持用作数据占位符的标识符。标识符永远不会与关键字同名。
现在,这里来了棘手的部分:我需要将关键字与标识符分开,但它们可能看起来相似,因此我需要一个正则表达式模式,以不区分大小写的方式匹配标识符,而不匹配其他内容。
我想到的解决方案如下:
我想要解析的语言使用关键字来表示部分并描述控制流。它还支持用作数据占位符的标识符。标识符永远不会与关键字同名。
现在,这里来了棘手的部分:我需要将关键字与标识符分开,但它们可能看起来相似,因此我需要一个正则表达式模式,以不区分大小写的方式匹配标识符,而不匹配其他内容。
我想到的解决方案如下:
- 每个关键字都由以下形式的令牌标识:
/((?i)keyword)(?!\w)/
(?i)
将对后续子模式应用不区分大小写的匹配(?!\w)
不接受关键字后面的任何单词字符(a-z,0-9等)- 这些字符不是匹配的一部分
- 与另一个关键字开头相同的关键字列在较长的关键字之后,以便它们首先匹配
- 匹配标识符的令牌最后出现,因此仅在没有识别到关键字时才会匹配
我想问的是,我现在的做法是否正确?是否有更好、更简单的正则表达式来匹配这些关键字?我应该停下来使用完全不同的语言解析方法吗?
顺便说一下,使用分词器匹配整个字符串的想法来自于Parse::Eyapp文档。我先从逐字符语法开始,但这种方法不太优雅,似乎与解析器生成器的灵活性相矛盾。它也很麻烦。
\b
代替(?!\w)
。 - HamZa