📄 cc.y
字号:
%{#include "cc.h"%}%union { Node* node; Sym* sym; Type* type; struct { Type* t; char c; } tycl; struct { Type* t1; Type* t2; } tyty; struct { char* s; long l; } sval; long lval; double dval; vlong vval;}%type <sym> ltag%type <lval> gctname gcname cname gname tname%type <lval> gctnlist gcnlist zgnlist%type <type> tlist sbody complex%type <tycl> types%type <node> zarglist arglist zcexpr%type <node> name block stmnt cexpr expr xuexpr pexpr%type <node> zelist elist adecl slist uexpr string lstring%type <node> xdecor xdecor2 labels label ulstmnt%type <node> adlist edecor tag qual qlist%type <node> abdecor abdecor1 abdecor2 abdecor3%type <node> zexpr lexpr init ilist forexpr%left ';'%left ','%right '=' LPE LME LMLE LDVE LMDE LRSHE LLSHE LANDE LXORE LORE%right '?' ':'%left LOROR%left LANDAND%left '|'%left '^'%left '&'%left LEQ LNE%left '<' '>' LLE LGE%left LLSH LRSH%left '+' '-'%left '*' '/' '%'%right LMM LPP LMG '.' '[' '('%token <sym> LNAME LTYPE%token <dval> LFCONST LDCONST%token <vval> LCONST LLCONST LUCONST LULCONST LVLCONST LUVLCONST%token <sval> LSTRING LLSTRING%token LAUTO LBREAK LCASE LCHAR LCONTINUE LDEFAULT LDO%token LDOUBLE LELSE LEXTERN LFLOAT LFOR LGOTO%token LIF LINT LLONG LREGISTER LRETURN LSHORT LSIZEOF LUSED%token LSTATIC LSTRUCT LSWITCH LTYPEDEF LTYPESTR LUNION LUNSIGNED%token LWHILE LVOID LENUM LSIGNED LCONSTNT LVOLATILE LSET LSIGNOF%token LRESTRICT LINLINE%%prog:| prog xdecl/* * external declarator */xdecl: zctlist ';' { dodecl(xdecl, lastclass, lasttype, Z); }| zctlist xdlist ';'| zctlist xdecor { lastdcl = T; firstarg = S; dodecl(xdecl, lastclass, lasttype, $2); if(lastdcl == T || lastdcl->etype != TFUNC) { diag($2, "not a function"); lastdcl = types[TFUNC]; } thisfn = lastdcl; markdcl(); firstdcl = dclstack; argmark($2, 0); } pdecl { argmark($2, 1); } block { Node *n; n = revertdcl(); if(n) $6 = new(OLIST, n, $6); if(!debug['a'] && !debug['Z']) codgen($6, $2); }xdlist: xdecor { dodecl(xdecl, lastclass, lasttype, $1); }| xdecor { $1 = dodecl(xdecl, lastclass, lasttype, $1); } '=' init { doinit($1->sym, $1->type, 0L, $4); }| xdlist ',' xdlistxdecor: xdecor2| '*' zgnlist xdecor { $$ = new(OIND, $3, Z); $$->garb = simpleg($2); }xdecor2: tag| '(' xdecor ')' { $$ = $2; }| xdecor2 '(' zarglist ')' { $$ = new(OFUNC, $1, $3); }| xdecor2 '[' zexpr ']' { $$ = new(OARRAY, $1, $3); }/* * automatic declarator */adecl: ctlist ';' { $$ = dodecl(adecl, lastclass, lasttype, Z); }| ctlist adlist ';' { $$ = $2; }adlist: xdecor { dodecl(adecl, lastclass, lasttype, $1); $$ = Z; }| xdecor { $1 = dodecl(adecl, lastclass, lasttype, $1); } '=' init { long w; w = $1->sym->type->width; $$ = doinit($1->sym, $1->type, 0L, $4); $$ = contig($1->sym, $$, w); }| adlist ',' adlist { $$ = $1; if($3 != Z) { $$ = $3; if($1 != Z) $$ = new(OLIST, $1, $3); } }/* * parameter declarator */pdecl:| pdecl ctlist pdlist ';'pdlist: xdecor { dodecl(pdecl, lastclass, lasttype, $1); }| pdlist ',' pdlist/* * structure element declarator */edecl: tlist { lasttype = $1; } zedlist ';'| edecl tlist { lasttype = $2; } zedlist ';'zedlist: /* extension */ { lastfield = 0; edecl(CXXX, lasttype, S); }| edlistedlist: edecor { dodecl(edecl, CXXX, lasttype, $1); }| edlist ',' edlistedecor: xdecor { lastbit = 0; firstbit = 1; }| tag ':' lexpr { $$ = new(OBIT, $1, $3); }| ':' lexpr { $$ = new(OBIT, Z, $2); }/* * abstract declarator */abdecor: { $$ = (Z); }| abdecor1abdecor1: '*' zgnlist { $$ = new(OIND, (Z), Z); $$->garb = simpleg($2); }| '*' zgnlist abdecor1 { $$ = new(OIND, $3, Z); $$->garb = simpleg($2); }| abdecor2abdecor2: abdecor3| abdecor2 '(' zarglist ')' { $$ = new(OFUNC, $1, $3); }| abdecor2 '[' zexpr ']' { $$ = new(OARRAY, $1, $3); }abdecor3: '(' ')' { $$ = new(OFUNC, (Z), Z); }| '[' zexpr ']' { $$ = new(OARRAY, (Z), $2); }| '(' abdecor1 ')' { $$ = $2; }init: expr| '{' ilist '}' { $$ = new(OINIT, invert($2), Z); }qual: '[' lexpr ']' { $$ = new(OARRAY, $2, Z); }| '.' ltag { $$ = new(OELEM, Z, Z); $$->sym = $2; }| qual '='qlist: init ','| qlist init ',' { $$ = new(OLIST, $1, $2); }| qual| qlist qual { $$ = new(OLIST, $1, $2); }ilist: qlist| init| qlist init { $$ = new(OLIST, $1, $2); }zarglist: { $$ = Z; }| arglist { $$ = invert($1); }arglist: name| tlist abdecor { $$ = new(OPROTO, $2, Z); $$->type = $1; }| tlist xdecor { $$ = new(OPROTO, $2, Z); $$->type = $1; }| '.' '.' '.' { $$ = new(ODOTDOT, Z, Z); }| arglist ',' arglist { $$ = new(OLIST, $1, $3); }block: '{' slist '}' { $$ = invert($2); // if($2 != Z) // $$ = new(OLIST, $2, $$); if($$ == Z) $$ = new(OLIST, Z, Z); }slist: { $$ = Z; }| slist adecl { $$ = new(OLIST, $1, $2); }| slist stmnt { $$ = new(OLIST, $1, $2); }labels: label| labels label { $$ = new(OLIST, $1, $2); }label: LCASE expr ':' { $$ = new(OCASE, $2, Z); }| LDEFAULT ':' { $$ = new(OCASE, Z, Z); }| LNAME ':' { $$ = new(OLABEL, dcllabel($1, 1), Z); }stmnt: error ';' { $$ = Z; }| ulstmnt| labels ulstmnt { $$ = new(OLIST, $1, $2); }forexpr: zcexpr| ctlist adlist { $$ = $2; }ulstmnt: zcexpr ';'| { markdcl(); } block { $$ = revertdcl(); if($$) $$ = new(OLIST, $$, $2); else $$ = $2; }| LIF '(' cexpr ')' stmnt { $$ = new(OIF, $3, new(OLIST, $5, Z)); if($5 == Z) warn($3, "empty if body"); }| LIF '(' cexpr ')' stmnt LELSE stmnt { $$ = new(OIF, $3, new(OLIST, $5, $7)); if($5 == Z) warn($3, "empty if body"); if($7 == Z) warn($3, "empty else body"); }| { markdcl(); } LFOR '(' forexpr ';' zcexpr ';' zcexpr ')' stmnt { $$ = revertdcl(); if($$){ if($4) $4 = new(OLIST, $$, $4); else $4 = $$; } $$ = new(OFOR, new(OLIST, $6, new(OLIST, $4, $8)), $10); }| LWHILE '(' cexpr ')' stmnt { $$ = new(OWHILE, $3, $5); }| LDO stmnt LWHILE '(' cexpr ')' ';' { $$ = new(ODWHILE, $5, $2); }| LRETURN zcexpr ';' { $$ = new(ORETURN, $2, Z); $$->type = thisfn->link; }| LSWITCH '(' cexpr ')' stmnt { $$ = new(OCONST, Z, Z); $$->vconst = 0; $$->type = types[TINT]; $3 = new(OSUB, $$, $3); $$ = new(OCONST, Z, Z); $$->vconst = 0; $$->type = types[TINT]; $3 = new(OSUB, $$, $3); $$ = new(OSWITCH, $3, $5); }| LBREAK ';' { $$ = new(OBREAK, Z, Z); }| LCONTINUE ';' { $$ = new(OCONTINUE, Z, Z); }| LGOTO ltag ';' { $$ = new(OGOTO, dcllabel($2, 0), Z); }| LUSED '(' zelist ')' ';' { $$ = new(OUSED, $3, Z); }| LSET '(' zelist ')' ';' { $$ = new(OSET, $3, Z); }zcexpr: { $$ = Z; }| cexprzexpr: { $$ = Z; }| lexprlexpr: expr { $$ = new(OCAST, $1, Z); $$->type = types[TLONG]; }cexpr: expr| cexpr ',' cexpr { $$ = new(OCOMMA, $1, $3); }expr: xuexpr| expr '*' expr { $$ = new(OMUL, $1, $3); }| expr '/' expr { $$ = new(ODIV, $1, $3); }| expr '%' expr { $$ = new(OMOD, $1, $3); }| expr '+' expr { $$ = new(OADD, $1, $3); }| expr '-' expr { $$ = new(OSUB, $1, $3); }| expr LRSH expr { $$ = new(OASHR, $1, $3); }| expr LLSH expr { $$ = new(OASHL, $1, $3); }| expr '<' expr { $$ = new(OLT, $1, $3); }| expr '>' expr { $$ = new(OGT, $1, $3); }| expr LLE expr { $$ = new(OLE, $1, $3); }| expr LGE expr { $$ = new(OGE, $1, $3); }| expr LEQ expr { $$ = new(OEQ, $1, $3); }| expr LNE expr { $$ = new(ONE, $1, $3); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -