Annotation of 43BSDReno/libexec/pcc/mip/cgram.y, revision 1.1.1.1

1.1       root        1: /*     cgram.y 4.22    87/12/09        */
                      2: 
                      3: /*
                      4:  * Grammar for the C compiler.
                      5:  *
                      6:  * This grammar requires the definitions of terminals in the file 'pcctokens'.
                      7:  * (YACC doesn't have an 'include' mechanism, unfortunately.)
                      8:  */
                      9: 
                     10: 
                     11: /* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts
                     12: /* these involved:
                     13:        if/else
                     14:        recognizing functions in various contexts, including declarations
                     15:        error recovery
                     16:        */
                     17: 
                     18: %left CM
                     19: %right ASOP ASSIGN
                     20: %right QUEST COLON
                     21: %left OROR
                     22: %left ANDAND
                     23: %left OR
                     24: %left ER
                     25: %left AND
                     26: %left EQUOP
                     27: %left RELOP
                     28: %left SHIFTOP
                     29: %left PLUS MINUS
                     30: %left MUL DIVOP
                     31: %right UNOP
                     32: %right INCOP SIZEOF
                     33: %left LB LP STROP
                     34: %{
                     35: # include "pass1.h"
                     36: %}
                     37: 
                     38:        /* define types */
                     39: %start ext_def_list
                     40: 
                     41: %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart
                     42:                enum_head str_head name_lp
                     43: %type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl
                     44:                cast_type null_decl funct_idn declarator fdeclarator nfdeclarator
                     45:                elist
                     46: 
                     47: %token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR ER ANDAND OROR
                     48:                ASSIGN STROP INCOP UNOP ICON
                     49: %token <nodep> TYPE
                     50: 
                     51: %%
                     52: 
                     53: %{
                     54:        static int fake = 0;
                     55: #ifndef FLEXNAMES
                     56:        static char fakename[NCHNAM+1];
                     57: #else
                     58:        static char fakename[24];
                     59: #endif
                     60:        static int nsizeof = 0;
                     61: %}
                     62: 
                     63: ext_def_list:     ext_def_list external_def
                     64:                |
                     65:                        =ftnend();
                     66:                ;
                     67: external_def:     data_def
                     68:                        ={ curclass = SNULL;  blevel = 0; }
                     69:                |  error
                     70:                        ={ curclass = SNULL;  blevel = 0; }
                     71:                ;
                     72: data_def:
                     73:                   oattributes  SM
                     74:                        ={  $1->in.op = FREE; }
                     75:                |  oattributes init_dcl_list  SM
                     76:                        ={  $1->in.op = FREE; }
                     77:                |  oattributes fdeclarator {
                     78:                                defid( tymerge($1,$2), curclass==STATIC?STATIC:EXTDEF );
                     79: #ifndef LINT
                     80:                                if( nerrors == 0 )
                     81:                                        pfstab(stab[$2->tn.rval].sname);
                     82: #endif
                     83:                                }  function_body
                     84:                        ={  
                     85:                            if( blevel ) cerror( "function level error" );
                     86:                            if( reached ) retstat |= NRETVAL; 
                     87:                            $1->in.op = FREE;
                     88:                            ftnend();
                     89:                            }
                     90:                ;
                     91: 
                     92: function_body:    arg_dcl_list compoundstmt
                     93:                ;
                     94: arg_dcl_list:     arg_dcl_list declaration
                     95:                |       ={  blevel = 1; }
                     96:                ;
                     97: 
                     98: stmt_list:        stmt_list statement
                     99:                |  /* empty */
                    100:                        ={  bccode();
                    101:                            (void) locctr(PROG);
                    102:                            }
                    103:                ;
                    104: 
                    105: r_dcl_stat_list        :  dcl_stat_list attributes SM
                    106:                        ={  $2->in.op = FREE; 
                    107: #ifndef LINT
                    108:                            if( nerrors == 0 ) plcstab(blevel);
                    109: #endif
                    110:                            }
                    111:                |  dcl_stat_list attributes init_dcl_list SM
                    112:                        ={  $2->in.op = FREE; 
                    113: #ifndef LINT
                    114:                            if( nerrors == 0 ) plcstab(blevel);
                    115: #endif
                    116:                            }
                    117:                ;
                    118: 
                    119: dcl_stat_list  :  dcl_stat_list attributes SM
                    120:                        ={  $2->in.op = FREE; }
                    121:                |  dcl_stat_list attributes init_dcl_list SM
                    122:                        ={  $2->in.op = FREE; }
                    123:                |  /* empty */
                    124:                ;
                    125: declaration:      attributes declarator_list  SM
                    126:                        ={ curclass = SNULL;  $1->in.op = FREE; }
                    127:                |  attributes SM
                    128:                        ={ curclass = SNULL;  $1->in.op = FREE; }
                    129:                |  error  SM
                    130:                        ={  curclass = SNULL; }
                    131:                ;
                    132: oattributes:     attributes
                    133:                |  /* VOID */
                    134:                        ={  $$ = mkty(INT,0,INT);  curclass = SNULL; }
                    135:                ;
                    136: attributes:       class type
                    137:                        ={  $$ = $2; }
                    138:                |  type class
                    139:                |  class
                    140:                        ={  $$ = mkty(INT,0,INT); }
                    141:                |  type
                    142:                        ={ curclass = SNULL ; }
                    143:                |  type class type
                    144:                        ={  $1->in.type = types( $1->in.type, $3->in.type, UNDEF );
                    145:                            $3->in.op = FREE;
                    146:                            }
                    147:                ;
                    148: 
                    149: 
                    150: class:           CLASS
                    151:                        ={  curclass = $1; }
                    152:                ;
                    153: 
                    154: type:             TYPE
                    155:                |  TYPE TYPE
                    156:                        ={  $1->in.type = types( $1->in.type, $2->in.type, UNDEF );
                    157:                            $2->in.op = FREE;
                    158:                            }
                    159:                |  TYPE TYPE TYPE
                    160:                        ={  $1->in.type = types( $1->in.type, $2->in.type, $3->in.type );
                    161:                            $2->in.op = $3->in.op = FREE;
                    162:                            }
                    163:                |  struct_dcl
                    164:                |  enum_dcl
                    165:                ;
                    166: 
                    167: enum_dcl:         enum_head LC moe_list optcomma RC
                    168:                        ={ $$ = dclstruct($1); }
                    169:                |  ENUM NAME
                    170:                        ={  $$ = rstruct($2,0);  stwart = instruct; }
                    171:                ;
                    172: 
                    173: enum_head:        ENUM
                    174:                        ={  $$ = bstruct(-1,0); stwart = SEENAME; }
                    175:                |  ENUM NAME
                    176:                        ={  $$ = bstruct($2,0); stwart = SEENAME; }
                    177:                ;
                    178: 
                    179: moe_list:         moe
                    180:                |  moe_list CM moe
                    181:                ;
                    182: 
                    183: moe:              NAME
                    184:                        ={  moedef( $1 ); }
                    185:                |  NAME ASSIGN con_e
                    186:                        ={  strucoff = $3;  moedef( $1 ); }
                    187:                ;
                    188: 
                    189: struct_dcl:       str_head LC type_dcl_list optsemi RC
                    190:                        ={ $$ = dclstruct($1);  }
                    191:                |  STRUCT NAME
                    192:                        ={  $$ = rstruct($2,$1); }
                    193:                ;
                    194: 
                    195: str_head:         STRUCT
                    196:                        ={  $$ = bstruct(-1,$1);  stwart=0; }
                    197:                |  STRUCT NAME
                    198:                        ={  $$ = bstruct($2,$1);  stwart=0;  }
                    199:                ;
                    200: 
                    201: type_dcl_list:    type_declaration
                    202:                |  type_dcl_list SM type_declaration
                    203:                ;
                    204: 
                    205: type_declaration:  type declarator_list
                    206:                        ={ curclass = SNULL;  stwart=0; $1->in.op = FREE; }
                    207:                |  type
                    208:                        ={  if( curclass != MOU ){
                    209:                                curclass = SNULL;
                    210:                                }
                    211:                            else {
                    212:                                sprintf( fakename, "$%dFAKE", fake++ );
                    213: #ifdef FLEXNAMES
                    214:                                /* No need to hash this, we won't look it up */
                    215:                                defid( tymerge($1, bdty(NAME,NIL,lookup( savestr(fakename), SMOS ))), curclass );
                    216: #else
                    217:                                defid( tymerge($1, bdty(NAME,NIL,lookup( fakename, SMOS ))), curclass );
                    218: #endif
                    219:                                werror("structure typed union member must be named");
                    220:                                }
                    221:                            stwart = 0;
                    222:                            $1->in.op = FREE;
                    223:                            }
                    224:                ;
                    225: 
                    226: 
                    227: declarator_list:   declarator
                    228:                        ={ defid( tymerge($<nodep>0,$1), curclass);  stwart = instruct; }
                    229:                |  declarator_list  CM {$<nodep>$=$<nodep>0;}  declarator
                    230:                        ={ defid( tymerge($<nodep>0,$4), curclass);  stwart = instruct; }
                    231:                ;
                    232: declarator:       fdeclarator
                    233:                |  nfdeclarator
                    234:                |  nfdeclarator COLON con_e
                    235:                        %prec CM
                    236:                        ={  if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" );
                    237:                            if( $3<0 || $3 >= FIELD ){
                    238:                                uerror( "illegal field size" );
                    239:                                $3 = 1;
                    240:                                }
                    241:                            defid( tymerge($<nodep>0,$1), FIELD|$3 );
                    242:                            $$ = NIL;
                    243:                            }
                    244:                |  COLON con_e
                    245:                        %prec CM
                    246:                        ={  if( !(instruct&INSTRUCT) ) uerror( "field outside of structure" );
                    247:                            (void) falloc( stab, $2, -1, $<nodep>0 );  /* alignment or hole */
                    248:                            $$ = NIL;
                    249:                            }
                    250:                |  error
                    251:                        ={  $$ = NIL; }
                    252:                ;
                    253: 
                    254:                /* int (a)();   is not a function --- sorry! */
                    255: nfdeclarator:     MUL nfdeclarator             
                    256:                        ={  umul:
                    257:                                $$ = bdty( UNARY MUL, $2, 0 ); }
                    258:                |  nfdeclarator  LP   RP                
                    259:                        ={  uftn:
                    260:                                $$ = bdty( UNARY CALL, $1, 0 );  }
                    261:                |  nfdeclarator LB RB           
                    262:                        ={  uary:
                    263:                                $$ = bdty( LB, $1, 0 );  }
                    264:                |  nfdeclarator LB con_e RB     
                    265:                        ={  bary:
                    266:                                if( (int)$3 <= 0 ) werror( "zero or negative subscript" );
                    267:                                $$ = bdty( LB, $1, $3 );  }
                    268:                |  NAME                 
                    269:                        ={  $$ = bdty( NAME, NIL, $1 );  }
                    270:                |   LP  nfdeclarator  RP                
                    271:                        ={ $$=$2; }
                    272:                ;
                    273: fdeclarator:      MUL fdeclarator
                    274:                        ={  goto umul; }
                    275:                |  fdeclarator  LP   RP
                    276:                        ={  goto uftn; }
                    277:                |  fdeclarator LB RB
                    278:                        ={  goto uary; }
                    279:                |  fdeclarator LB con_e RB
                    280:                        ={  goto bary; }
                    281:                |   LP  fdeclarator  RP
                    282:                        ={ $$ = $2; }
                    283:                |  name_lp  name_list  RP
                    284:                        ={
                    285:                                if( blevel!=0 ) uerror("function declaration in bad context");
                    286:                                $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
                    287:                                stwart = 0;
                    288:                                }
                    289:                |  name_lp RP
                    290:                        ={
                    291:                                $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
                    292:                                stwart = 0;
                    293:                                }
                    294:                ;
                    295: 
                    296: name_lp:         NAME LP
                    297:                        ={
                    298:                                /* turn off typedefs for argument names */
                    299:                                stwart = SEENAME;
                    300:                                if( stab[$1].sclass == SNULL )
                    301:                                    stab[$1].stype = FTN;
                    302:                                }
                    303:                ;
                    304: 
                    305: name_list:        NAME                 
                    306:                        ={ ftnarg( $1 );  stwart = SEENAME; }
                    307:                |  name_list  CM  NAME 
                    308:                        ={ ftnarg( $3 );  stwart = SEENAME; }
                    309:                | error
                    310:                ;
                    311:                /* always preceeded by attributes: thus the $<nodep>0's */
                    312: init_dcl_list:    init_declarator
                    313:                        %prec CM
                    314:                |  init_dcl_list  CM {$<nodep>$=$<nodep>0;}  init_declarator
                    315:                ;
                    316:                /* always preceeded by attributes */
                    317: xnfdeclarator:    nfdeclarator
                    318:                        ={  int id;
                    319: 
                    320:                            defid( $1 = tymerge($<nodep>0,$1), curclass);
                    321:                            id = $1->tn.rval;
                    322:                            beginit(id);
                    323:                            if( stab[id].sclass == AUTO ||
                    324:                                stab[id].sclass == REGISTER ||
                    325:                                stab[id].sclass == STATIC )
                    326:                                stab[id].suse = -lineno;
                    327:                            }
                    328:                |  error
                    329:                ;
                    330:                /* always preceeded by attributes */
                    331: init_declarator:   nfdeclarator
                    332:                        ={  nidcl( tymerge($<nodep>0,$1) ); }
                    333:                |  fdeclarator
                    334:                        ={  defid( tymerge($<nodep>0,$1), uclass(curclass) );
                    335:                            if( paramno > 0 ){
                    336:                                uerror( "illegal argument" );
                    337:                                paramno = 0;
                    338:                                }
                    339:                        }
                    340:                |  xnfdeclarator optasgn e
                    341:                        %prec CM
                    342:                        ={  doinit( $3 );
                    343:                            endinit(); }
                    344:                |  xnfdeclarator optasgn LC init_list optcomma RC
                    345:                        ={  endinit(); }
                    346:                | error
                    347:                        ={  fixinit(); }
                    348:                ;
                    349: 
                    350: init_list:        initializer
                    351:                        %prec CM
                    352:                |  init_list  CM  initializer
                    353:                ;
                    354: initializer:      e
                    355:                        %prec CM
                    356:                        ={  doinit( $1 ); }
                    357:                |  ibrace init_list optcomma RC
                    358:                        ={  irbrace(); }
                    359:                ;
                    360: 
                    361: optcomma       :       /* VOID */
                    362:                |  CM
                    363:                ;
                    364: 
                    365: optsemi                :       /* VOID */
                    366:                |  SM
                    367:                ;
                    368: 
                    369: optasgn                :       /* uncomment for old-fashioned initializations */
                    370:                        /* /* VOID */
                    371:                        /* ={  werror( "old-fashioned initialization: use =" ); }
                    372:                /* | */  ASSIGN
                    373:                ;
                    374: 
                    375: ibrace         : LC
                    376:                        ={  ilbrace(); }
                    377:                ;
                    378: 
                    379: /*     STATEMENTS      */
                    380: 
                    381: compoundstmt:     dcmpstmt
                    382:                |  cmpstmt
                    383:                ;
                    384: 
                    385: dcmpstmt:         begin r_dcl_stat_list stmt_list RC
                    386:                        ={  
                    387: #ifndef LINT
                    388:                            if( nerrors == 0 ) prcstab(blevel);
                    389: #endif
                    390:                            --blevel;
                    391:                            if( blevel == 1 ) blevel = 0;
                    392:                            clearst( blevel );
                    393:                            checkst( blevel );
                    394:                            autooff = *--psavbc;
                    395:                            regvar = *--psavbc;
                    396:                            }
                    397:                ;
                    398: 
                    399: cmpstmt:          begin stmt_list RC
                    400:                        ={  --blevel;
                    401:                            if( blevel == 1 ) blevel = 0;
                    402:                            clearst( blevel );
                    403:                            checkst( blevel );
                    404:                            autooff = *--psavbc;
                    405:                            regvar = *--psavbc;
                    406:                            }
                    407:                ;
                    408: 
                    409: begin:           LC
                    410:                        ={  if( blevel == 1 ) dclargs();
                    411:                            ++blevel;
                    412:                            if( psavbc > &asavbc[BCSZ-2] ) cerror( "nesting too deep" );
                    413:                            *psavbc++ = regvar;
                    414:                            *psavbc++ = autooff;
                    415:                            }
                    416:                ;
                    417: 
                    418: statement:        e   SM
                    419:                        ={ ecomp( $1 ); }
                    420:                |  compoundstmt
                    421:                |  ifprefix statement
                    422:                        ={ deflab($1);
                    423:                           reached = 1;
                    424:                           }
                    425:                |  ifelprefix statement
                    426:                        ={  if( $1 != NOLAB ){
                    427:                                deflab( $1 );
                    428:                                reached = 1;
                    429:                                }
                    430:                            }
                    431:                |  whprefix statement
                    432:                        ={  branch(  contlab );
                    433:                            deflab( brklab );
                    434:                            if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1;
                    435:                            else reached = 0;
                    436:                            resetbc(0);
                    437:                            }
                    438:                |  doprefix statement WHILE  LP  e  RP   SM
                    439:                        ={  deflab( contlab );
                    440:                            if( flostat & FCONT ) reached = 1;
                    441:                            ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) );
                    442:                            deflab( brklab );
                    443:                            reached = 1;
                    444:                            resetbc(0);
                    445:                            }
                    446:                |  forprefix .e RP statement
                    447:                        ={  deflab( contlab );
                    448:                            if( flostat&FCONT ) reached = 1;
                    449:                            if( $2 ) ecomp( $2 );
                    450:                            branch( $1 );
                    451:                            deflab( brklab );
                    452:                            if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
                    453:                            else reached = 0;
                    454:                            resetbc(0);
                    455:                            }
                    456:                | switchpart statement
                    457:                        ={  if( reached ) branch( brklab );
                    458:                            deflab( $1 );
                    459:                           swend();
                    460:                            deflab(brklab);
                    461:                            if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
                    462:                            resetbc(FCONT);
                    463:                            }
                    464:                |  BREAK  SM
                    465:                        ={  if( brklab == NOLAB ) uerror( "illegal break");
                    466:                            else if(reached) branch( brklab );
                    467:                            flostat |= FBRK;
                    468:                            if( brkflag ) goto rch;
                    469:                            reached = 0;
                    470:                            }
                    471:                |  CONTINUE  SM
                    472:                        ={  if( contlab == NOLAB ) uerror( "illegal continue");
                    473:                            else branch( contlab );
                    474:                            flostat |= FCONT;
                    475:                            goto rch;
                    476:                            }
                    477:                |  RETURN  SM
                    478:                        ={  retstat |= NRETVAL;
                    479:                            branch( retlab );
                    480:                        rch:
                    481:                            if( !reached ) werror( "statement not reached");
                    482:                            reached = 0;
                    483:                            }
                    484:                |  RETURN e  SM
                    485:                        ={  register NODE *temp;
                    486:                            idname = curftn;
                    487:                            temp = buildtree( NAME, NIL, NIL );
                    488:                            if(temp->in.type == TVOID)
                    489:                                uerror("void function %s cannot return value",
                    490:                                        stab[idname].sname);
                    491:                            temp->in.type = DECREF( temp->in.type );
                    492:                            temp = buildtree( RETURN, temp, $2 );
                    493:                            /* now, we have the type of the RHS correct */
                    494:                            temp->in.left->in.op = FREE;
                    495:                            temp->in.op = FREE;
                    496:                            ecomp( buildtree( FORCE, temp->in.right, NIL ) );
                    497:                            retstat |= RETVAL;
                    498:                            branch( retlab );
                    499:                            reached = 0;
                    500:                            }
                    501:                |  GOTO NAME SM
                    502:                        ={  register NODE *q;
                    503:                            q = block( FREE, NIL, NIL, INT|ARY, 0, INT );
                    504:                            q->tn.rval = idname = $2;
                    505:                            defid( q, ULABEL );
                    506:                            stab[idname].suse = -lineno;
                    507:                            branch( stab[idname].offset );
                    508:                            goto rch;
                    509:                            }
                    510:                |   SM
                    511:                |  error  SM
                    512:                |  error RC
                    513:                |  label statement
                    514:                ;
                    515: label:            NAME COLON
                    516:                        ={  register NODE *q;
                    517:                            q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL );
                    518:                            q->tn.rval = $1;
                    519:                            defid( q, LABEL );
                    520:                            reached = 1;
                    521:                            }
                    522:                |  CASE e COLON
                    523:                        ={  addcase($2);
                    524:                            reached = 1;
                    525:                            }
                    526:                |  DEFAULT COLON
                    527:                        ={  reached = 1;
                    528:                            adddef();
                    529:                            flostat |= FDEF;
                    530:                            }
                    531:                ;
                    532: doprefix:      DO
                    533:                        ={  savebc();
                    534:                            if( !reached ) werror( "loop not entered at top");
                    535:                            brklab = getlab();
                    536:                            contlab = getlab();
                    537:                            deflab( $$ = getlab() );
                    538:                            reached = 1;
                    539:                            }
                    540:                ;
                    541: ifprefix:      IF LP e RP
                    542:                        ={  ecomp( buildtree( CBRANCH, $3, bcon( $$=getlab()) ) ) ;
                    543:                            reached = 1;
                    544:                            }
                    545:                ;
                    546: ifelprefix:      ifprefix statement ELSE
                    547:                        ={  if( reached ) branch( $$ = getlab() );
                    548:                            else $$ = NOLAB;
                    549:                            deflab( $1 );
                    550:                            reached = 1;
                    551:                            }
                    552:                ;
                    553: 
                    554: whprefix:        WHILE  LP  e  RP
                    555:                        ={  savebc();
                    556:                            if( !reached ) werror( "loop not entered at top");
                    557:                            if( $3->in.op == ICON && $3->tn.lval != 0 ) flostat = FLOOP;
                    558:                            deflab( contlab = getlab() );
                    559:                            reached = 1;
                    560:                            brklab = getlab();
                    561:                            if( flostat == FLOOP ) tfree( $3 );
                    562:                            else ecomp( buildtree( CBRANCH, $3, bcon( brklab) ) );
                    563:                            }
                    564:                ;
                    565: forprefix:       FOR  LP  .e  SM .e  SM 
                    566:                        ={  if( $3 ) ecomp( $3 );
                    567:                            else if( !reached ) werror( "loop not entered at top");
                    568:                            savebc();
                    569:                            contlab = getlab();
                    570:                            brklab = getlab();
                    571:                            deflab( $$ = getlab() );
                    572:                            reached = 1;
                    573:                            if( $5 ) ecomp( buildtree( CBRANCH, $5, bcon( brklab) ) );
                    574:                            else flostat |= FLOOP;
                    575:                            }
                    576:                ;
                    577: switchpart:       SWITCH  LP  e  RP
                    578:                        ={  register NODE *q;
                    579:                        
                    580:                            savebc();
                    581:                            brklab = getlab();
                    582:                            q = $3;
                    583:                            switch( q->in.type ) {
                    584:                            case CHAR:  case UCHAR:
                    585:                            case SHORT: case USHORT:
                    586:                            case INT:   case UNSIGNED:
                    587:                            case MOE:   case ENUMTY:
                    588:                                    break;
                    589:                            default:
                    590:                                werror("switch expression not type int");
                    591:                                q = makety( q, INT, q->fn.cdim, q->fn.csiz );
                    592:                                }
                    593: #ifdef LINT
                    594:                            if( hflag && q->in.op == ICON )
                    595:                                werror( "constant switch expression" );
                    596: #endif
                    597:                            ecomp( buildtree( FORCE, q, NIL ) );
                    598:                            branch( $$ = getlab() );
                    599:                            swstart();
                    600:                            reached = 0;
                    601:                            }
                    602:                ;
                    603: /*     EXPRESSIONS     */
                    604: con_e:            { $<intval>$=instruct; stwart=instruct=0; } e
                    605:                        %prec CM
                    606:                        ={  $$ = icons( $2 );  instruct=$<intval>1; }
                    607:                ;
                    608: .e:               e
                    609:                |
                    610:                        ={ $$=0; }
                    611:                ;
                    612: elist:            e
                    613:                        %prec CM
                    614:                |  elist  CM  e
                    615:                        ={  goto bop; }
                    616:                ;
                    617: 
                    618: e:                e RELOP e
                    619:                        ={
                    620:                        preconf:
                    621:                            if( yychar==RELOP||yychar==EQUOP||yychar==AND||yychar==OR||yychar==ER ){
                    622:                            precplaint:
                    623:                                if( hflag ) werror( "precedence confusion possible: parenthesize!" );
                    624:                                }
                    625:                        bop:
                    626:                            $$ = buildtree( $2, $1, $3 );
                    627:                            }
                    628:                |  e CM e
                    629:                        ={  $2 = COMOP;
                    630:                            goto bop;
                    631:                            }
                    632:                |  e DIVOP e
                    633:                        ={  goto bop; }
                    634:                |  e PLUS e
                    635:                        ={  if(yychar==SHIFTOP) goto precplaint; else goto bop; }
                    636:                |  e MINUS e
                    637:                        ={  if(yychar==SHIFTOP ) goto precplaint; else goto bop; }
                    638:                |  e SHIFTOP e
                    639:                        ={  if(yychar==PLUS||yychar==MINUS) goto precplaint; else goto bop; }
                    640:                |  e MUL e
                    641:                        ={  goto bop; }
                    642:                |  e EQUOP  e
                    643:                        ={  goto preconf; }
                    644:                |  e AND e
                    645:                        ={  if( yychar==RELOP||yychar==EQUOP ) goto preconf;  else goto bop; }
                    646:                |  e OR e
                    647:                        ={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
                    648:                |  e ER e
                    649:                        ={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
                    650:                |  e ANDAND e
                    651:                        ={  goto bop; }
                    652:                |  e OROR e
                    653:                        ={  goto bop; }
                    654:                |  e MUL ASSIGN e
                    655:                        ={  abop:
                    656:                                $$ = buildtree( ASG $2, $1, $4 );
                    657:                                }
                    658:                |  e DIVOP ASSIGN e
                    659:                        ={  goto abop; }
                    660:                |  e PLUS ASSIGN e
                    661:                        ={  goto abop; }
                    662:                |  e MINUS ASSIGN e
                    663:                        ={  goto abop; }
                    664:                |  e SHIFTOP ASSIGN e
                    665:                        ={  goto abop; }
                    666:                |  e AND ASSIGN e
                    667:                        ={  goto abop; }
                    668:                |  e OR ASSIGN e
                    669:                        ={  goto abop; }
                    670:                |  e ER ASSIGN e
                    671:                        ={  goto abop; }
                    672:                |  e QUEST e COLON e
                    673:                        ={  $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) );
                    674:                            }
                    675:                |  e ASOP e
                    676:                        ={  werror( "old-fashioned assignment operator" );  goto bop; }
                    677:                |  e ASSIGN e
                    678:                        ={  goto bop; }
                    679:                |  term
                    680:                ;
                    681: term:             term INCOP
                    682:                        ={  $$ = buildtree( $2, $1, bcon(1) ); }
                    683:                |  MUL term
                    684:                        ={ ubop:
                    685:                            $$ = buildtree( UNARY $1, $2, NIL );
                    686:                            }
                    687:                |  AND term
                    688:                        ={  if( ISFTN($2->in.type) || ISARY($2->in.type) ){
                    689:                                werror( "& before array or function: ignored" );
                    690:                                $$ = $2;
                    691:                                }
                    692:                            else if( $2->in.op == UNARY MUL &&
                    693:                                     ($2->in.left->in.op == STASG ||
                    694:                                      $2->in.left->in.op == STCALL ||
                    695:                                      $2->in.left->in.op == UNARY STCALL) ){
                    696:                                /* legal trees but not available to users */
                    697:                                uerror( "unacceptable operand of &" );
                    698:                                goto ubop;
                    699:                                }
                    700:                            else goto ubop;
                    701:                            }
                    702:                |  MINUS term
                    703:                        ={  goto ubop; }
                    704:                |  UNOP term
                    705:                        ={
                    706:                            $$ = buildtree( $1, $2, NIL );
                    707:                            }
                    708:                |  INCOP term
                    709:                        ={  $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS,
                    710:                                                $2,
                    711:                                                bcon(1)  );
                    712:                            }
                    713:                |  pushsizeof term  %prec SIZEOF
                    714:                        ={  $$ = doszof( $2 ); --nsizeof; }
                    715:                |  LP cast_type RP term  %prec INCOP
                    716:                        ={  $$ = buildtree( CAST, $2, $4 );
                    717:                            $$->in.left->in.op = FREE;
                    718:                            $$->in.op = FREE;
                    719:                            $$ = $$->in.right;
                    720:                            }
                    721:                |  pushsizeof LP cast_type RP  %prec SIZEOF
                    722:                        ={  $$ = doszof( $3 ); --nsizeof; }
                    723:                |  term LB e RB
                    724:                        ={  $$ = buildtree( UNARY MUL, buildtree( PLUS, $1, $3 ), NIL ); }
                    725:                |  funct_idn  RP
                    726:                        ={  $$=buildtree(UNARY CALL,$1,NIL); }
                    727:                |  funct_idn elist  RP
                    728:                        ={  $$=buildtree(CALL,$1,$2); }
                    729:                |  term STROP NAME
                    730:                        ={  if( $2 == DOT ){
                    731:                                if( notlval( $1 ) &&
                    732:                                    !($1->in.op == UNARY MUL &&
                    733:                                      ($1->in.left->in.op == STASG ||
                    734:                                       $1->in.left->in.op == STCALL ||
                    735:                                       $1->in.left->in.op == UNARY STCALL)) )
                    736:                                    uerror("structure reference must be addressable");
                    737:                                $1 = buildtree( UNARY AND, $1, NIL );
                    738:                                }
                    739:                            idname = $3;
                    740:                            $$ = buildtree( STREF, $1, buildtree( NAME, NIL, NIL ) );
                    741:                            }
                    742:                |  NAME
                    743:                        ={  idname = $1;
                    744:                            /* recognize identifiers in initializations */
                    745:                            if( blevel==0 && stab[idname].stype == UNDEF ) {
                    746:                                register NODE *q;
                    747: #ifndef FLEXNAMES
                    748:                                werror( "undeclared initializer name %.8s", stab[idname].sname );
                    749: #else
                    750:                                werror( "undeclared initializer name %s", stab[idname].sname );
                    751: #endif
                    752:                                q = block( FREE, NIL, NIL, INT, 0, INT );
                    753:                                q->tn.rval = idname;
                    754:                                defid( q, EXTERN );
                    755:                                }
                    756:                            $$=buildtree(NAME,NIL,NIL);
                    757:                            if( nsizeof == 0 )
                    758:                                stab[$1].suse = -lineno;
                    759:                        }
                    760:                |  ICON
                    761:                        ={  $$=bcon(0);
                    762:                            $$->tn.lval = lastcon;
                    763:                            $$->tn.rval = NONAME;
                    764:                            if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG);
                    765:                            }
                    766:                |  FCON
                    767:                        ={  $$=buildtree(FCON,NIL,NIL);
                    768:                            $$->fpn.fval = fcon;
                    769:                            }
                    770:                |  DCON
                    771:                        ={  $$=buildtree(DCON,NIL,NIL);
                    772:                            $$->dpn.dval = dcon;
                    773:                            }
                    774:                |  STRING
                    775:                        ={  $$ = getstr(); /* get string contents */ }
                    776:                |   LP  e  RP
                    777:                        ={ $$=$2; }
                    778:                ;
                    779: 
                    780: cast_type:       type null_decl
                    781:                        ={
                    782:                        $$ = tymerge( $1, $2 );
                    783:                        $$->in.op = NAME;
                    784:                        $1->in.op = FREE;
                    785:                        }
                    786:                ;
                    787: 
                    788: pushsizeof:      SIZEOF
                    789:                        ={ ++nsizeof; }
                    790:                ;
                    791: 
                    792: null_decl:        /* empty */
                    793:                        ={ $$ = bdty( NAME, NIL, -1 ); }
                    794:                |  LP RP
                    795:                        ={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); }
                    796:                |  LP null_decl RP LP RP
                    797:                        ={  $$ = bdty( UNARY CALL, $2, 0 ); }
                    798:                |  MUL null_decl
                    799:                        ={  goto umul; }
                    800:                |  null_decl LB RB
                    801:                        ={  goto uary; }
                    802:                |  null_decl LB con_e RB
                    803:                        ={  goto bary;  }
                    804:                |  LP null_decl RP
                    805:                        ={ $$ = $2; }
                    806:                ;
                    807: 
                    808: funct_idn:        NAME  LP 
                    809:                        ={  if( stab[$1].stype == UNDEF ){
                    810:                                register NODE *q;
                    811:                                q = block( FREE, NIL, NIL, FTN|INT, 0, INT );
                    812:                                q->tn.rval = $1;
                    813:                                defid( q, EXTERN );
                    814:                                }
                    815:                            idname = $1;
                    816:                            $$=buildtree(NAME,NIL,NIL);
                    817:                            stab[idname].suse = -lineno;
                    818:                        }
                    819:                |  term  LP 
                    820:                ;
                    821: %%
                    822: 
                    823: NODE *
                    824: mkty( t, d, s ) unsigned t; {
                    825:        return( block( TYPE, NIL, NIL, t, d, s ) );
                    826:        }
                    827: 
                    828: NODE *
                    829: bdty( op, p, v ) NODE *p; {
                    830:        register NODE *q;
                    831: 
                    832:        q = block( op, p, NIL, INT, 0, INT );
                    833: 
                    834:        switch( op ){
                    835: 
                    836:        case UNARY MUL:
                    837:        case UNARY CALL:
                    838:                break;
                    839: 
                    840:        case LB:
                    841:                q->in.right = bcon(v);
                    842:                break;
                    843: 
                    844:        case NAME:
                    845:                q->tn.rval = v;
                    846:                break;
                    847: 
                    848:        default:
                    849:                cerror( "bad bdty" );
                    850:                }
                    851: 
                    852:        return( q );
                    853:        }
                    854: 
                    855: dstash( n ){ /* put n into the dimension table */
                    856:        if( curdim >= DIMTABSZ-1 ){
                    857:                cerror( "dimension table overflow");
                    858:                }
                    859:        dimtab[ curdim++ ] = n;
                    860:        }
                    861: 
                    862: savebc() {
                    863:        if( psavbc > & asavbc[BCSZ-4 ] ){
                    864:                cerror( "whiles, fors, etc. too deeply nested");
                    865:                }
                    866:        *psavbc++ = brklab;
                    867:        *psavbc++ = contlab;
                    868:        *psavbc++ = flostat;
                    869:        *psavbc++ = swx;
                    870:        flostat = 0;
                    871:        }
                    872: 
                    873: resetbc(mask){
                    874: 
                    875:        swx = *--psavbc;
                    876:        flostat = *--psavbc | (flostat&mask);
                    877:        contlab = *--psavbc;
                    878:        brklab = *--psavbc;
                    879: 
                    880:        }
                    881: 
                    882: addcase(p) NODE *p; { /* add case to switch */
                    883: 
                    884:        p = optim( p );  /* change enum to ints */
                    885:        if( p->in.op != ICON || p->tn.rval != NONAME ){
                    886:                uerror( "non-constant case expression");
                    887:                return;
                    888:                }
                    889:        if( swp == swtab ){
                    890:                uerror( "case not in switch");
                    891:                return;
                    892:                }
                    893:        if( swp >= &swtab[SWITSZ] ){
                    894:                cerror( "switch table overflow");
                    895:                }
                    896:        swp->sval = p->tn.lval;
                    897:        deflab( swp->slab = getlab() );
                    898:        ++swp;
                    899:        tfree(p);
                    900:        }
                    901: 
                    902: adddef(){ /* add default case to switch */
                    903:        if( swtab[swx].slab >= 0 ){
                    904:                uerror( "duplicate default in switch");
                    905:                return;
                    906:                }
                    907:        if( swp == swtab ){
                    908:                uerror( "default not inside switch");
                    909:                return;
                    910:                }
                    911:        deflab( swtab[swx].slab = getlab() );
                    912:        }
                    913: 
                    914: swstart(){
                    915:        /* begin a switch block */
                    916:        if( swp >= &swtab[SWITSZ] ){
                    917:                cerror( "switch table overflow");
                    918:                }
                    919:        swx = swp - swtab;
                    920:        swp->slab = -1;
                    921:        ++swp;
                    922:        }
                    923: 
                    924: swend(){ /* end a switch block */
                    925: 
                    926:        register struct sw *swbeg, *p, *q, *r, *r1;
                    927:        CONSZ temp;
                    928:        int tempi;
                    929: 
                    930:        swbeg = &swtab[swx+1];
                    931: 
                    932:        /* sort */
                    933: 
                    934:        r1 = swbeg;
                    935:        r = swp-1;
                    936: 
                    937:        while( swbeg < r ){
                    938:                /* bubble largest to end */
                    939:                for( q=swbeg; q<r; ++q ){
                    940:                        if( q->sval > (q+1)->sval ){
                    941:                                /* swap */
                    942:                                r1 = q+1;
                    943:                                temp = q->sval;
                    944:                                q->sval = r1->sval;
                    945:                                r1->sval = temp;
                    946:                                tempi = q->slab;
                    947:                                q->slab = r1->slab;
                    948:                                r1->slab = tempi;
                    949:                                }
                    950:                        }
                    951:                r = r1;
                    952:                r1 = swbeg;
                    953:                }
                    954: 
                    955:        /* it is now sorted */
                    956: 
                    957:        for( p = swbeg+1; p<swp; ++p ){
                    958:                if( p->sval == (p-1)->sval ){
                    959:                        uerror( "duplicate case in switch, %d", p->sval );
                    960:                        return;
                    961:                        }
                    962:                }
                    963: 
                    964:        genswitch( swbeg-1, swp-swbeg );
                    965:        swp = swbeg-1;
                    966:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.