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