Mit C ++ 11 regex den Inhalt einer kontextfreien Grammatikdatei erfassen

Vorwort

Ich versuche, meine eigene kontextfreie Grammatikspezifikation zu schreiben, um sie mit den Regeln meines Lexers / Parsers zu verknüpfen. Es soll dem von ähnlich seinANTLRDabei werden Großbuchstaben als Lexer-Regel und Kleinbuchstaben als Parser-Regel klassifiziert. Es ist beabsichtigt, eine beliebige Kombination von String-Literalen und / oder regulären Ausdrücken für Lexer-Regeln und eine beliebige Kombination von Lexer / Regex-Regeln und / oder anderen Parser-IDs für Parser-Regeln zu akzeptieren. Jede Regel in ist das Format von<bezeichner>: <ausdruck>;

Hier ist ein Beispiel für die Grammatik:

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

Die Schwierigkeit, die ich habe, ist die Fähigkeit, die Ausdruckszeichenfolgen abzugleichen, da deren Inhalt dazu neigt, sich zu ändern.
Ich habe ursprünglich geschrieben:
([a-zA-Z0-9_]*)(?:\s*)(?:\:)(?:\s*)((?:\'?).*(?:\'?)(?:\;))
als Übereinstimmungsregel, die für einen einzelnen String-Literal-Ausdruck in einfachen Anführungszeichen in Ordnung ist, aber ich muss dies erweitern, um mehrere nicht-gierige String-Literale und kombinierte Anweisungen zuzulassen, die durch eine beliebige Anzahl von Leerzeichen getrennt sind. Es geht mir nicht darum, mögliche reguläre Ausdrücke innerhalb eines übereinstimmenden Ausdrucks abzugleichen oder auch nur getrennte Teile des Ausdrucks zu erfassen, da dies später durch eine separate reguläre Ausdrücke-Operation erledigt wird, also muss ich das wirklich nur tunbestätigen Bezeichner und Ausdrücke ...

Alles in allem, Ich benötige die Operation regex_search, um den Inhalt der Grammatik zu durchsuchen. Dabei verwende ich die folgende Syntax für Übereinstimmungen:

Eine gültige IDbeginnend mit einem oder mehreren Klein- oder Großbuchstaben, optional gefolgt von einer beliebigen Anzahl von alphanumerischen Zeichen (die optional eine beliebige Anzahl von Unterstrichen dazwischen enthalten können, solange der Bezeichner nicht mit einem beginnt oder endet).Eine beliebige Anzahl von Leerzeichen, Tabulatoren, Zeilenumbrüche usw., ohne sie zu erfassen.Ein Doppelpunkt ohne es zu erfassen.Eine beliebige Anzahl von Leerzeichen, Tabulatoren, Zeilenumbrüche usw., ohne sie zu erfassen.Mindestens einer von: (in beliebiger Reihenfolge) eine beliebige Anzahl von String-Literalen (in einfachen Anführungszeichen eingeschlossen, ohne die Anführungszeichen zu erfassen), eine beliebige Anzahl von Lexer / Parser-Bezeichnern, eine beliebige Anzahl von Regexen (in eckigen Klammern eingeschlossen). Das Ergebnis dieser Übereinstimmungsregel sollte den gesamten Ausdruck als einzelne Zeichenfolge erfassen, die später eine Nachverarbeitungsphase durchläuft.Eine beliebige Anzahl von Leerzeichen, Tabulatoren, Zeilenumbrüche usw., ohne sie zu erfassen.Ein Semikolon optional gefolgt von einem nicht erfassten Leerzeichen.Optional jede Anzahl der nicht erfassten Leerzeichen, gefolgt von einem einzelnen erfassten ZeilenkommentarEine beliebige Anzahl von Leerzeichen, Tabulatoren, Zeilenumbrüche usw., ohne sie zu erfassen.Frage

Ist es möglich, dies in einer einzelnen regex_search-Operation zu platzieren?
Ich habe rumgespieltExpresso und kann es einfach nicht richtig machen ...

Aktualisieren

Bisher konnte ich Folgendes erfinden:

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

Wie Sie sehen können, habe ichBezeichner, Trennzeichen undZeilenenden perfekt arbeiten. Aber in Ausdrücken stecke ich total fest!

Wie kann ich der Regex-Bibliothek mitteilen, dass ich möchte?ENTWEDER ein nicht gieriges String-Literal,ODER eine beliebige Anzahl von Zeichen vor dem Zeilenende,UND eine beliebige Anzahl von ihnen in beliebiger Reihenfolge?

Auch wenn ich nur ein einziges String-Literal zulasse, wie würde ich sagen"Das schließende einfache Anführungszeichen ist NICHT optional, wenn das erste vorhanden ist"?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage