|
|
|
%language "c"
|
|
|
|
%output "grammatical.cpp"
|
|
|
|
%defines "grammatical.h"
|
|
|
|
%param {yyscan_t scanner}
|
|
|
|
%define api.prefix {conf}
|
|
|
|
%define api.pure full
|
|
|
|
%define lr.type ielr
|
|
|
|
%define parse.lac full
|
|
|
|
%define parse.error verbose
|
|
|
|
//%define parse.trace
|
|
|
|
%locations
|
|
|
|
//%no-lines
|
|
|
|
|
|
|
|
%{
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "parser.h"
|
|
|
|
#include "../debug.h"
|
|
|
|
#include "../object.h"
|
|
|
|
#include "../globals.h"
|
|
|
|
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
|
|
|
#define YY_TYPEDEF_YY_SCANNER_T
|
|
|
|
typedef void* yyscan_t;
|
|
|
|
#endif
|
|
|
|
#include "yyloc.h"
|
|
|
|
#include "grammatical.h"
|
|
|
|
inline void conferror(YYLTYPE *locp, yyscan_t sc, const char * str)
|
|
|
|
{
|
|
|
|
COUT(ERROR)<<std::endl<<" Grammatical parser: "<<str<<std::endl;
|
|
|
|
}
|
|
|
|
#include "lexical.h"
|
|
|
|
%}
|
|
|
|
|
|
|
|
%union
|
|
|
|
{
|
|
|
|
bool b;
|
|
|
|
int64_t i;
|
|
|
|
double r;
|
|
|
|
std::string* str;
|
|
|
|
ObjectBase* ob;
|
|
|
|
}
|
|
|
|
|
|
|
|
%token ASSIGN OBRACE CBRACE ENDL DELIM
|
|
|
|
|
|
|
|
%token <r> REAL
|
|
|
|
%token <b> BOOL
|
|
|
|
%token <i> INTEGER
|
|
|
|
%token <str> NAME
|
|
|
|
%token <str> IDENTIFIER
|
|
|
|
%token <str> STRING
|
|
|
|
|
|
|
|
%left '-' '+'
|
|
|
|
%left '*' '/'
|
|
|
|
%precedence UNARY /* negation--unary minus */
|
|
|
|
%right '^' /* exponentiation */
|
|
|
|
%left '.'
|
|
|
|
|
|
|
|
%type <ob> longidentifier
|
|
|
|
%type <ob> expression
|
|
|
|
%type <ob> call
|
|
|
|
%type <ob> object
|
|
|
|
%type <ob> pair
|
|
|
|
%type <ob> list
|
|
|
|
|
|
|
|
%destructor {} REAL INTEGER BOOL STRING
|
|
|
|
%destructor {delete $$;} <*>
|
|
|
|
|
|
|
|
%%
|
|
|
|
input:
|
|
|
|
%empty {COUT(DEBUG)<<"Empty input\n";}
|
|
|
|
| input line {COUT(DEBUG)<<" input line\n";}
|
|
|
|
;
|
|
|
|
|
|
|
|
line:
|
|
|
|
NAME ASSIGN object ENDL {COUT(DEBUG)<<" NAME ASSIGN object ENDL\n"; if(G_vars.count(*$1)!=0) delete G_vars[*$1]; G_vars[*$1]=$3; delete $1;}
|
|
|
|
| NAME ASSIGN list ENDL {COUT(DEBUG)<<" NAME ASSIGN list ENDL\n"; if(G_vars.count(*$1)!=0) delete G_vars[*$1]; G_vars[*$1]=$3; delete $1;}
|
|
|
|
| NAME OBRACE list CBRACE ENDL {COUT(DEBUG)<<" NAME OBRACE list CBRACE ENDL\n";
|
|
|
|
transform($1->begin(),$1->end(),$1->begin(),::tolower);
|
|
|
|
ObjectList* ol=dynamic_cast<ObjectList*>($3);
|
|
|
|
if(*$1=="save") G_tosave.push_back(ol);
|
|
|
|
else if(*$1=="print") G_toprint.push_back(ol);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
COUT(ERROR)<<std::endl<<"Unknown statement "<<(*$1)<<std::endl;
|
|
|
|
delete ol;
|
|
|
|
delete $1;
|
|
|
|
YYABORT;
|
|
|
|
}
|
|
|
|
delete $1;}
|
|
|
|
| NAME OBRACE object CBRACE ENDL {COUT(DEBUG)<<" NAME OBRACE object CBRACE ENDL\n";
|
|
|
|
transform($1->begin(),$1->end(),$1->begin(),::tolower);
|
|
|
|
ObjectList* ol=new ObjectList($3);
|
|
|
|
if(*$1=="save") G_tosave.push_back(ol);
|
|
|
|
else if(*$1=="print") G_toprint.push_back(ol);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
COUT(ERROR)<<std::endl<<"Unknown statement "<<(*$1)<<std::endl;
|
|
|
|
delete ol;
|
|
|
|
delete $1;
|
|
|
|
YYABORT;
|
|
|
|
}
|
|
|
|
delete $1;}
|
|
|
|
;
|
|
|
|
|
|
|
|
list:
|
|
|
|
object object {COUT(DEBUG)<<" object object\n"; $$=(new ObjectList($1))->PushBack($2);}
|
|
|
|
| list object {COUT(DEBUG)<<" list object\n"; dynamic_cast<ObjectList*>($1)->PushBack($2); $$=$1;}
|
|
|
|
;
|
|
|
|
|
|
|
|
pair:
|
|
|
|
IDENTIFIER ASSIGN object {COUT(DEBUG)<<" IDENTIFIER ASSIGN object\n"; $$=new ObjectPair($1,$3); delete $1;}
|
|
|
|
;
|
|
|
|
|
|
|
|
object:
|
|
|
|
STRING {COUT(DEBUG)<<" STRING\n"; $$=new ObjectString($1); delete $1;}
|
|
|
|
| BOOL {COUT(DEBUG)<<" BOOL\n"; $$=new ObjectBool($1);}
|
|
|
|
| OBRACE list CBRACE {COUT(DEBUG)<<" OBRACE list CBRACE\n"; $$=$2;}
|
|
|
|
| expression {COUT(DEBUG)<<" expression\n"; $$=$1;}
|
|
|
|
| pair {COUT(DEBUG)<<" pair\n"; $$=$1;}
|
|
|
|
| OBRACE object CBRACE {COUT(DEBUG)<<" OBRACE object CBRACE\n"; $$=$2;}
|
|
|
|
| object DELIM {COUT(DEBUG)<<" OBJECT DELIM\n"; $$=$1;}
|
|
|
|
;
|
|
|
|
|
|
|
|
call:
|
|
|
|
IDENTIFIER OBRACE object CBRACE {COUT(DEBUG)<<" IDENTIFIER OBRACE object CBRACE\n"; $$=new OFunc($1,$3); delete $1;}
|
|
|
|
| IDENTIFIER OBRACE list CBRACE {COUT(DEBUG)<<" IDENTIFIER OBRACE list CBRACE\n"; $$=new OFunc($1,$3); delete $1;}
|
|
|
|
|
|
|
|
|
|
|
|
longidentifier:
|
|
|
|
IDENTIFIER '.' IDENTIFIER {COUT(DEBUG)<<" IDENTIFIER DOT IDENTIFIER\n"; $$=new OFunc("GET",(new ObjectList(new OId($1)))->PushBack(new ObjectString($3))); delete $1; delete $3;}
|
|
|
|
| longidentifier '.' IDENTIFIER {COUT(DEBUG)<<" longidentifier '.' IDENTIFIER\n"; $$=new OFunc("GET",(new ObjectList($1))->PushBack(new ObjectString($3))); delete $3;}
|
|
|
|
|
|
|
|
expression:
|
|
|
|
IDENTIFIER {COUT(DEBUG)<<" IDENTIFIER\n"; $$=new OId($1); delete $1;}
|
|
|
|
| longidentifier {COUT(DEBUG)<<" longidentifier\n"; $$=$1;}
|
|
|
|
| REAL {COUT(DEBUG)<<" REAL\n"; $$=new ObjectReal($1);}
|
|
|
|
| INTEGER {COUT(DEBUG)<<" INTEGER\n"; $$=new ObjectInt($1);}
|
|
|
|
| expression '-' expression {COUT(DEBUG)<<" -\n"; $$=new OFunc("SUB",(new ObjectList($1))->PushBack($3));}
|
|
|
|
| expression '+' expression {COUT(DEBUG)<<" +\n"; $$=new OFunc("ADD",(new ObjectList($1))->PushBack($3));}
|
|
|
|
| expression '/' expression {COUT(DEBUG)<<" /\n"; $$=new OFunc("DIV",(new ObjectList($1))->PushBack($3));}
|
|
|
|
| expression '*' expression {COUT(DEBUG)<<" *\n"; $$=new OFunc("MUL",(new ObjectList($1))->PushBack($3));}
|
|
|
|
| expression '^' expression {COUT(DEBUG)<<" ^\n"; $$=new OFunc("POW",(new ObjectList($1))->PushBack($3));}
|
|
|
|
| '-' expression %prec UNARY {COUT(DEBUG)<<" unary -\n"; $$=new OFunc("NEG",$2);}
|
|
|
|
| '+' expression %prec UNARY {COUT(DEBUG)<<" unary +\n"; $$=new OFunc("POS",$2);}
|
|
|
|
| OBRACE expression CBRACE {COUT(DEBUG)<<" OBRACE expression CBRACE\n"; $$=$2;}
|
|
|
|
| call {COUT(DEBUG)<<" call\n"; $$=$1;}
|
|
|
|
;
|