Dynamische Scanner |
Top Previous Next |
Skripte > Klassen-Elemente und C++-Befehle > Parserklasse-Methoden > Plugin-Methoden > Dynamische Scanner
Dynamische Scanner machen den TextTransformer gewissermaßen lernfähig. Textabschnitte - meist Worte -, die zunächst durch einen allgemeinen regulären Ausdruck erkannt werden, können einem Platzhalter-Token zugeordnet werden. Kommt der gleiche Textteil an späterer Stelle im Eingabetext erneut vor, so kann er nun durch das bisherige Platzhalter-Token erkannt werden.
Da das nächste Token immer schon bereits erkannt ist, kann ein neu hinzugefügtes dynamisches Token erst erkannt werden, wenn das nächste Token konsumiert wurde. Falls nötig, kann auch nach AddToken xState.SetPosition(xState.Position()) aufgerufen werden, wodurch eine Neuerkennung an der aktuellen Position erzwungen wird.
Ab TextTransformer 1.3.4 kann AddToken als Übergangsaktion ausgeführt werden. Damit steht es bereits vor Ermittlung des nächsten Tokens zur Verfügung.
Unabhängig von den Projekteinstellungen wird bei Platzhalter-Token stets zwischen Groß- und Kleinschreibung unterschieden.
bool AddToken( const str& xsText, const str& xsDynTokenName)
AddToken fügt dem zuvor zu definierenden Platzhalter-Token xsDynTokenName den String xsText als Alternative hinzu. Sobald der Parser dann auf das Vorkommen des xsDynTokenName genannten dynamischen Tokens im Text prüft und dort der String xsText steht, gilt xsDynTokenName als erkannt. Die Funktion gibt bei Erfolg true zurück. Wenn das Platzhalter-Token nicht definiert ist, wird false zurückgeliefert.
bool AddToken( const str& xsText, const str& xsDynTokenName, const str& xsScope)
Speziell zum Parsen von Programmiersprachen ist die relativ komplexe AddToken-Methode mit drei Parametern konzipiert. Wird diese aufgerufen, so wird wie bei dem Aufruf mit nur zwei Parametern dem Platzhalter-Token xsDynTokenName den String xsText als Alternative hinzugefügt. Diese Alternative wird beim anschließenden Parsen aber nur dann im Text erkannt, wenn der aktuelle Textbereich entweder xsScope ist oder ein ihm untergeordneter (später hinzugefügter) Textbereich ist. Wird z.B. die Deklaration einer Klasse geparst, können die Namen der Klassenvariablen dem Scope der Klasse - d.h. ihrem Namen - zugeordnet werden. Im Definitionsteil kann dann erneut der Scope der Klasse gesetzt werden und der dynamische Scanner wird die Namen der Klassenvariablen wiedererkennen. Außerhalb des Scopes können die gleichen Namen eine anderer Bedeutung haben.
Beispiel: " Eval; Eval; Eval "
ID {{ AddToken(xState.str(), "USER_FUNCTION", "FUNCTION_SCOPE"); PushScope("FUNCTION_SCOPE"); PushScope("BLOCK_SCOPE"); }} // das nächste Token ist bereits erkannt, Eval kann daher frühestens als übernächstes als USER_FUNCTION erkannt werden.
";"
USER_FUNCTION // Eval wird als USER_FUNCTION erkannt, weil der aktuelle Scope BLOCK_SCOPE dem Scope FUNCTION_SCOPE untergeordnet ist
{{ PopScope(); PopScope(); }}
";"
USER_FUNCTION // Eval wird nicht erkannt, da aktuell kein Scope gesetzt ist, d.h. auch nicht der FUNCTION_SCOPE oder ein ihm untergeordneter Scope.
Beispiel:
In Grammatiken anderer Parsergeneratoren werden bisweilen die Alternativen einer Syntaxregel so aufgezählt, dass ihnen jeweils der Name der Produktion und das Definitionszeichen vorangestellt wird. Z.B.:
Rule1 ::= A B Rule1 ::= C Rule1
Rule2 ::= D Rule2 ::= Rule1 E
Sollen derartige Regeln in den TextTransformer importiert werden, so bietet sich die Verwendung eines dynamischer Token für die Namen der Regeln an, um die Alternativen in einer Regel zusammenzufassen.
{{ str sScope; }} ID {{ sScope = xState.str(); AddToken( xState.str(), "SAME", sScope ); }} "::=" Expression // GrammarExpression {{ PushScope(sScope); }} ( SAME {{ PopScope(); }} "::=" Expression // GrammarExpression {{ PushScope(sScope); }} )*
void ClearTokens(const str& xsScope)
Mit dieser Funktion werden alle dynamischen Token gelöscht, die für den Textbereich xsScope definiert wurden. Ist xsScope ein leerer String werden alle Token für alle Bereiche entfernt.
Falls Token bestimmten Textbereichen zugeordnet wurden, sollte vor Beendigung eines Programms ClearTokens mit einem leeren String aufgerufen werden, um Speicherlöcher zu vermeiden. |
Diese Seite gehört zur TextTransformer Dokumentation |
Home Inhalt English |