IF...ELSE...END |
Top Previous Next |
Scripts > Productions > IF...ELSE...END
Alternatives, which would produce a LL (1) conflict in another place, are allowed in an IF...ELSE...END structure. The progress of parsing isn't only determined by the next token here but is controlled by predicates too; e.g. a look-ahead in the current text (see remark below).
This structure has more exactly the form:
IF( boolean expression ) if-branch ELSE else-branch END
The IF-branch and the ELSE-branch are arbitrary concatenations or groupings of tokens and semantic actions. The ELSE branch is optional. So a simple IF expression is possible too:
IF( boolean expression ) if-branch END
The boolsche expression only is evaluated, if the expected tokens is in the first set of the IF-branch. If the IF-branch cannot start with the next token, the ELSE-branch is executed, independently of whether the IF-condition is correct or not. If there is noe ELSE-branch, the structure is nullable.
The boolean expression always is interpretable and exportable.
Examples:
The simple structure can be used e.g. to resolve the conflict in the following rules:
Declaration ::= Type ( IdentEqual )? QualIdent ";" IdentEqual ::= Ident "=" QualIdent ::= Ident ( "." Ident )*
// e.g: "int i = xState.itg;" oder "int i;"
Here is a LL(1) conflict, as both IdentEqual and QualIdent are beginning with Ident. It can be resolved either by factoring out of Ident:
Declaration ::= Type Ident ( ( "." Ident )* | "=" QualIdent ) ";"
or you can write a look-ahead production, using IdentEqual:
Declaration ::= Type IF ( IdentEqual() ) IdentEqual END QualIdent ";"
There are LL(1) conflicts too, which cannot be resolved so easy or not at all. Then the IF...ELSE...END structure has to be used.
As boolean expression you also can use a class variable:
IF ( m_bProfile ) ( {{ double start = clock_sec(); }} Production {{ out << clock_sec() - start << " s" << endl; }} ) ELSE Production END
1. Remark:
The following structure is an infinite loop, if the condition is wrong:
( IF(Condition) Production END )*
The expected token, which belongs to the first set of Production also belongs to the first set of the loop. Because this token cannot be consumed, the loop is executed again and again.
Instead you should write:
WHILE(Condition) ( Production )*
or
( IF(Condition) Production ELSE BREAK END )*
In this respect the IF-construct of the TextTransformers isn't comparable with the IF-construct Coco/R, where the condition is set before the loop.
2. Remark:
If one of the branches is nullable, the complete structure is regarded as nullable. This can have an unexpected consequence. No matter what the condition yields in the following structure the token 'd' is always recognized, if it is next in the text. Also, if the condition isn't satisfied, no error results, if in this text doesn't follow 'c' but 'd'.
IF ( Condition ) "a"? ELSE "c" END "d"
|
This page belongs to the TextTransformer Documentation |
Home Content German |