7.1.3.4 Loops

To repeatedly execute an expression, quantify it by ‘*’.

Example

( [ "a" "b" ] . A )* [ "b" "c" ] . .

A parser repeats the execution of ‘[ "a" "b" ] . A’ expression while a look-ahead terminal symbol is "a" and stops repeating the execution if a look-ahead terminal symbol is "c". If a look-ahead terminal symbol is "b", the parser either repeats the execution of that expression or stops repeating the execution.

In the above example, a choice whether to continue or stop repeating expression execution is deterministic on the look-ahead terminal symbol "a" or "c" and nondeterministic on the look-ahead terminal symbol "b".

Note: in a bottom-up template grammar, the parser may choose whether or not to repeat an expression quantified by ‘*’ based on subsequent terminal symbols consumable by the expression or an expression following the quantifier ‘*’.

If an expression is not inside ‘(’ … ‘)’, the quantifier ‘*’ after the expression relates to its last element. For example, in the expression ‘. . A B*’ the quantifier ‘*’ relates only to ‘B’.

Note: if the quantifier ‘*’ follows a sequence of input terminal symbols, terminal symbol placeholders, and terminal symbol classes, a quantified expression is the entire sequence rather than its last element. For example, the notation ‘. . [ "a" "Beta" ]*’ means that the quantified expression is ‘. . [ "a" "Beta" ]’. To relate ‘*’ only to [ "a" "Beta" ], use the notation ‘. . ([ "a" "Beta" ]*)’ or ‘. . ([ "a" "Beta" ])*’.

As a result of iterative determinization, a parser removes terminal symbols from overlapping terminal symbol classes defining the FIRST set of an expression quantified by ‘*’ and the FIRST set of an expression after the quantifier ‘*’ but preserves a set of terminal symbols in the union of the two FIRST sets.

A parser can determinize the expression from the above example in the following ways:

( [ "a" "b" ] . A )* "c" . .

or

( "a" . A )* [ "b" "c" ] . .

On nondeterministic choice between repeating the execution of an expression and stopping the execution, a parser selects one of the two alternatives with profile probability 0.5. Use a notation

[Probability]

at the beginning of an expression quantified by ‘*’ to specify a custom profile probability of repeating the execution. The probability of stopping the execution is equal to 1-Probability.

Example

( [0.25] [ "a" "b" ] . A )* [ "b" "c" ] . .

On the look-ahead terminal symbol "b", a parser executes the expression ‘[ "a" "b" ] . A’ with profile probability 0.25 or executes the expression ‘[ "b" "c" ] . .’ with profile probability 0.75.

Note: using a custom profile probability of repeating the execution of an expression quantified by ‘*’ requires calling a parser with the option --profile-tol=FLOAT where FLOAT is small enough; otherwise, specifying the custom profile probability will not have any effect.