Я пытаюсь написать свою собственную спецификацию грамматики без контекста, чтобы связать ее с правилами моего лексера / парсера. Это должно быть похоже на ANTLRгде идентификаторы в верхнем регистре классифицируются как правило Lexer, а идентификаторы в нижнем регистре классифицируются как правило Parser. Он предназначен для принятия любой комбинации строковых литералов и / или регулярных выражений для правил лексера и любой комбинации правил лексера / регулярного выражения и / или других идентификаторов синтаксического анализатора для правил синтаксического анализатора. Каждое правило в формате <идентификатор>:<выражение>;
Вот пример грамматики:
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
Как видите, у меня есть идентификаторы, сепараторы а также линия концы работает отлично. Но выражения, где я полностью застрял!
Как я могу сказать библиотеке регулярных выражений, что я хочу ИЛИ не жадный строковый литерал, ИЛИ ЖЕ любой набор символов до конца строки, А ТАКЖЕ любое их количество в любом порядке?
Даже если бы я допустил только один строковый литерал, как бы я сказал «Закрывающая одинарная кавычка НЕ обязательна, если существует первая»?
Это может быть не безупречно и может потребовать дополнительного кодирования того, как обрабатываются результаты совпадений, но, похоже, это работает:
#/////////////////////
# Identifier
#/////////////////////
(
(?:[a-zA-Z]+)
(?:
(?:[a-zA-Z0-9_]*)
(?:\w+)
)?
)
#/////////////////////
# Separator
#/////////////////////
(?:\s*\:\s*)
#///////////////////////
# Expression
#///////////////////////
(
'(?:\\\\.|[^'])*'|[^']+ # Might need to be processed separately
)
#/////////////////////
# Line End
#/////////////////////
(?:\s*\;\s*)
Других решений пока нет …