前言
我正在尝试编写自己的上下文无关语法规范,以与我的词法分析器/解析器的规则相关联。这意味着类似于ANTLR的,其中大写标识符分类为 Lexer 规则,小写标识符分类为 Parser 规则。它旨在接受用于词法分析器规则的字符串文字和/或正则表达式的任何组合,以及用于解析器规则的词法分析器/正则表达式规则和/或其他解析器标识符的任何组合。里面的每条规则都是<identifier>:<expression>的格式;
下面是一个语法示例:
integer : DIGIT+; //parser rule containing at least one lexer rule
twodigits : DIGIT DIGIT; //parser rule containing two consecutive lexer rules
DIGIT : [0-9]; //lexer rule containing regex
string : '"' CHAR* '"'; //parser rule containing zero or more
// lexer rules, wrapped in two string literals
CHAR : (LCHAR|UCHAR); //lexer rule containing two lexer rules which
// will later evaluate to one of two tokens
LCHAR : [a-z]; //lexer rule containing regex
UCHAR : [A-Z]; //lexer rule containing regex
SPACE : ' '; //lexer rule containing string literal
问题
我遇到的麻烦是匹配表达式字符串的能力,因为它们的内容往往会有所不同。
我最初写
([a-zA-Z0-9_]*)(?:\s*)(?:\:)(?:\s*)((?:\'?).*(?:\'?)(?:\;))
的是:作为匹配规则,它适用于由单引号括起来的单个字符串文字表达式,但我需要扩展它以允许多个非贪婪字符串文字,以及由任意数量的空格分隔的组合语句。我不关心在匹配的表达式中匹配潜在的正则表达式,甚至不关心表达式的隔离部分,因为这稍后由单独的正则表达式操作处理,所以实际上我只需要验证标识符和表达式......
总而言之,我需要 regex_search 操作来查看语法的内容,使用以下语法进行匹配:
- 一个有效的标识符,以一个或多个小写或大写字母开头,后跟任意数量的字母数字字符(可选地可以在其间包含任意数量的下划线字符,只要标识符不以一个开头或结尾)。
- 任意数量的空白字符、制表符、换行符等,而不捕获它。
- 没有捕获的冒号。
- 任意数量的空白字符、制表符、换行符等,而不捕获它。
- 至少以下之一:(以任何顺序)任意数量的字符串文字(括在单引号中,不捕获引号),任意数量的词法分析器/解析器标识符,任意数量的正则表达式(括在方括号中)。此匹配规则的结果应将整个表达式捕获为单个字符串,稍后将通过后处理阶段。
- 任意数量的空白字符、制表符、换行符等,而不捕获它。
- 分号可选地后跟任何未捕获的空格。
- (可选)任意数量的未捕获空格,后跟单个捕获的行注释
- 任意数量的空白字符、制表符、换行符等,而不捕获它。
问题
是否可以将其放入单个 regex_search 操作中?
我在Expresso中搞砸了,但似乎无法正确处理......
更新
到目前为止,我已经能够提出以下建议:
#/////////////////////
# Identifier
#/////////////////////
(
(?:[a-zA-Z]+) # At least one lower/uppercase letter
(?:
(?:[a-zA-Z0-9_]*) # Zero or more alphanumeric/underscore characters,
(?:\w+) # explicitly followed by one or more alphanumeric
)? # characters
)
#/////////////////////
# Separator
#/////////////////////
(?:\s*) # Any amount of uncaptured whitespace
(?:\:) # An uncaptured colon
(?:\s*) # Any amount of uncaptured whitespace
#///////////////////////
# Expression
#///////////////////////
(
# String Literals:
(?:\'?) # An optional single quote,
(?: # which is meant to start and end a string
(?:[^'\\] | \\.)* # literal, but issues several problems for
) # me (see comments below, after this code block)
(?:\'?)
# Other expressions
# ????????????
)
#/////////////////////
# Line End
#/////////////////////
(?:\s*) # Any amount of uncaptured whitespace
(?:\;) # An uncaptured colon
(?:\s*) # Any amount of uncaptured whitespace
如您所见,我的标识符、分隔符和行尾工作得很好。但是表情是我完全卡住的地方!
我如何告诉正则表达式库我想要一个非贪婪的字符串文字,或者行尾之前的任何字符集,以及任何数量的任意顺序?
即使我只允许一个字符串文字,我怎么会说“如果第一个单引号存在,则右单引号不是可选的”?