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