2

前言

我正在尝试编写自己的上下文无关语法规范,以与我的词法分析器/解析器的规则相关联。这意味着类似于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

如您所见,我的标识符分隔符行尾工作得很好。但是表情是我完全卡住的地方!

我如何告诉正则表达式库我想要一个非贪婪的字符串文字,或者行尾之前的任何字符集,以及任何数量的任意顺序?

即使我只允许一个字符串文字,我怎么会说“如果第一个单引号存在,则右单引号不是可选的”

4

1 回答 1

0

它可能并非完美无缺,并且可能需要对匹配结果的处理方式进行额外编码,但这似乎可行:

#/////////////////////
# Identifier
#/////////////////////
(
    (?:[a-zA-Z]+)
    (?:
        (?:[a-zA-Z0-9_]*)
        (?:\w+)
    )?
)

#/////////////////////
# Separator
#/////////////////////
(?:\s*\:\s*)

#///////////////////////
# Expression
#///////////////////////
(
    '(?:\\\\.|[^'])*'|[^']+     # Might need to be processed separately
)

#/////////////////////
# Line End
#/////////////////////
(?:\s*\;\s*)
于 2013-03-12T21:30:29.380 回答