/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright (C) 2001       Gerwin Klein <lsf@jflex.de>                    *
 * Copyright (C) 2001       Bernhard Rumpe <rumpe@in.tum.de>               *
 * All rights reserved.                                                    *
 *                                                                         *
 * License: BSD                                                            *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


// definition of tokens, if applicable with token type 
terminal INPUT, FUNCTIONS, OUTPUT, END, ARGUMENTS;
terminal IF, THEN, ELSE, FI, ERROR;
terminal COMMA, LPAR, RPAR;
terminal EQ, LE, LEQ, MINUS, PLUS, TIMES, DIV, UMINUS;

terminal String ID, NUMBER;

non terminal Tprogram  program;
non terminal Tparlist  parlist;
non terminal Texplist  explist;
non terminal Tdekllist dekllist;
non terminal Tdekl     dekl;
non terminal Texp      exp;
non terminal Tboolexp  boolexp;
non terminal Tident    ident;
non terminal Tnumber   number;


// precedences, left associativity
precedence left EQ, LE, LEQ;
precedence left MINUS, PLUS;
precedence left TIMES, DIV;
precedence left UMINUS;


// here the rules start 
program       ::= INPUT parlist:p FUNCTIONS dekllist:d OUTPUT explist:o
                                        ARGUMENTS explist:a END
                  {: RESULT = new Tprogram(p,d,o,a); :}
                ;

parlist       ::= ident:i
                  {: RESULT = new Tparlist(i); :}
                | parlist:p COMMA ident:i
                  {: RESULT = new Tparlist(p,i); :}
                ;

explist       ::= exp:e
                  {: RESULT = new Texplist(e); :}
                | explist:l COMMA exp:e
                  {: RESULT = new Texplist(l,e); :}
                ;

dekllist      ::= dekl:d
                  {: RESULT = new Tdekllist(d);:}
                | dekllist:l COMMA dekl:d
                  {: RESULT = new Tdekllist(l,d); :}
                ;

dekl          ::= ident:i LPAR parlist:p RPAR EQ exp:e
                  {: RESULT = new Tdekl(i,p,e); :}
                ;

exp           ::= number:n
                  {: RESULT = n; :}
                | ident:i
                  {: RESULT = i; :}
                | ident:i LPAR explist:e RPAR
                  {: RESULT = new Tfun(i,e); :}
                | LPAR exp:e RPAR
                  {: RESULT = e; :}
                | MINUS exp:e                
                  {: RESULT = new Tuminus(e); :} %prec UMINUS
                | exp:l PLUS exp:r
                  {: RESULT = new Texpinfix(l,'+',r); :}
                | exp:l TIMES exp:r
                  {: RESULT = new Texpinfix(l,'*',r); :}
                | exp:l DIV exp:r
                  {: RESULT = new Texpinfix(l,'/',r); :}
                | exp:l MINUS exp:r
                  {: RESULT = new Texpinfix(l,'-',r); :}
                | IF boolexp:b THEN exp:t ELSE exp:e FI
                  {: RESULT = new Tifthenelse(b,t,e); :}
                ;

boolexp       ::= exp:l EQ exp:r
                  {: RESULT = new Tboolexp(l,'=',r); :}
                | exp:l LE exp:r
                  {: RESULT = new Tboolexp(l,'<',r); :}
                | exp:l LEQ exp:r
                  {: RESULT = new Tboolexp(l,'!',r); :}
                ;

ident         ::= ID:n
                  {: RESULT = new Tident(n); :}
                ;

number        ::= NUMBER:z
                  {: RESULT = new Tnumber(z); :}
                ;
