Использование регулярного выражения C ++ 11 для захвата содержимого файла безконтекстной грамматики

Я пытаюсь написать свою собственную спецификацию грамматики без контекста, чтобы связать ее с правилами моего лексера / парсера. Это должно быть похоже на 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

Как видите, у меня есть идентификаторы, сепараторы а также линия концы работает отлично. Но выражения, где я полностью застрял!

Как я могу сказать библиотеке регулярных выражений, что я хочу ИЛИ не жадный строковый литерал, ИЛИ ЖЕ любой набор символов до конца строки, А ТАКЖЕ любое их количество в любом порядке?

Даже если бы я допустил только один строковый литерал, как бы я сказал «Закрывающая одинарная кавычка НЕ ​​обязательна, если существует первая»?

2

Решение

Это может быть не безупречно и может потребовать дополнительного кодирования того, как обрабатываются результаты совпадений, но, похоже, это работает:

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

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

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

#/////////////////////
# Line End
#/////////////////////
(?:\s*\;\s*)
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]