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