You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
7.3 KiB
157 lines
7.3 KiB
%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 <inttypes.h> |
|
#include <algorithm> |
|
#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)<<std::endl<<" Grammatical parser: "<<str<<std::endl<<" in file "<<locp->filename; |
|
if(locp->first_line==locp->last_line) COUT(ERROR)<<" at line "<<locp->last_line<<", from position "<<locp->first_column<<" to "<<locp->last_column<<std::endl; |
|
else COUT(ERROR)<<" from line "<<locp->first_line<<", position "<<locp->first_column<<" to line "<<locp->last_line<<", position "<<locp->last_column<<std::endl; |
|
} |
|
inline void conferror(const YYLTYPE& locp, yyscan_t sc, const std::string& str) |
|
{ |
|
conferror(&locp,sc,str.c_str()); |
|
} |
|
%} |
|
|
|
%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 DELIM |
|
%precedence ASSIGN |
|
%precedence IDENTIFIER /* low-priority for just identifier */ |
|
%left '-' '+' |
|
%left '*' '/' |
|
%precedence UNARY /* negation--unary minus */ |
|
%right '^' /* exponentiation */ |
|
%left '.' |
|
%precedence OBRACE CBRACE |
|
|
|
%type <ob> longidentifier |
|
%type <ob> expression |
|
%type <ob> object |
|
%type <ob> pair |
|
%type <ob> 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<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;} |
|
| 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<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 %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;} |
|
;
|
|
|