📄 gram.y
字号:
n->n_initializer = (Pexpr)n->tp; n->tp = 0; $$ = n; } ;oper : PLUS | MINUS | MUL | AND | OR | ER | SHIFTOP | EQUOP | DIVOP | RELOP | ANDAND | OROR | LP RP { $$ = CALL; } | LB RB { $$ = DEREF; } | NOT | COMPL | ICOP | ASOP | ASSIGN | NEW { $$ = NEW; } | DELETE { $$ = DELETE; } ;tn_list : TNAME DOT | TNAME MEM | tn_list TNAME DOT { error("CNs do not nest"); } | tn_list ID DOT { error("CNs do not nest"); } ;decl : decl arg_list { Freturns($2) = Ntype($1); Ntype($1) = (Ptype)$2; } | TNAME arg_list { Pname n = (Pname)$1; $$ = Ncopy(n); if (ccl && strcmp(n->string,ccl->string)) Nhide(n); $<pn>$->n_oper = TNAME; Freturns($2) = Ntype($$); Ntype($$) = (Ptype)$2; } | decl LP elist RP /* may be class object initializer, class object vector initializer, if not elist will be a CM or an ID */ { TOK k = 1; Pname l = $<pn>3; if (fct_void && l==0) k = 0; Ntype($1) = fctN(Ntype($1),l,k); } | TNAME LP elist RP { TOK k = 1; Pname l = $<pn>3; if (fct_void && l==0) k = 0; $$ = Ncopy($1); $<pn>$->n_oper = TNAME; Ntype($$) = fctN(0,l,k); } | fname | ID DOT fname { $$ = Ncopy($3); $<pn>$->n_qualifier = $1; } | tn_list fname { $$ = $2; set_scope($<pn>1); $<pn>$->n_qualifier = $<pn>1; } | tn_list TNAME { $$ = Ncopy($2); set_scope($<pn>1); $<pn>$->n_oper = TNAME; $<pn>$->n_qualifier = $<pn>1; } | ptr decl %prec MUL { Ptyp($1) = Ntype($2); Ntype($2) = (Ptype)$1; $$ = $2; } | ptr TNAME %prec MUL { $$ = Ncopy($2); $<pn>$->n_oper = TNAME; Nhide($2); Ntype($$) = (Ptype)$1; } | TNAME vec %prec LB { $$ = Ncopy($1); $<pn>$->n_oper = TNAME; Nhide($1); Ntype($$) = (Ptype)$2; } | decl vec %prec LB { Vtype($2) = Ntype($1); Ntype($1) = (Ptype)$2; } | LP decl RP arg_list { Freturns($4) = Ntype($2); Ntype($2) = (Ptype)$4; $$ = $2; } | LP decl RP vec { Vtype($4) = Ntype($2); Ntype($2) = (Ptype)$4; $$ = $2; } ;arg_decl : ID { $$ = $<pn>1; } | %prec NO_ID { $$ = new name; } | ptr arg_decl %prec MUL { Ptyp($1) = Ntype($2); Ntype($2) = (Ptype)$1; $$ = $2; } | arg_decl vec %prec LB { Vtype($2) = Ntype($1); Ntype($1) = (Ptype)$2; } | LP arg_decl RP arg_list { Freturns($4) = Ntype($2); Ntype($2) = (Ptype)$4; $$ = $2; } | LP arg_decl RP vec { Vtype($4) = Ntype($2); Ntype($2) = (Ptype)$4; $$ = $2; } ;new_decl : %prec NO_ID { $$ = new name; } | ptr new_decl %prec MUL { Ptyp($1) = Ntype($2); Ntype($2) = (Ptype)$1; $$ = $2; } | new_decl vec %prec LB { Vtype($2) = Ntype($1); Ntype($1) = (Ptype)$2; } ;cast_decl : %prec NO_ID { $$ = new name; } | ptr cast_decl %prec MUL { Ptyp($1) = Ntype($2); Ntype($2) = (Ptype)$1; $$ = $2; } | cast_decl vec %prec LB { Vtype($2) = Ntype($1); Ntype($1) = (Ptype)$2; } | LP cast_decl RP arg_list { Freturns($4) = Ntype($2); Ntype($2) = $<pt>4; $$ = $2; } | LP cast_decl RP vec { Vtype($4) = Ntype($2); Ntype($2) = $<pt>4; $$ = $2; } ;c_decl : %prec NO_ID { $$ = new name; } | ptr c_decl %prec MUL { Ptyp($1) = Ntype($2); Ntype($2) = (Ptype)$1; $$ = $2; } ;/***************** statements: returns Pstmt *****************/stmt_list : stmt_list statement { if ($2) if ($1) Sadd($1,$2); else { $$ = slistN($2); stmt_seen = 1; } } | statement { if ($1) { $$ = slistN($1); stmt_seen = 1; } } ;condition : LP e RP { $$ = $2; if ($<pe>$ == dummy) error("empty condition"); stmt_seen = 1; } ;block : LC { cd_vec[cdi] = cd; stmt_vec[cdi] = stmt_seen; tn_vec[cdi++] = modified_tn; cd = 0; stmt_seen = 0; modified_tn = 0; } stmt_list RC { Pname n = Nunlist(cd); Pstmt ss = Sunlist($3); $$ = new block($<l>1,n,ss); if (modified_tn) restore(); cd = cd_vec[--cdi]; stmt_seen = stmt_vec[cdi]; modified_tn = tn_vec[cdi]; if (cdi < 0) error('i',"block level(%d)",cdi); } | LC RC { $$ = new block($<l>1,0,0); } | LC error RC { $$ = new block($<l>1,0,0); } ;simple : e { $$ = new estmt(SM,curloc,$<pe>1,0); } | BREAK { $$ = new stmt(BREAK,$<l>1,0); } | CONTINUE { $$ = new stmt(CONTINUE,$<l>1,0); } | RETURN e { $$ = new estmt(RETURN,$<l>1,$<pe>2,0); } | GOTO ID { $$ = new lstmt(GOTO,$<l>1,$<pn>2,0); } | DO { stmt_seen=1; } statement WHILE condition { $$ = new estmt(DO,$<l>1,$<pe>5,$<ps>3); } ;statement : simple SM | ASM LP STRING RP SM { if (stmt_seen) $$ = new estmt(ASM,curloc,(Pexpr)$<s>3,0); else { Pname n = new name(make_name('A')); n->tp = new basetype(ASM,(Pname)$<s>3); if (cd) Nadd_list(cd,n); else cd=(Pname)nlistN(n); $$ = 0; } } /* | simple { error("';' missing after simpleS"); }*/ | data_dcl { if ($<pn>1) if (stmt_seen) { Pname n = $<pn>1; $$ = new block(n->where,n,0); $<ps>$->base = DCL; } else { if (cd) Nadd_list(cd,$1); else cd = (Pname)nlistN($1); $$ = 0; } } | att_fct_def { Pname n = Pname($1); lex_unget(RC); error(&n->where,"%n's definition is nested (did you forget a ``}''?)",n); if (cd) Nadd_list(cd,$1); else cd = (Pname)nlistN($1); $$ = 0; } | block | IF condition statement { $$ = new ifstmt($<l>1,$<pe>2,$<ps>3,0); } | IF condition statement ELSE statement { $$ = new ifstmt($<l>1,$<pe>2,$<ps>3,$<ps>5); } | WHILE condition statement { $$ = new estmt(WHILE,$<l>1,$<pe>2,$<ps>3); } | FOR LP { stmt_seen=1; } statement e SM e RP statement { $$ = new forstmt($<l>1,$<ps>4,$<pe>5,$<pe>7,$<ps>9); } | SWITCH condition statement { $$ = new estmt(SWITCH,$<l>1,$<pe>2,$<ps>3); } | ID COLON { $$ = $1; stmt_seen=1; } statement { Pname n = $<pn>3; $$ = new lstmt(LABEL,n->where,n,$<ps>4); } | CASE { stmt_seen=1; } e COLON statement { if ($<pe>3 == dummy) error("empty case label"); $$ = new estmt(CASE,$<l>1,$<pe>3,$<ps>5); } | DEFAULT COLON { stmt_seen=1; } statement { $$ = new stmt(DEFAULT,$<l>1,$<ps>4); } ;/********************* expressions: returns Pexpr **************/elist : ex_list { Pexpr e = Eunlist($1); while (e && e->e1==dummy) { if (e->e2) error("EX inEL"); delete e; e = e->e2; } $$ = e; }ex_list : initializer %prec CM { Pexpr e = new expr(ELIST,$<pe>1,0); $$ = (PP)new elist(e); } | ex_list CM initializer { Pexpr e = new expr(ELIST,$<pe>3,0); Eadd($1,e); } ;initializer : e %prec CM | LC elist RC { Pexpr e; if ($2) e = $<pe>2; else e = new expr(ELIST,dummy,0); $$ = new expr(ILIST,e,0); } ;e : e ASSIGN e { binop: $$ = new expr($<t>2,$<pe>1,$<pe>3); } | e PLUS e { goto binop; } | e MINUS e { goto binop; } | e MUL e { goto binop; } | e AND e { goto binop; } | e OR e { goto binop; } | e ER e { goto binop; } | e SHIFTOP e { goto binop; } | e EQUOP e { goto binop; } | e DIVOP e { goto binop; } | e RELOP e { goto binop; } | e ANDAND e { goto binop; } | e OROR e { goto binop; } | e ASOP e { goto binop; } | e CM e { goto binop; } | e QUEST e COLON e { $$ = new qexpr($<pe>1,$<pe>3,$<pe>5); } | DELETE term { $$ = new expr(DELETE,$<pe>2,0); } | DELETE LB e RB term { $$ = new expr(DELETE,$<pe>5,$<pe>3); } | term | %prec NO_EXPR { $$ = dummy; } ;term : TYPE LP elist RP { TOK b = $<t>1; Ptype t; switch (b) { case CHAR: t = char_type; break; case SHORT: t = short_type; break; case INT: t = int_type; break; case LONG: t = long_type; break; case UNSIGNED: t = uint_type; break; case FLOAT: t = float_type; break; case DOUBLE: t = double_type; break; case VOID: t = void_type; break; default: error("illegal constructor:%k",b); t = int_type; } $$ = new texpr(VALUE,t,$<pe>3); } | TNAME LP elist RP { Ptype t = Ntype($1); $$ = new texpr(VALUE,t,$<pe>3); } | NEW new_type { Ptype t = Ntype($2); $$ = new texpr(NEW,t,0); } | NEW LP new_type RP { Ptype t = Ntype($3); $$ = new texpr(NEW,t,0); } | term ICOP { $$ = new expr($<t>2,$<pe>1,0); } | CAST cast_type ENDCAST term %prec ICOP { $$ = new texpr(CAST,Ntype($2),$<pe>4); } | MUL term { $$ = new expr(DEREF,$<pe>2,0); } | AND term { $$ = new expr(ADDROF,0,$<pe>2); } | MINUS term { $$ = new expr(UMINUS,0,$<pe>2); } | PLUS term { $$ = new expr(UPLUS,0,$<pe>2); } | NOT term { $$ = new expr(NOT,0,$<pe>2); } | COMPL term { $$ = new expr(COMPL,0,$<pe>2); } | ICOP term { $$ = new expr($<t>1,0,$<pe>2); } | SIZEOF term { $$ = new texpr(SIZEOF,0,$<pe>2); } | SIZEOF CAST cast_type ENDCAST %prec SIZEOF { $$ = new texpr(SIZEOF,Ntype($3),0); } | term LB e RB { $$ = new expr(DEREF,$<pe>1,$<pe>3); } | term LP elist RP { Pexpr ee = $<pe>3; Pexpr e = $<pe>1; if (e->base == NEW) e->e1 = ee; else $$ = new call(e,ee); } | term REF prim { $$ = new ref(REF,$<pe>1,$<pn>3); } | term REF TNAME { Pname n = Ncopy($3); $$ = new ref(REF,$<pe>1,n); } | term DOT prim { $$ = new ref(DOT,$<pe>1,$<pn>3); } | term DOT TNAME { Pname n = Ncopy($3); $$ = new ref(DOT,$<pe>1,n); } | MEM tag { $$ = Ncopy($2); $<pn>$->n_qualifier = sta_name; } | prim | LP e RP { $$ = $2; } | ZERO { $$ = zero; } | ICON { $$ = conN(ICON,$1); } | FCON { $$ = conN(FCON,$1); } | STRING { $$ = conN(STRING,$1); } | CCON { $$ = conN(CCON,$1); } | THIS { $$ = conN(THIS,0); }/* | %prec NO_EXPR { $$ = dummy; }*/ ;prim : ID { $$ = $<pn>1; } | TNAME MEM tag { $$ = Ncopy($3); $<pn>$->n_qualifier = $<pn>1; } | ID MEM tag { $$ = Ncopy($3); Pname nx = ktbl->look($<pn>1->string,HIDDEN); if (nx == 0) error("non-typeN%n before ::",$$); $<pn>$->n_qualifier = nx; } | OPERATOR oper { $$ = new name(oper_name($2)); $<pn>$->n_oper = $<t>2; } | TNAME MEM OPERATOR oper { $$ = new name(oper_name($4)); $<pn>$->n_oper = $<t>4; $<pn>$->n_qualifier = $<pn>1; } | ID MEM OPERATOR oper { $$ = new name(oper_name($4)); $<pn>$->n_oper = $<t>4; Pname nx = ktbl->look($<pn>1->string,HIDDEN); if (nx == 0) error("non-typeN%n before ::",$$); $<pn>$->n_qualifier = nx; } | OPERATOR c_type { Pname n = $<pn>2; static char buf[128]; buf[0] = '_'; buf[1] = 'O'; n->tp->signature(buf+2); n->string = buf; n->tp = 0; $$ = n; } | TNAME MEM OPERATOR c_type { Pname n = $<pn>4; static char buf[128]; buf[0] = '_'; buf[1] = 'O'; n->tp->signature(buf+2); n->string = buf; n->tp = 0; n->n_qualifier = $<pn>1; $$ = n; } | ID MEM OPERATOR c_type { Pname n = $<pn>4; static char buf[128]; buf[0] = '_'; buf[1] = 'O'; n->tp->signature(buf+2); n->string = buf; n->tp = 0; Pname nx = ktbl->look($<pn>1->string,HIDDEN); if (nx == 0) error("non-typeN%n before ::",$$); n->n_qualifier = nx; $$ = n; } ;/****************** abstract types (return type Pname) *************/cast_type : type cast_decl { $$ = Ncast($1,$2); } ;c_tp : TYPE { $$ = new basetype($<t>1,0); } | TNAME { $$ = new basetype(TYPE,$<pn>1); } ;c_type : c_tp c_decl { $$ = Ncast($1,$2); } ;new_type : type new_decl { $$ = Ncast($1,$2); } ;arg_type : type arg_decl { $$ = Ndata($1,$2); } | type arg_decl ASSIGN initializer { $$ = Ndata($1,$2); $<pn>$->n_initializer = $<pe>4; } ;arg_list : LP arg_type_list RP { TOK k = 1; Pname l = $<pn>2; // if (fct_void && l==0) k = 0; $$ = fctN(0,Nunlist(l),k); } | LP arg_type_list ELLIPSIS RP { TOK k = ELLIPSIS; Pname l = $<pn>2; // if (fct_void && l==0) k = 0; $$ = fctN(0,Nunlist(l),k); } | LP arg_type_list CM ELLIPSIS RP { TOK k = ELLIPSIS; Pname l = $<pn>2; // if (fct_void && l==0) k = 0; $$ = fctN(0,Nunlist(l),k); } ;arg_type_list : arg_type_list CM at { if ($3) if ($1) Nadd($1,$3); else { error("AD syntax"); $$ = nlistN($3); } else error("AD syntax"); } | at %prec CM { if ($1) $$ = nlistN($1); } ;at : arg_type | %prec EMPTY { $$ = 0; }ptr : MUL %prec NO_ID { $$ = new ptr(PTR,0); } | AND %prec NO_ID { $$ = new ptr(RPTR,0); } | MUL TYPE { TOK c = $<t>2; if (c == CONST) $$ = new ptr(PTR,0,1); else { $$ = new ptr(PTR,0); error("syntax error: *%k",c); } } | AND TYPE { TOK c = $<t>2; if (c == CONST) $$ = new ptr(RPTR,0,1); else { $$ = new ptr(RPTR,0); error("syntax error: &%k",c); } } ;vec : LB e RB { Pexpr d = $<pe>2; $$ = vecN( (d!=dummy)?d:0 ); } ;%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -