3.3. User Non terminals

Felix syntax extensions are not limited to simple statements. The parser is a general, backtracking RD parser and can handle any LL grammar. The only constraint is that it must be triggered initially by a user defined keyword.

The example below shows how you can define and use auxilliary nonterminal productions, which is necessary to handle lists of things other than statements.

Currently, the user actions must be expressions or statements. The system allows statements in tuples, by converting them to a special kind of expression. This allows the syntax macro processor to handle them uniformly.

Note also that the system is openly recursive: new user defined statements can be nested anywhere. They are also recognized immediately after the preprocessor #statement statement, including in the very next #statement definition.

Start felix section to tut/examples/mac302.flx[1 /1 ]
     1: #line 847 "./lpsrc/flx_tut_macro.pak"
     2: #include <flx.flxh>
     3: #keyword DONE
     4: #keyword THEN
     5: #keyword ELIF
     6: #keyword ELSE
     7: 
     8: #nonterminal elif_clause #
     9:   ELIF expr THEN statements =>#
    10:   (_2,_4)
    11: #
    12: 
    13: #nonterminal elif_clauses #
    14:   elif_clause =>#
    15:   _tuple _1
    16: #
    17: 
    18: #nonterminal elif_clauses #
    19:   elif_clause elif_clauses =>#
    20:   _tuple_cons (_1,_2)
    21: #
    22: 
    23: #nonterminal else_clause #
    24:   ELSE statements =>#
    25:   ((),_2)
    26: #
    27: 
    28: #nonterminal else_clause #
    29:   elif_clauses ELSE statements =>#
    30:   (_1,_3)
    31: #
    32: 
    33: #statement#
    34:   IF expr THEN statements else_clause DONE; =>#
    35:   macro {
    36:     macro val elifs,elsepart = _4;
    37:     macro endoff is new;
    38:     macro next is new;
    39:     if not _1 goto next;
    40:       _3;
    41:     next:>
    42:       macro for val elifcond,elifclause in elifs do
    43:       macro next' is new;
    44:       if not elifcond goto next';
    45:       elifclause;
    46:       goto endoff;
    47:     next':>
    48:       done;
    49:       elsepart;
    50:     endoff:>
    51:   };
    52: #
    53: 
    54: val x = 2;
    55: IF x==1 THEN print 1; print 1; endl;
    56: ELIF x==3 THEN print 3; print 3; endl;
    57: ELIF x==5 THEN print 5; print 5; endl;
    58: ELIF x==7 THEN print 7; print 7; endl;
    59: ELSE print "None"; endl; DONE;
    60: 
    61: 
End felix section to tut/examples/mac302.flx[1]