IF...ELSE...END |
Top Previous Next |
Skripte > Produktionen > IF...ELSE...END
In einer IF...ELSE...END Struktur werden Alternativen zugelassen, die an anderer Stelle einen LL(1)-Konflikt ergeben würden. Der Fortgang des Parsens wird hier nicht nur durch das nächstfolgende Token bestimmt, sondern wird auch über Prädikate gesteuert; z.B. einer Vorausschau im aktuellen Text (s. Anmerkung unten)
Genauer hat diese Struktur die Form:
IF( boolscher Ausdruck ) If-Zweig ELSE Else-Zweig END
IF- und ELSE-Zweig sind hier beliebige Verkettunngen oder Gruppierungen von Token und semantischen Aktionen. Der ELSE-Zweig ist optional, so dass auch eine einfache IF-Abfrage möglich ist:
IF( boolscher Ausdruck ) If-Zweig END
Der boolsche Ausdruck wird nur ausgewertet, wenn eines der Token aus der Anfängermenge des IF-Zweiges erwartet wird. Kann der IF-Zweig nicht mit dem nächsten Token beginnen, wird der ELSE-Zweig ausgeführt, unabhängig davon ob die IF-Bedingung zutrifft oder nicht. Falls es keinen ELSE-Zweig gibt, ist die Struktur löschbar.
Der boolscher Ausdruck ist immer zugleich interpretierbar und exportierbar.
Beispiele:
Diese einfache Struktur kann z.B. verwendet werden, um den Konflikt in den folgenden Regeln aufzulösen:
Declaration ::= Type ( IdentEqual )? QualIdent ";" IdentEqual ::= Ident "=" QualIdent ::= Ident ( "." Ident )*
// z.B.: "int i = xState.itg;" oder "int i;"
Da sowohl IdentEqual als auch QualIdent mit Ident beginnen besteht hier ein LL(1)-Konflikt. Er lässt sich entweder durch Ausklammerung von Ident auflösen:
Declaration ::= Type Ident ( ( "." Ident )* | "=" QualIdent ) ";"
oder es kann mittels der IdentEqual als Vorausschau-Produktion geschrieben werden:
Declaration ::= Type IF ( IdentEqual() ) IdentEqual END QualIdent ";"
Es gibt auch LL(1)-Konflikte, die nicht so einfach oder überhaupt nicht auflösbar sind. Hier muss die IF...ELSE...END Struktur verwendet werden.
Als boolscher Ausdruck kann auch schlicht eine Klassen-Variable dienen.
IF ( m_bProfile ) ( {{ double start = clock_sec(); }} Production {{ out << clock_sec() - start << " s" << endl; }} ) ELSE Production END
1. Anmerkung:
Die folgende Struktur ist unendlichen Schleife, wenn die Bedingung falsch ist.
( IF(Bedingung) Produktion END )*
Das zur Anfängermenge von Produktion gehörende erwartete Token wird während eines Schleifendurchlaufs nicht konsumiert. Da dieses Token auch zur Anfängermenge der Schleife gehört, wird diese immer wieder erneut ausgeführt.
Stattdessen sollte geschrieben werden:
WHILE(Bedingung) Produktion
oder
( IF( Bedingung ) Produktion ELSE BREAK END )*
Das IF-Konstrukt des TextTransformers ist insofern nicht zu vergleichen mit dem IF-Konstrukt von Coco/R, bei dem die Bedingung vor die Schleife gesetzt wird.
2. Anmerkung:
Wenn einer der Zweige löschbar ist, wird die gesamte Struktur als löschbar betrachtet. Das kann eine unerwartete Konsequenz haben. Egal, was in folgender Struktur die Bedingung ergibt, wird immer das Token "d" erkannt, wenn es als nächstes im Text steht. Auch, wenn die Bedingung nicht erfüllt ist, ergibt sich kein Fehler, wenn im Text nicht 'c' sondern 'd' folgt.
IF ( Bedingung ) "a"? ELSE "c" END "d"
|
Diese Seite gehört zur TextTransformer Dokumentation |
Home Inhalt English |