%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 // Get name of initial parsed file %initial-action {@$.filename=confget_extra(scanner)->state.curdir+confget_extra(scanner)->state.filename;} %{ #include #include #include "parser.h" #include "../debug.h" #include "../object.h" #include "../globals.h" // We can't include lexical.h before grammatical.h, because of strange errors, but grammatical.h only needs definition of yyscan_t #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif #include "grammatical.h" #include "lexical.h" inline void conferror(const YYLTYPE* locp, yyscan_t sc, const char* str) { COUT(ERROR)<filename; if(locp->first_line==locp->last_line) COUT(ERROR)<<" at line "<last_line<<", from position "<first_column<<" to "<last_column<first_line<<", position "<first_column<<" to line "<last_line<<", position "<last_column< REAL %token BOOL %token INTEGER %token NAME %token IDENTIFIER %token STRING %left DELIM %precedence ASSIGN %precedence IDENTIFIER /* low-priority for just identifier */ %left '-' '+' %left '*' '/' %precedence UNARY /* negation--unary minus */ %right '^' /* exponentiation */ %left '.' %precedence OBRACE CBRACE %type longidentifier %type expression %type object %type pair %type list %destructor {} REAL INTEGER BOOL %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($3); if(*$1=="save") G_tosave.push_back(ol); else if(*$1=="print") G_toprint.push_back(ol); else { conferror(@1,scanner,"unknown statement "+(*$1)); 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 { conferror(@1,scanner,"unknown statement "+(*$1)); 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($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 %prec ASSIGN {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;} ; 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;} | 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 {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;} ;