使用C++11正则表达式捕获上下文无关语法文件的内容

Using C++11 regex to capture the contents of a context-free-grammar file

本文关键字:文件 上下文无关语法 C++11 正则表达式 使用      更新时间:2023-10-16

前言

我正在尝试编写我自己的上下文无关语法规范,以与我的lexer/parser的规则相关联。它与ANTLR类似,其中大写标识符分类为Lexer规则,小写标识符分类为Parser规则。它旨在接受lexer规则的字符串文字和/或正则表达式的任何组合,以及语法分析器规则的lexer/regex规则和/或其他语法分析器标识符的任何组合。中的每个规则的格式为<标识符>:<表达式>

这里有一个语法示例:

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操作来查看语法的内容,使用以下语法进行匹配:

  • 一个有效的标识符,以一个或多个小写字母或大写字母开头,可选择后跟任意数量的字母数字字符(可选择在两者之间包含任意数量的下划线字符,只要标识符不以一开头或结尾(
  • 任意数量的空白字符、制表符、换行符等,而不捕获它们
  • 冒号而不捕获它
  • 任意数量的空白字符、制表符、换行符等,而不捕获它们
  • 中的至少一个:(按任何顺序(任意数量的字符串文字(用单引号括起来,不捕获引号(、任意数量的lexer/parser标识符、任意数量(用方括号括起来(的正则表达式。此匹配规则的结果应将整个表达式捕获为单个字符串,该字符串稍后将经过后处理阶段
  • 任意数量的空白字符、制表符、换行符等,而不捕获它们
  • 分号(可选(后跟任何未捕获的空格
  • 可选,后面跟有单个捕获行注释的任意数量的未捕获空格
  • 任意数量的空白字符、制表符、换行符等,而不捕获它们

问题

是否可以将其放入单个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

正如您所看到的,我有标识符分隔符行尾,它们工作得很好。但表情是我完全被卡住的地方

我如何告诉正则表达式库我想要非贪婪字符串文字,行尾前的任何字符集,AND任意数量的字符(按任意顺序(

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

它可能不是完美无瑕的,并且可能需要额外的编码来处理匹配结果,但这似乎是有效的:

#/////////////////////
# Identifier
#/////////////////////
(
    (?:[a-zA-Z]+)
    (?:
        (?:[a-zA-Z0-9_]*)
        (?:w+)
    )?
)
#/////////////////////
# Separator
#/////////////////////
(?:s*:s*)
#///////////////////////
# Expression
#///////////////////////
(
    '(?:\\.|[^'])*'|[^']+     # Might need to be processed separately
)
#/////////////////////
# Line End
#/////////////////////
(?:s*;s*)