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.

147 lines
6.6 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
%{
#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 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
{
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:
9 years ago
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;}
;