📄 cgram.y
字号:
%term NAME 2%term STRING 3%term ICON 4%term FCON 5%term PLUS 6%term MINUS 8%term MUL 11%term AND 14%term OR 17%term ER 19%term QUEST 21%term COLON 22%term ANDAND 23%term OROR 24/* special interfaces for yacc alone *//* These serve as abbreviations of 2 or more ops: ASOP =, = ops RELOP LE,LT,GE,GT EQUOP EQ,NE DIVOP DIV,MOD SHIFTOP LS,RS ICOP ICR,DECR UNOP NOT,COMPL STROP DOT,STREF */%term ASOP 25%term RELOP 26%term EQUOP 27%term DIVOP 28%term SHIFTOP 29%term INCOP 30%term UNOP 31%term STROP 32/* reserved words, etc */%term TYPE 33%term CLASS 34%term STRUCT 35%term RETURN 36%term GOTO 37%term IF 38%term ELSE 39%term SWITCH 40%term BREAK 41%term CONTINUE 42%term WHILE 43%term DO 44%term FOR 45%term DEFAULT 46%term CASE 47%term SIZEOF 48%term ENUM 49/* little symbols, etc. *//* namely, LP ( RP ) LC { RC } LB [ RB ] CM , SM ; */%term LP 50%term RP 51%term LC 52%term RC 53%term LB 54%term RB 55%term CM 56%term SM 57%term ASSIGN 58/* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts/* these involved: if/else recognizing functions in various contexts, including declarations error recovery */%left CM%right ASOP ASSIGN%right QUEST COLON%left OROR%left ANDAND%left OR%left ER%left AND%left EQUOP%left RELOP%left SHIFTOP%left PLUS MINUS%left MUL DIVOP%right UNOP%right INCOP SIZEOF%left LB LP STROP%{# include "mfile1"%} /* define types */%start ext_def_list%type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart enum_head str_head name_lp%type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl cast_type null_decl funct_idn declarator fdeclarator nfdeclarator elist%token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR ER ANDAND OROR ASSIGN STROP INCOP UNOP ICON%token <nodep> TYPE%%%{ static int fake = 0; static char fakename[NCHNAM+1];%}ext_def_list: ext_def_list external_def | =ftnend(); ;external_def: data_def ={ curclass = SNULL; blevel = 0; } | error ={ curclass = SNULL; blevel = 0; } ;data_def: oattributes SM ={ $1->op = FREE; } | oattributes init_dcl_list SM ={ $1->op = FREE; } | oattributes fdeclarator { defid( tymerge($1,$2), curclass==STATIC?STATIC:EXTDEF ); } function_body ={ if( blevel ) cerror( "function level error" ); if( reached ) retstat |= NRETVAL; $1->op = FREE; ftnend(); } ;function_body: arg_dcl_list compoundstmt ;arg_dcl_list: arg_dcl_list declaration | ={ blevel = 1; } ;stmt_list: stmt_list statement | /* empty */ ={ bccode(); locctr(PROG); } ;dcl_stat_list : dcl_stat_list attributes SM ={ $2->op = FREE; } | dcl_stat_list attributes init_dcl_list SM ={ $2->op = FREE; } | /* empty */ ;declaration: attributes declarator_list SM ={ curclass = SNULL; $1->op = FREE; } | attributes SM ={ curclass = SNULL; $1->op = FREE; } | error SM ={ curclass = SNULL; } ;oattributes: attributes | /* VOID */ ={ $$ = mkty(INT,0,INT); curclass = SNULL; } ;attributes: class type ={ $$ = $2; } | type class | class ={ $$ = mkty(INT,0,INT); } | type ={ curclass = SNULL ; } ;class: CLASS ={ curclass = $1; } ;type: TYPE | TYPE TYPE ={ $1->type = types( $1->type, $2->type, UNDEF ); $2->op = FREE; } | TYPE TYPE TYPE ={ $1->type = types( $1->type, $2->type, $3->type ); $2->op = $3->op = FREE; } | struct_dcl | enum_dcl ;enum_dcl: enum_head LC moe_list optcomma RC ={ $$ = dclstruct($1); } | ENUM NAME ={ $$ = rstruct($2,0); stwart = instruct; } ;enum_head: ENUM ={ $$ = bstruct(-1,0); } | ENUM NAME ={ $$ = bstruct($2,0); } ;moe_list: moe | moe_list CM moe ;moe: NAME ={ moedef( $1 ); } | NAME ASSIGN con_e ={ strucoff = $3; moedef( $1 ); } ;struct_dcl: str_head LC type_dcl_list optsemi RC ={ $$ = dclstruct($1); } | STRUCT NAME ={ $$ = rstruct($2,$1); } ;str_head: STRUCT ={ $$ = bstruct(-1,$1); stwart=0; } | STRUCT NAME ={ $$ = bstruct($2,$1); stwart=0; } ;type_dcl_list: type_declaration | type_dcl_list SM type_declaration ;type_declaration: type declarator_list ={ curclass = SNULL; stwart=0; $1->op = FREE; } | type ={ if( curclass != MOU ){ curclass = SNULL; } else { sprintf( fakename, "$%dFAKE", fake++ ); defid( tymerge($1, bdty(NAME,NIL,lookup( fakename, SMOS ))), curclass ); } stwart = 0; $1->op = FREE; } ;declarator_list: declarator ={ defid( tymerge($<nodep>0,$1), curclass); stwart = instruct; } | declarator_list CM {$<nodep>$=$<nodep>0;} declarator ={ defid( tymerge($<nodep>0,$4), curclass); stwart = instruct; } ;declarator: fdeclarator | nfdeclarator | nfdeclarator COLON con_e %prec CM ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" ); if( $3<0 || $3 >= FIELD ){ uerror( "illegal field size" ); $3 = 1; } defid( tymerge($<nodep>0,$1), FIELD|$3 ); $$ = NIL; } | COLON con_e %prec CM ={ if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" ); falloc( stab, $2, -1, $<nodep>0 ); /* alignment or hole */ $$ = NIL; } | error ={ $$ = NIL; } ; /* int (a)(); is not a function --- sorry! */nfdeclarator: MUL nfdeclarator ={ umul: $$ = bdty( UNARY MUL, $2, 0 ); } | nfdeclarator LP RP ={ uftn: $$ = bdty( UNARY CALL, $1, 0 ); } | nfdeclarator LB RB ={ uary: $$ = bdty( LB, $1, 0 ); } | nfdeclarator LB con_e RB ={ bary: if( (int)$3 <= 0 ) werror( "zero or negative subscript" ); $$ = bdty( LB, $1, $3 ); } | NAME ={ $$ = bdty( NAME, NIL, $1 ); } | LP nfdeclarator RP ={ $$=$2; } ;fdeclarator: MUL fdeclarator ={ goto umul; } | fdeclarator LP RP ={ goto uftn; } | fdeclarator LB RB ={ goto uary; } | fdeclarator LB con_e RB ={ goto bary; } | LP fdeclarator RP ={ $$ = $2; } | name_lp name_list RP ={ if( blevel!=0 ) uerror("function declaration in bad context"); $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 ); stwart = 0; } | name_lp RP ={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 ); stwart = 0; } ;name_lp: NAME LP ={ /* turn off typedefs for argument names */ stwart = SEENAME; } ;name_list: NAME ={ ftnarg( $1 ); stwart = SEENAME; } | name_list CM NAME ={ ftnarg( $3 ); stwart = SEENAME; } ; /* always preceeded by attributes: thus the $<nodep>0's */init_dcl_list: init_declarator %prec CM | init_dcl_list CM {$<nodep>$=$<nodep>0;} init_declarator ; /* always preceeded by attributes */xnfdeclarator: nfdeclarator ={ defid( $1 = tymerge($<nodep>0,$1), curclass); beginit($1->rval); } | error ; /* always preceeded by attributes */init_declarator: nfdeclarator ={ nidcl( tymerge($<nodep>0,$1) ); } | fdeclarator ={ defid( tymerge($<nodep>0,$1), uclass(curclass) ); } | xnfdeclarator optasgn e %prec CM ={ doinit( $3 ); endinit(); } | xnfdeclarator optasgn LC init_list optcomma RC ={ endinit(); } ;init_list: initializer %prec CM | init_list CM initializer ;initializer: e %prec CM ={ doinit( $1 ); } | ibrace init_list optcomma RC ={ irbrace(); } ;optcomma : /* VOID */ | CM ;optsemi : /* VOID */ | SM ;optasgn : /* VOID */ ={ werror( "old-fashioned initialization: use =" ); } | ASSIGN ;ibrace : LC ={ ilbrace(); } ;/* STATEMENTS */compoundstmt: begin dcl_stat_list stmt_list RC ={ --blevel; if( blevel == 1 ) blevel = 0; clearst( blevel ); checkst( blevel ); autooff = *--psavbc; regvar = *--psavbc; } ;begin: LC ={ if( blevel == 1 ) dclargs(); ++blevel; if( psavbc > &asavbc[BCSZ-2] ) cerror( "nesting too deep" ); *psavbc++ = regvar; *psavbc++ = autooff; } ;statement: e SM ={ ecomp( $1 ); } | compoundstmt | ifprefix statement ={ deflab($1); reached = 1; } | ifelprefix statement ={ if( $1 != NOLAB ){ deflab( $1 ); reached = 1; } } | whprefix statement ={ branch( contlab ); deflab( brklab ); if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1; else reached = 0; resetbc(0); } | doprefix statement WHILE LP e RP SM ={ deflab( contlab ); if( flostat & FCONT ) reached = 1; ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) ); deflab( brklab ); reached = 1; resetbc(0); } | forprefix .e RP statement ={ deflab( contlab ); if( flostat&FCONT ) reached = 1; if( $2 ) ecomp( $2 ); branch( $1 ); deflab( brklab ); if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1; else reached = 0; resetbc(0); } | switchpart statement ={ if( reached ) branch( brklab ); deflab( $1 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -