Używanie regexu C ++ 11 do przechwytywania zawartości pliku gramatyki bezkontekstowej

Przedmowa

Próbuję napisać własną specyfikację gramatyczną bez kontekstu, aby powiązać ją z regułami mojego leksera / parsera. Ma być podobny do tego zANTLR, gdzie identyfikatory dużych liter klasyfikowane są jako reguła Lexera, a małe litery klasyfikowane jako reguła Parsera. Ma przyjmować dowolną kombinację literałów łańcuchowych i / lub wyrażeń regularnych dla reguł leksykonu oraz dowolną kombinację reguł leksykonu / wyrażenia regularnego i / lub innych identyfikatorów parsera dla reguł analizatora składni. Każda reguła jest w formacie<identyfikator>: <wyrażenie>;

Oto przykład gramatyki:

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


Problem

Mam problem z dopasowaniem ciągów wyrazów, ponieważ ich zawartość jest inna.
Pierwotnie napisałem:
([a-zA-Z0-9_]*)(?:\s*)(?:\:)(?:\s*)((?:\'?).*(?:\'?)(?:\;))
jako regułę dopasowania, która jest odpowiednia dla pojedynczego wyrażenia literałowego otoczonego pojedynczymi cudzysłowami, ale muszę to rozwinąć, aby umożliwić wiele nie-zachłannych literałów łańcuchowych, a połączone instrukcje oddzielone dowolną liczbą białych znaków. Nie interesuje mnie dopasowywanie potencjalnych wyrażeń regularnych w dopasowanym wyrażeniu, ani nawet przechwytywanie wyodrębnionych części wyrażenia, ponieważ jest to obsługiwane później przez oddzielną operację wyrażeń regularnych, więc naprawdę muszę tylkouprawomocnić identyfikatory i wyrażenia ...

W sumie, Potrzebuję operacji regex_search, aby przejrzeć zawartość gramatyki, używając następującej składni dla dopasowań:

Poprawny identyfikator, zaczynając od jednej lub więcej niższych lub wielkich liter, po których opcjonalnie może występować dowolna liczba znaków alfanumerycznych (które opcjonalnie mogą zawierać dowolną liczbę znaków podkreślenia między nimi, o ile identyfikator nie zaczyna się lub nie kończy na jednym).Dowolna liczba białe znaki, tabulatory, znaki nowej linii itp. bez przechwytywania.Dwukropek bez przechwytywania.Dowolna liczba białe znaki, tabulatory, znaki nowej linii itp. bez przechwytywania.Przynajmniej jeden z: (w dowolnej kolejności) dowolna liczba literałów łańcuchowych (zawartych w pojedynczych cudzysłowach, bez przechwytywania cudzysłowów), dowolna liczba identyfikatorów leksera / parsera, dowolna liczba wyrażeń regularnych (ujęta w nawiasy kwadratowe). Wynik tej reguły dopasowania powinien uchwycić całe wyrażenie jako pojedynczy ciąg, który następnie przejdzie przez etap przetwarzania końcowego.Dowolna liczba białe znaki, tabulatory, znaki nowej linii itp. bez przechwytywania.Średnik opcjonalnie następuje dowolne niezapisane białe spacje.Opcjonalnie dowolne liczba niezapisanych przestrzeni, po których następuje pojedynczy przechwycony komentarz liniiDowolna liczba białe znaki, tabulatory, znaki nowej linii itp. bez przechwytywania.Pytanie

Czy jest możliwe umieszczenie tego w pojedynczej operacji regex_search?
Wciągnęłam sięExpresso i po prostu nie mogę tego zrobić dobrze ...

Aktualizacja

Do tej pory udało mi się wymyślić:

#/////////////////////
# 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

Jak widać, mamidentyfikatory, separatory ikońce linii działa idealnie. Ale wyrażenia są tam, gdzie całkowicie utknąłem!

Jak mogę poinformować bibliotekę wyrażeń regularnych, którą chcęZARÓWNO nie chciwy literał smyczkowy,LUB dowolny zestaw znaków przed końcem linii,I dowolna ich liczba w dowolnej kolejności?

Nawet jeśli pozwoliłbym tylko na jeden ciąg literału, jak bym powiedział„Zamknięcie pojedynczej wyceny NIE jest opcjonalne, jeśli pierwsza istnieje”?

questionAnswers(1)

yourAnswerToTheQuestion