6.3. Parser shortcuts

The Felix parser system actually accepts so-called meta-grammars.

You can have an anonymous sequence of symbols or set of alternatives, simply by enclosing them in parentheses. The implementation declares a dummy nonterminal for such groups, and replaces the group with the name of the dummy non-terminal.

You can also apply the postfix operators "*", "+" and "?" to any symbol or group. Curly brackets "{" .. "}" can also be used and are equivalent to ( .. ) *. Note you can't use [..] notation for optional constructions, since this conflicts with the use of [] for type subscripts.

Note: although it makes sense at present anonymous nonterminal specifications can't contain names or client code.

Note: restriction: at present each dummy is distinct, so any anonymous expression occuring more than once will lead to a reduce/reduce conflict.

Note: restriction: all the anonymous symbols must have attributes.

Start C++ section to tut/examples/tut312.flx[1 /1 ]
     1: include "std";
     2: 
     3: // the input string
     4: data := "1+22+33$";
     5: 
     6: // a type for tokens
     7: union token_t =
     8:   | TOK_EOF
     9:   | TOK_PLUS
    10:   | TOK_INT of int
    11: ;
    12: 
    13: // a token stream generator
    14: var i = 0;
    15: fun get_token():token_t =
    16: {
    17:   ch := data.[i to i+1];
    18:   ++i;
    19:   tok :=
    20:     match ch with
    21:     | "$" => TOK_EOF
    22:     | "+" => TOK_PLUS
    23:     | "1" => TOK_INT 1
    24:     | "2" => TOK_INT 2
    25:     | "3" => TOK_INT 3
    26:     endmatch
    27:   ;
    28:   return tok;
    29: }
    30: 
    31: // a type for expression terms
    32: union expr_t =
    33:   | Integer of int
    34: ;
    35: 
    36: // a grammar for expressions
    37: nonterm expr : expr_t =
    38: | xx:expr TOK_PLUS y:TOK_INT+ =>
    39:   match xx with
    40:   | Integer ?i => let case 2 (?j,_) = y in Integer (i+j)
    41:   endmatch
    42: 
    43: | y:TOK_INT => Integer y
    44: ;
    45: 
    46: // a parser for our example
    47: var z : 1 + int =
    48:   parse (the get_token) with
    49:   | e: expr => match e with | Integer ?i => i endmatch
    50:   endmatch
    51: ;
    52: 
    53: // print the result
    54: match z with
    55: | case 1 => { print "Error"; }
    56: | case 2 (?i) => { print i; }
    57: endmatch;
    58: endl;
    59: 
End C++ section to tut/examples/tut312.flx[1]