libcas - Grammar File (for YACC/bison)
/*
(C) Christoph Lehner 2012
*/
%skeleton "lalr1.cc"
%define namespace "cas"
%define parser_class_name "InputGrammar"
%code requires {
#include "libcas.hh"
namespace cas { class Input; }
}
%union {
char *s;
int i;
Expression* e;
Arguments* a;
}
%code {
#define yylex(v,l,i) i->lex(v,l)
}
%locations
%parse-param { cas::Input* input }
%lex-param { cas::Input* input }
%token END 0 "end of input"
%token INVALID "invalid token"
%token <i> INTEGER "integer"
%token <s> NAME "name"
%type <e> exp
%type <a> arglist
%left '+'
%left '-'
%left '*'
%left '/'
%left NEG POS
%right '^'
%destructor { } <i>
%destructor { delete $$; } <*>
%%
input:
exp { input->e = $1; }
;
exp:
INTEGER { $$ = new Integer($1); }
| NAME { $$ = new Symbol($1); }
| NAME '(' arglist ')' { $$ = new Function($1,$3); }
| NAME '(' ')' { $$ = new Function($1,0); }
| exp '+' exp { Arguments* a = new Arguments(); a->add($1); a->add($3); $$ = new Operator('+',a); }
| exp '-' exp { Arguments* a = new Arguments(); a->add($1); a->add($3); $$ = new Operator('-',a); }
| exp '*' exp { Arguments* a = new Arguments(); a->add($1); a->add($3); $$ = new Operator('*',a); }
| exp '/' exp { Arguments* a = new Arguments(); a->add($1); a->add($3); $$ = new Operator('/',a); }
| '-' exp %prec NEG { if ($2->getType()==Expression::INTEGER) { ((Integer*)$2)->i *= -1; $$ = $2; } else { Arguments* a = new Arguments(); a->add($2); $$ = new Operator('-',a); } }
| '+' exp %prec POS { $$ = $2; }
| exp '^' exp { Arguments* a = new Arguments(); a->add($1); a->add($3); $$ = new Operator('^',a); }
| '(' exp ')' { $$ = $2; }
;
arglist:
exp { Arguments* a = new Arguments(); a->add($1); $$ = a; }
| arglist ',' exp { $1->add($3); $$ = $1; }
;
%%