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