%{ #pragma warning(disable:4786) #ifndef STL_INC #define STL_INC #include #include #include #include #include #include #include using namespace std; #endif #include "jbc.h" #include #undef stderr #define stderr parsefp Varlist *tmpvl; Variable *tmpv; void yyerror(char* p); int yylex(); //支援関数 Expression* CreateOP2Expr(Expression* e1,Expression* e2,int op){ Expression* te=new Expression; te->lineno=e1->lineno; te->type=op; te->exprtype=T_OP2; te->elist.push_back(e1); te->elist.push_back(e2); return te; } Statement* CreateSubstExpr(Expression* e1,Expression* e2,int op){ Statement* ts=new Statement; Expression* te=new Expression; ts->lineno=e1->lineno; ts->stmttype=T_SUBST; ts->exprlist.push_back(e1); *te=*e1; ts->exprlist.push_back(CreateOP2Expr(te,e2,op)); return ts; } %} %union{ struct{ int lineno; union{ int type; Varlist* vl; Expression* expr; Statement* stmt; ExprVec* exprvec; StmtVec* stmtvec; }; }; } //トークン一覧 //値 %token T_ID T_CONST //型関連 %token T_SUB T_FUNCTION %token T_DIM T_AS T_INT T_FLOAT T_STRING T_TYPE T_REDIM %token T_TINT T_TFLOAT T_TSTRING T_VOID T_ERROR //制御関連 %token T_IF T_ELSE T_ELSEIF T_ENDIF T_THEN T_END T_LIST %token T_FOR T_NEXT T_EXIT T_TO T_STEP %token T_DO T_LOOP T_WHILE T_UNTIL %token T_CONTINUE T_RETURN T_CALL T_COMMA //演算子(2項演算子 前にしかつかない演算子(- !) 前にも後ろにもつく演算子(++ --) %token T_OP2 T_OP1p T_OP1 //算術演算(+ - 単項- * / % ++ --) %token T_PLUS T_MINUS T_NEG T_MULT T_DIV T_MOD T_INC T_DEC //シフト(<< >>) %token T_LSHIFT T_RSHIFT //論理演算(| & ^ ! || && ^^ !!) %token T_BITOR T_BITAND T_BITXOR T_BITNOT T_BOOLOR T_BOOLAND T_BOOLXOR T_BOOLNOT //比較演算子(= <> < <= > >=) %token T_EQ T_NE T_LT T_LE T_GT T_GE //演算しつつ代入(代入を示す += -= *= /= %= |= &= ^= <<= >>=) %token T_SUBST T_EQADD T_EQSUB T_EQMUL T_EQDIV T_EQMOD T_EQOR T_EQAND T_EQXOR T_EQLS T_EQRS //カッコ( ( ) [ ] ) %token T_LPAREN T_RPAREN T_LBRACKET T_RBRACKET //式のリスト %token T_STATEMENTS %left T_BOOLOR T_BOOLAND T_BOOLXOR %left T_BITOR T_BITAND T_BITXOR %left T_EQ T_NE T_LT T_LE T_GT T_GE %left T_LSHIFT T_RSHIFT %left T_PLUS T_MINUS %left T_MULT T_DIV T_MOD %left T_NEG %left T_TYPE %type T_CONST T_ID T_INT T_FLOAT T_STRING id %type varlist varlines varline vardef arglist args arg %type type '\n' %type expr expr_op prog const cast_op cast_type %type idbracket step while_state %type idarray idarray2 idparen %type statements %type statement call_state subst_state exit_state %type if_state elseif_states elseif_state else_state %type for_state do_state %type T_EXIT T_CONTINUE T_RETURN T_DIM T_TINT T_TFLOAT T_TSTRING %type T_ELSE T_IF T_ELSEIF T_FOR T_DO T_SUB T_FUNCTION T_AS %start prog %% //プログラムの構造 prog : varlist funclist {gVarlist=$1; for(Varlist::iterator it=$1->begin();it!=$1->end();it++) (*it)->local=false;} ; //-------------------------------------------------------------- //変数宣言部 //変数宣言 varlist : varlines { $$=$1; } | {$$=new Varlist();} ; varlines : varlines varline { $$=$1; $1->insert($1->end(),$2->begin(),$2->end()); delete $2; } | varline { $$=$1; } ; //宣言1行分 varline : T_DIM {tmpvl=new Varlist();} vars T_AS type ml { for(Varlist::iterator it=tmpvl->begin();it!=tmpvl->end();it++){ (*it)->type.type=$5; (*it)->lineno=$1; } $$=tmpvl; } /* | error ml { cout << "ERROR LINE [" << $2 << "] - 読み飛ばします\n"; $$=new Varlist();}*/ ; //カンマ区切り vars : vars T_COMMA vardef | vardef ; //配列を含む vardef : T_ID { tmpv=new Variable(); tmpv->name=IDlist[$1->index];} arraylist { tmpvl->push_back(tmpv);} ; arraylist : vararray | vararray2 | ; //[]で指定する配列 vararray : vararray varbracket | varbracket ; varbracket : T_LBRACKET T_INT T_RBRACKET { if($2->ival<0) $2->ival=0; tmpv->type.arraydepth.push_back($2->ival); } | T_LBRACKET T_RBRACKET { tmpv->type.arraydepth.push_back(-1);} ; //()で指定する配列 vararray2 : T_LPAREN varparen T_RPAREN ; varparen : varparen T_COMMA varparen2 | varparen2 ; varparen2 : T_INT { if($1->ival<0) $1->ival=0; tmpv->type.arraydepth.push_back($1->ival); } | { tmpv->type.arraydepth.push_back(-1);} ; //型 type : T_TINT { $$=T_INT;} | T_TFLOAT { $$=T_FLOAT;} | T_TSTRING { $$=T_STRING;} ; //------------------------------------------------ //関数 //関数 funclist : func funclist | ; func : T_SUB T_ID T_LPAREN arglist T_RPAREN ml varlist statements T_END T_SUB ml { gFunc.push_back(new Function()); gFunc.back()->name=IDlist[$2->index]; gFunc.back()->lineno[0]=$1; gFunc.back()->lineno[1]=$10; gFunc.back()->rettype.type=T_VOID; if($4){ gFunc.back()->args=*$4; delete $4; } for(Varlist::iterator it=$7->begin();it!=$7->end();it++) (*it)->local=true; gFunc.back()->vl=*$7; delete $7; gFunc.back()->plist=*$8; delete $8; gFunc.back()->local=true; } | T_FUNCTION T_ID T_LPAREN arglist T_RPAREN T_AS type { tmpv=new Variable(); gFunc.push_back(new Function());} arraylist { gFunc.back()->rettype.arraydepth=tmpv->type.arraydepth; delete tmpv;} ml varlist statements T_END T_FUNCTION ml { gFunc.back()->name=IDlist[$2->index]; gFunc.back()->lineno[0]=$1; gFunc.back()->lineno[1]=$15; gFunc.back()->rettype.type=$7; if($4){ gFunc.back()->args=*$4; delete $4; } for(Varlist::iterator it=$12->begin();it!=$12->end();it++) (*it)->local=true; gFunc.back()->vl=*$12; delete $12; gFunc.back()->plist=*$13; delete $13; } ; //引数一覧 arglist : args { $$=$1;} | { $$=NULL;} ; args : args T_COMMA arg { $$=$1; $$->push_back(*$3->begin()); delete $3;} | arg {$$=$1;} ; arg : T_ID { tmpv=new Variable();} arraylist T_AS type { { Variable *v=new Variable(); v->name=IDlist[$1->index]; v->type.type=$5; v->type.arraydepth=tmpv->type.arraydepth; delete tmpv; $$=new Varlist(); $$->push_back(v); } } ; //------------------------------------------------ //プログラム群 statements : statements statement ml { $$=$1; if($2) $$->push_back($2); } | {$$=new StmtVec();} ; //1行の文 statement : call_state | subst_state | exit_state | if_state | for_state | do_state | error {$$=NULL;} ; //関数呼出 call_state : T_CALL T_ID idarray2{ $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_CALL; $$->exprlist.push_back($2); $$->exprlist.insert($$->exprlist.end(),$3->begin(),$3->end()); delete $3; } | T_CALL T_ID { $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_CALL; $$->exprlist.push_back($2); } | T_REDIM T_ID idarray { $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_REDIM; $$->exprlist.push_back($2); $$->exprlist.insert($$->exprlist.end(),$3->begin(),$3->end()); delete $3; } | T_REDIM T_ID idarray2 { $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_REDIM; $$->exprlist.push_back($2); $$->exprlist.insert($$->exprlist.end(),$3->begin(),$3->end()); delete $3; } ; //代入 subst_state : id T_EQ expr { $$=new Statement; $$->lineno=$1->lineno; $$->stmttype=T_SUBST; $$->exprlist.push_back($1); $$->exprlist.push_back($3); } | id T_EQADD expr { $$=CreateSubstExpr($1,$3,T_PLUS); } | id T_EQSUB expr { $$=CreateSubstExpr($1,$3,T_MINUS);} | id T_EQMUL expr { $$=CreateSubstExpr($1,$3,T_MULT); } | id T_EQDIV expr { $$=CreateSubstExpr($1,$3,T_DIV); } | id T_EQMOD expr { $$=CreateSubstExpr($1,$3,T_MOD); } | id T_EQOR expr { $$=CreateSubstExpr($1,$3,T_BITOR);} | id T_EQAND expr { $$=CreateSubstExpr($1,$3,T_BITAND); } | id T_EQXOR expr { $$=CreateSubstExpr($1,$3,T_BITXOR); } | id T_EQLS expr { $$=CreateSubstExpr($1,$3,T_LSHIFT); } | id T_EQRS expr { $$=CreateSubstExpr($1,$3,T_RSHIFT); } ; exit_state : T_EXIT T_FOR {$$=new Statement; $$->lineno=$1; $$->stmttype=T_EXIT; $$->subtype=T_FOR; } | T_EXIT T_DO {$$=new Statement; $$->lineno=$1; $$->stmttype=T_EXIT; $$->subtype=T_DO; } | T_EXIT T_SUB {$$=new Statement; $$->lineno=$1; $$->stmttype=T_RETURN; } | T_RETURN {$$=new Statement; $$->lineno=$1; $$->stmttype=T_RETURN; } | T_RETURN expr {$$=new Statement; $$->lineno=$1; $$->stmttype=T_RETURN; $$->exprlist.push_back($2);} | T_CONTINUE {$$=new Statement; $$->lineno=$1; $$->stmttype=T_CONTINUE;} | T_EXIT T_FUNCTION expr {$$=new Statement;$$->lineno=$1; $$->stmttype=T_RETURN; $$->exprlist.push_back($3);} ; //IF関連 if_state : T_IF expr T_THEN statement { $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_IF; $$->exprlist.push_back($2); $$->stmtlist.push_back($4); } | T_IF expr T_THEN ml statements elseif_states else_state T_ENDIF { $$=new Statement; $$->lineno=$2->lineno; $$->stmttype=T_IF; $$->exprlist.push_back($2); { Statement *tmp=new Statement; tmp->stmttype=T_LIST; tmp->stmtlist=*$5; $$->stmtlist.push_back(tmp); delete $5; } $$->exprlist.insert($$->exprlist.end(),$6->exprlist.begin(),$6->exprlist.end()); $$->stmtlist.insert($$->stmtlist.end(),$6->stmtlist.begin(),$6->stmtlist.end()); delete $6; if($7) $$->stmtlist.push_back($7); } ; elseif_states : elseif_states elseif_state { $$=$1; $$->exprlist.push_back($2->exprlist.back()); $2->exprlist.clear(); $$->stmtlist.push_back($2); } | { $$=new Statement;} ; elseif_state : T_ELSEIF expr T_THEN ml statements { $$=new Statement; $$->lineno=$1; $$->stmttype=T_LIST; $$->stmtlist=*$5; $$->exprlist.push_back($2); delete $5; } ; else_state : T_ELSE ml statements { $$=new Statement; $$->lineno=$1; $$->stmttype=T_LIST; $$->stmtlist=*$3; delete $3; } | {$$=NULL;} ; //for next関連 for_state : T_FOR T_ID T_EQ expr T_TO expr step ml statements T_NEXT { $$=new Statement; $$->lineno=$1; $$->stmttype=T_FOR; $$->exprlist.push_back($2); $$->exprlist.push_back($4); $$->exprlist.push_back($6); if($7) $$->exprlist.push_back($7); $$->stmtlist=*$9; delete $9; } ; step : T_STEP expr { $$=$2;} | { $$=NULL;} ; //do loop関連 do_state : T_DO while_state ml statements T_LOOP while_state { $$=new Statement; $$->lineno=$1; $$->stmttype=T_DO; $$->exprlist.push_back($2); $$->exprlist.push_back($6); $$->stmtlist=*$4; delete $4; } ; while_state : T_WHILE expr { $$=$2; $$->index=T_WHILE;} | T_UNTIL expr { $$=$2; $$->index=T_UNTIL;} | { $$=new Expression; $$->index=T_WHILE; $$->type=T_INT; $$->exprtype=T_CONST; $$->ival=1; } ; //------------------------------------------------------- //式 expr : id | const | T_LPAREN expr T_RPAREN { $$=$2;} | expr_op | cast_op ; const : T_INT | T_FLOAT | T_STRING ; id : T_ID idarray { $$=$1; $$->elist=*$2; delete $2;} | T_ID idarray2 { $$=$1; $$->elist=*$2; delete $2;} | T_ID ; //[]で指定する配列 idarray : idarray idbracket {$$=$1; $$->push_back($2);} | idbracket {$$=new ExprVec(); $$->push_back($1);} ; idbracket : T_LBRACKET expr T_RBRACKET { $$=$2; } ; //()で指定する配列(関数呼出もこれ) idarray2 : T_LPAREN idparen T_RPAREN {$$=$2;} | T_LPAREN T_RPAREN {$$=new ExprVec();} ; idparen : idparen T_COMMA expr {$$=$1; $$->push_back($3);} | expr {$$=new ExprVec(); $$->push_back($1);} ; //項演算 expr_op : expr T_PLUS expr {$$=CreateOP2Expr($1,$3,T_PLUS);} | expr T_MINUS expr {$$=CreateOP2Expr($1,$3,T_MINUS);} | expr T_MULT expr {$$=CreateOP2Expr($1,$3,T_MULT);} | expr T_DIV expr {$$=CreateOP2Expr($1,$3,T_DIV);} | expr T_MOD expr {$$=CreateOP2Expr($1,$3,T_MOD);} | expr T_LSHIFT expr {$$=CreateOP2Expr($1,$3,T_LSHIFT);} | expr T_RSHIFT expr {$$=CreateOP2Expr($1,$3,T_RSHIFT);} | expr T_BITOR expr {$$=CreateOP2Expr($1,$3,T_BITOR);} | expr T_BITAND expr {$$=CreateOP2Expr($1,$3,T_BITAND);} | expr T_BITXOR expr {$$=CreateOP2Expr($1,$3,T_BITXOR);} | expr T_BOOLOR expr {$$=CreateOP2Expr($1,$3,T_BOOLOR);} | expr T_BOOLAND expr {$$=CreateOP2Expr($1,$3,T_BOOLAND);} | expr T_BOOLXOR expr {$$=CreateOP2Expr($1,$3,T_BOOLXOR);} | expr T_EQ expr {$$=CreateOP2Expr($1,$3,T_EQ);} | expr T_NE expr {$$=CreateOP2Expr($1,$3,T_NE);} | expr T_LT expr {$$=CreateOP2Expr($1,$3,T_LT);} | expr T_LE expr {$$=CreateOP2Expr($1,$3,T_LE);} | expr T_GT expr {$$=CreateOP2Expr($1,$3,T_GT);} | expr T_GE expr {$$=CreateOP2Expr($1,$3,T_GE);} | T_MINUS expr %prec T_NEG { $$=new Expression; $$->lineno=$2->lineno; $$->type=T_NEG; $$->exprtype=T_OP1; $$->elist.push_back($2); } | T_BITNOT expr %prec T_NEG { $$=new Expression; $$->lineno=$2->lineno; $$->type=T_BITNOT; $$->exprtype=T_OP1; $$->elist.push_back($2); } | T_BOOLNOT expr %prec T_NEG { $$=new Expression; $$->lineno=$2->lineno; $$->type=T_BOOLNOT; $$->exprtype=T_OP1; $$->elist.push_back($2); } ; cast_op : T_LPAREN cast_type T_RPAREN expr %prec T_TYPE { $$=$2; $$->elist.push_back($4); } | cast_type T_LPAREN expr T_RPAREN %prec T_TYPE { $$=$1; $$->elist.push_back($3); } ; cast_type : T_TINT { $$=new Expression; $$->lineno=$1; $$->type=T_INT; $$->exprtype=T_TYPE; } | T_TFLOAT { $$=new Expression; $$->lineno=$1; $$->type=T_FLOAT; $$->exprtype=T_TYPE; } | T_TSTRING { $$=new Expression; $$->lineno=$1; $$->type=T_STRING; $$->exprtype=T_TYPE; } ; ml : ml '\n' | '\n' ; %%