Annotation of coherent/d/bin/bc/gram.y, revision 1.1

1.1     ! root        1: /*     Bc - an infix desk calculator */
        !             2: 
        !             3: %{
        !             4: #include <stdio.h>
        !             5: #include "bc.h"
        !             6: #define        YYTNAMES
        !             7: 
        !             8: /* This will generate yyerror() and error recovery */
        !             9: #define YYSYNTAX       goto YYerract
        !            10: /* This will enter error recovery */
        !            11: #define YYERROR                ++yyerrflag; goto YYerract
        !            12: 
        !            13: static code    *breakloc       = NULL; /* where to go on break statement */
        !            14: static code    *contloc        = NULL; /* where to go on continue statement */
        !            15: static dicent  *retfrom        = NULL; /* what function to return from */
        !            16: static dicent  **dvec;                 /* list of locals */
        !            17: static dicent  **pardvec;              /* list of formal parameters */
        !            18: static dicent  **autdvec;              /* list of automatic variables */
        !            19: static int     ldvec;                  /* length of dvec */
        !            20: static int     lpardvec;               /* length of pardvec */
        !            21: static int     lautdvec;               /* length of autdvec */
        !            22: %}
        !            23: 
        !            24: 
        !            25: %union {
        !            26:        opcode  opcode;
        !            27:        rvalue  *lvalue;
        !            28:        char    *svalue;
        !            29:        dicent  *dvalue;
        !            30:        int     ivalue;
        !            31:        code    *location;
        !            32: }
        !            33: 
        !            34: 
        !            35: %token <lvalue>        NUMBER
        !            36: %token <svalue>        STRING
        !            37: %token <dvalue>        IDENTIFIER
        !            38: %token                 ADDAB   AUTO    BREAK   CONTINUE DECR   DEFINE
        !            39: %token                 DIVAB   DO      DOT     ELSE    EQP      ERROR
        !            40: %token                 EXPAB   FOR     GEP     GTP     IBASE    IF
        !            41: %token                 INCR    LENGTH_ LEP     LTP     MULAB    NEP
        !            42: %token                 OBASE   QUIT    REMAB   RETURN_ SCALE_   SQRT_
        !            43: %token                 SUBAB   WHILE
        !            44: 
        !            45: %type  <opcode>        assignment_op   special_load    special_store
        !            46: %type  <opcode>        function_like_primitive         relational
        !            47: %type  <dvalue>        local
        !            48: %type  <ivalue>        argument_list   non_empty_argument_list
        !            49: %type  <location>      jump_true       jump_false      else_part
        !            50: %type  <location>      goto            save_loc        save_break
        !            51: %type  <location>      save_continue
        !            52: 
        !            53: %right '='
        !            54: %left  '+'     '-'
        !            55: %left  '*'     '/'     '%'
        !            56: %right '^'
        !            57: %left  INCR    DECR    UMINUS
        !            58: 
        !            59: %%
        !            60: /* Error recovery: allok is FALSE if any syntax or semantic error
        !            61:  * occurred, but the error production will be reduced in all cases
        !            62:  * except one, the case where cstream overflows.
        !            63:  */
        !            64: 
        !            65: session:
        !            66:        /* empty */
        !            67: |      session statement {
        !            68:                emitop(STOP);
        !            69: immfix:                if (allok)
        !            70:                        interp();
        !            71:                litfree(cstream, loc);
        !            72:                loc = cstream;
        !            73:                allok = TRUE;
        !            74:                breakloc = contloc = retfrom = NULL;
        !            75:        }
        !            76: |      session definition {
        !            77:                if (loc[-1].opcode != RETURN) {
        !            78:                        emitop(PGLSC);
        !            79:                        emitnum(&zero);
        !            80:                        emitop(LOAD);
        !            81:                        emitop(RETURN);
        !            82:                        emitid(retfrom);
        !            83:                }
        !            84: deffix:                if (allok)
        !            85:                        install(&retfrom->globalv.fvalue, pardvec, lpardvec,
        !            86:                                autdvec, lautdvec);
        !            87:                else {
        !            88:                        remloc(pardvec, lpardvec);
        !            89:                        remloc(autdvec, lautdvec);
        !            90:                        retfrom->globalt = UNDEFINED;
        !            91:                        litfree(cstream, loc);
        !            92:                }
        !            93:                mpfree(pardvec);
        !            94:                lpardvec = 0;
        !            95:                pardvec = NULL;
        !            96:                mpfree(autdvec);
        !            97:                lautdvec = 0;
        !            98:                autdvec = NULL;
        !            99:                mpfree(dvec);
        !           100:                ldvec = 0;
        !           101:                dvec = NULL;
        !           102:                loc = cstream;
        !           103:                allok = TRUE;
        !           104:                breakloc = contloc = retfrom = NULL;
        !           105:        }
        !           106: |      session error '\n' {
        !           107:                YYERROK;
        !           108:                if (retfrom != NULL)
        !           109:                        goto deffix;
        !           110:                else
        !           111:                        goto immfix;
        !           112:        }
        !           113: ;
        !           114: 
        !           115: /*
        !           116:  *     Statements.
        !           117:  */
        !           118: 
        !           119: statement:
        !           120:        /*
        !           121:         * The code generated for an IF statement  with an else part is as
        !           122:         * follows:
        !           123:         *                      if not condition, goto L1
        !           124:         *                      true part of IF statement
        !           125:         *                      goto L2
        !           126:         *      L1:             false part of IF statement
        !           127:         *      L2:
        !           128:         *
        !           129:         * If there is no ELSE part, then the code generated is as
        !           130:         * follows:
        !           131:         *                      if not condition, goto L1
        !           132:         *                      true part of IF statement
        !           133:         *      L1:
        !           134:         */
        !           135:        IF '(' jump_false ')'                                   /* $1  */
        !           136:                statement                                       /* $5  */
        !           137:                else_part {                                     /* $6  */
        !           138:                        patch($3, $6);
        !           139:                }
        !           140: |
        !           141:        /*
        !           142:         * The code generated for the WHILE statement is as
        !           143:         * follows:
        !           144:         *      CONTINUE:       if condition, goto L1
        !           145:         *      BREAK:          goto L2
        !           146:         *      L1:             body of WHILE statement
        !           147:         *                      goto CONTINUE
        !           148:         *      L2:
        !           149:         */
        !           150:        WHILE save_continue '(' jump_true ')'                   /* $1  */
        !           151:                save_break goto                                 /* $6  */
        !           152:                save_loc statement                              /* $8  */
        !           153:                goto {                                          /* $10 */
        !           154:                        patch($4, $8);
        !           155:                        patch($7, loc);
        !           156:                        patch($10, contloc);
        !           157:                        breakloc = $6;                  /* restore break */
        !           158:                        contloc = $2;                   /* restore continue */
        !           159:                }
        !           160: |
        !           161:        /*
        !           162:         * The code produced for the FOR statement is as
        !           163:         * follows:
        !           164:         *                      initialization expression
        !           165:         *      L1:             if condition, goto L3
        !           166:         *      BREAK:          goto L4
        !           167:         *      CONTINUE:       increment expression
        !           168:         *                      goto L1
        !           169:         *      L3:             body of FOR statement
        !           170:         *                      goto CONTINUE
        !           171:         *      L4:
        !           172:         */
        !           173:        FOR '(' optional_expression_list';'                     /* $1  */
        !           174:                save_loc jump_true ';'                          /* $5  */
        !           175:                save_break goto                                 /* $8  */
        !           176:                save_continue optional_expression_list ')'      /* $10 */
        !           177:                goto                                            /* $13 */
        !           178:                save_loc statement                              /* $14 */
        !           179:                goto {                                          /* $16 */
        !           180:                        patch($6, $14);
        !           181:                        patch($9, loc);
        !           182:                        patch($13, $5);
        !           183:                        patch($16, contloc);
        !           184:                        breakloc = $8;
        !           185:                        contloc = $10;
        !           186:                }
        !           187: |
        !           188:        /*
        !           189:         * The code produced for the DO-WHILE statement is as
        !           190:         * follows:
        !           191:         *                      goto L1
        !           192:         *      BREAK:          goto L3
        !           193:         *      CONTINUE:       goto L2
        !           194:         *      L1:             body of DO-WHILE statement
        !           195:         *      L2:             if condition, goto L1
        !           196:         *      L3:
        !           197:         */
        !           198:        DO goto                                                 /* $1  */
        !           199:                save_break goto                                 /* $3  */
        !           200:                save_continue goto                              /* $5  */
        !           201:                save_loc statement WHILE '('                    /* $7  */
        !           202:                save_loc jump_true ')' end_of_statement {       /* $11 */
        !           203:                        patch($2, $7);
        !           204:                        patch($4, loc);
        !           205:                        patch($6, $11);
        !           206:                        patch($12, $7);
        !           207:                        breakloc = $3;
        !           208:                        contloc = $5;
        !           209:                }
        !           210: |      BREAK end_of_statement {
        !           211:                if (breakloc == NULL) {
        !           212:                        gerror("Break not in loop");
        !           213:                        YYERROR;
        !           214:                }
        !           215:                emitop(BRALW);
        !           216:                emitaddr(breakloc);
        !           217:        }
        !           218: |      CONTINUE end_of_statement {
        !           219:                if (contloc == NULL) {
        !           220:                        gerror("Continue not in loop");
        !           221:                        YYERROR;
        !           222:                }
        !           223:                emitop(BRALW);
        !           224:                emitaddr(contloc);
        !           225:        }
        !           226: |      RETURN_ end_of_statement {
        !           227:                if (retfrom == NULL) {
        !           228:                        gerror("Return not in function");
        !           229:                        YYERROR;
        !           230:                }
        !           231:                emitop(PGLSC);
        !           232:                emitnum(&zero);
        !           233:                emitop(LOAD);
        !           234:                emitop(RETURN);
        !           235:                emitid(retfrom);
        !           236:        }
        !           237: |      RETURN_ expression end_of_statement {
        !           238:                if (retfrom == NULL) {
        !           239:                        gerror("Return not in function");
        !           240:                        YYERROR;
        !           241:                }
        !           242:                emitop(RETURN);
        !           243:                emitid(retfrom);
        !           244:        }
        !           245: |      assignment_expression end_of_statement {
        !           246:                emitop(POP);
        !           247:        }
        !           248: |      non_assignment_expression end_of_statement {
        !           249:                emitop(PRNUM);
        !           250:                emitop(PRNL);
        !           251:        }
        !           252: |      non_assignment_expression '$' end_of_statement {
        !           253:                emitop(PRNUM);
        !           254:        }
        !           255: |      STRING end_of_statement {
        !           256:                emitop(PRSTR);
        !           257:                emitstr($1);
        !           258:                emitop(PRNL);
        !           259:        }
        !           260: |      STRING '$' end_of_statement {
        !           261:                emitop(PRSTR);
        !           262:                emitstr($1);
        !           263:        }
        !           264: |      '{' statement_list '}'
        !           265: |      QUIT end_of_statement {
        !           266:                emitop(EXIT);
        !           267:        }
        !           268: |      end_of_statement
        !           269: ;
        !           270: 
        !           271: end_of_statement:
        !           272:        ';'
        !           273: |      '\n'
        !           274: ;
        !           275: 
        !           276: statement_list:
        !           277:        /* empty */
        !           278: |      statement_list statement
        !           279: ;
        !           280: 
        !           281: else_part:
        !           282:        /* empty */ {
        !           283:                $$ = loc;
        !           284:        }
        !           285: |      ELSE goto save_loc statement {
        !           286:                $$ = $3;
        !           287:                patch($2, loc);
        !           288:        }
        !           289: ;
        !           290: 
        !           291: optional_expression_list:
        !           292:        /* empty */
        !           293: |      non_empty_expression_list
        !           294: ;
        !           295: 
        !           296: non_empty_expression_list:
        !           297:        expression {
        !           298:                emitop(POP);
        !           299:        }
        !           300: |      non_empty_expression_list ',' expression {
        !           301:                emitop(POP);
        !           302:        }
        !           303: ;
        !           304: 
        !           305: goto:
        !           306:        /* empty */ {
        !           307:                emitop(BRALW);
        !           308:                $$ = emitzap;
        !           309:        }
        !           310: ;
        !           311: 
        !           312: save_loc:
        !           313:        /* empty */ {
        !           314:                $$ = loc;
        !           315:        }
        !           316: ;
        !           317: 
        !           318: save_break:
        !           319:        /* empty */ {
        !           320:                $$ = breakloc;
        !           321:                breakloc = loc;
        !           322:        }
        !           323: ;
        !           324: 
        !           325: save_continue:
        !           326:        /* empty */ {
        !           327:                $$ = contloc;
        !           328:                contloc = loc;
        !           329:        }
        !           330: ;
        !           331: 
        !           332: /*
        !           333:  *     Function definition.
        !           334:  */
        !           335: 
        !           336: definition:
        !           337:        definition_header '(' parameter_list ')'                /* $1 */
        !           338:                optional_nl '{' '\n'                            /* $5 */
        !           339:                optional_auto statement_list '}'                /* $8 */
        !           340: ;
        !           341: 
        !           342: definition_header:
        !           343:        DEFINE IDENTIFIER {
        !           344:                if (chkfunc($2)) {
        !           345:                        retfrom = $2;
        !           346:                } else {
        !           347:                        YYERROR;
        !           348:                }
        !           349:        }
        !           350: ;
        !           351: 
        !           352: parameter_list:
        !           353:        /* empty */
        !           354: |      non_empty_local_list {
        !           355:                pardvec = dvec;
        !           356:                lpardvec = ldvec;
        !           357:                locaddr(pardvec, lpardvec, 0);
        !           358:                dvec = NULL;
        !           359:                ldvec = 0;
        !           360:        }
        !           361: ;
        !           362: 
        !           363: optional_auto:
        !           364:        /* empty */
        !           365: |      AUTO non_empty_local_list end_of_statement {
        !           366:                autdvec = dvec;
        !           367:                lautdvec = ldvec;
        !           368:                locaddr(autdvec, lautdvec, lpardvec);
        !           369:                dvec = NULL;
        !           370:                ldvec = 0;
        !           371:        }
        !           372: ;
        !           373: 
        !           374: non_empty_local_list:
        !           375:        local {
        !           376:                dvec = (dicent **)mpalc(ldvec * sizeof (*dvec));
        !           377:                dvec += ldvec;
        !           378:                *--dvec = $1;
        !           379:        }
        !           380: |      local ',' non_empty_local_list {
        !           381:                *--dvec = $1;
        !           382:        }
        !           383: ;
        !           384: 
        !           385: local:
        !           386:        IDENTIFIER {
        !           387:                if ($1->localt != UNDEFINED) {
        !           388:                        gerror("Attempt to redeclare %s", $1->word);
        !           389:                        YYERROR;
        !           390:                }
        !           391:                $1->localt = SCALAR;
        !           392:                ++ldvec;
        !           393:                /* $$ = $1 */
        !           394:        }
        !           395: |      IDENTIFIER '[' ']' {
        !           396:                if ($1->localt != UNDEFINED) {
        !           397:                        gerror("Attempt to redeclare %s", $1->word);
        !           398:                        YYERROR;
        !           399:                }
        !           400:                $1->localt = ARRAY;
        !           401:                ++ldvec;
        !           402:                /* $$ = $1 */
        !           403:        }
        !           404: ;
        !           405: 
        !           406: optional_nl:
        !           407:        /* empty */
        !           408: |      '\n'
        !           409: ;
        !           410: 
        !           411: /*
        !           412:  *     Expressions.
        !           413:  */
        !           414: 
        !           415: expression:
        !           416:        assignment_expression
        !           417: |      non_assignment_expression
        !           418: ;
        !           419: 
        !           420: assignment_expression:
        !           421:        l_value '=' expression {
        !           422:                emitop(STORE);
        !           423:        }
        !           424: |      l_value add_r_value assignment_op expression {
        !           425:                emitop($3);
        !           426:                emitop(STORE);
        !           427:        }
        !           428: |      special_store '=' expression {
        !           429:                emitop($1);
        !           430:        }
        !           431: |      special_load assignment_op expression {
        !           432:                emitop($2);
        !           433:                emitop($1);
        !           434:        }
        !           435: ;
        !           436: 
        !           437: non_assignment_expression:
        !           438:        NUMBER {
        !           439:                emitop(PLISC);
        !           440:                emitnum($1);
        !           441:                emitop(LOAD);
        !           442:        }
        !           443: |      l_value {
        !           444:                emitop(LOAD);
        !           445:        }
        !           446: |      special_load
        !           447: |      IDENTIFIER '(' argument_list ')' {
        !           448:                if (chkfunc($1)) {
        !           449:                        emitop(CALL);
        !           450:                        emitid($1);
        !           451:                        emitcnt($3);
        !           452:                } else {
        !           453:                        YYERROR;
        !           454:                }
        !           455:        }
        !           456: |      INCR l_value {
        !           457:                emitop(PRVAL);
        !           458:                emitop(INC);
        !           459:                emitop(STORE);
        !           460:        }
        !           461: |      INCR special_load {
        !           462:                emitop(INC);
        !           463:                emitop($2);
        !           464:        }
        !           465: |      DECR l_value {
        !           466:                emitop(PRVAL);
        !           467:                emitop(DEC);
        !           468:                emitop(STORE);
        !           469:        }
        !           470: |      DECR special_load {
        !           471:                emitop(DEC);
        !           472:                emitop($2);
        !           473:        }
        !           474: |      l_value INCR {
        !           475:                emitop(PRVAL);
        !           476:                emitop(INC);
        !           477:                emitop(STORE);
        !           478:                emitop(DEC);
        !           479:        }
        !           480: |      special_load INCR {
        !           481:                emitop(INC);
        !           482:                emitop($1);
        !           483:                emitop(DEC);
        !           484:        }
        !           485: |      l_value DECR {
        !           486:                emitop(PRVAL);
        !           487:                emitop(DEC);
        !           488:                emitop(STORE);
        !           489:                emitop(INC);
        !           490:        }
        !           491: |      special_load DECR {
        !           492:                emitop(DEC);
        !           493:                emitop($1);
        !           494:                emitop(INC);
        !           495:        }
        !           496: |      '-' non_assignment_expression   %prec UMINUS {
        !           497:                emitop(NEG);
        !           498:        }
        !           499: |      non_assignment_expression '^' non_assignment_expression {
        !           500:                emitop(EXP);
        !           501:        }
        !           502: |      non_assignment_expression '*' non_assignment_expression {
        !           503:                emitop(MUL);
        !           504:        }
        !           505: |      non_assignment_expression '/' non_assignment_expression {
        !           506:                emitop(DIV);
        !           507:        }
        !           508: |      non_assignment_expression '%' non_assignment_expression {
        !           509:                emitop(REM);
        !           510:        }
        !           511: |      non_assignment_expression '+' non_assignment_expression {
        !           512:                emitop(ADD);
        !           513:        }
        !           514: |      non_assignment_expression '-' non_assignment_expression {
        !           515:                emitop(SUB);
        !           516:        }
        !           517: |      '(' expression ')'
        !           518: |      function_like_primitive '(' expression ')' {
        !           519:                emitop($1);
        !           520:        }
        !           521: ;
        !           522: 
        !           523: l_value:
        !           524:        IDENTIFIER {
        !           525:                if (chktype($1, SCALAR))
        !           526:                        sload($1);
        !           527:                else {
        !           528:                        YYERROR;
        !           529:                }
        !           530:        }
        !           531: |      IDENTIFIER '[' expression ']' {
        !           532:                if (chktype($1, ARRAY))
        !           533:                        aeload($1);
        !           534:                else {
        !           535:                        YYERROR;
        !           536:                }
        !           537:        }
        !           538: |      DOT {
        !           539:                emitop(PGLSC);
        !           540:                emitnum(&dot);
        !           541:        }
        !           542: ;
        !           543: 
        !           544: argument:
        !           545:        expression
        !           546: |      IDENTIFIER '[' ']' {
        !           547:                if (chktype($1, ARRAY))
        !           548:                        arload($1);
        !           549:                else {
        !           550:                        YYERROR;
        !           551:                }
        !           552:        }
        !           553: ;
        !           554: 
        !           555: argument_list:
        !           556:        /* empty */ {
        !           557:                $$ = 0;
        !           558:        }
        !           559: |      non_empty_argument_list
        !           560:                /* $$ = $1 */
        !           561: ;
        !           562: 
        !           563: non_empty_argument_list:
        !           564:        argument {
        !           565:                $$ = 1;
        !           566:        }
        !           567: |      non_empty_argument_list ',' argument {
        !           568:                $$ = $1 + 1;
        !           569:        }
        !           570: ;
        !           571: 
        !           572: add_r_value:
        !           573:        /* empty */ {
        !           574:                emitop(PRVAL);
        !           575:        }
        !           576: ;
        !           577: 
        !           578: special_store:
        !           579:        IBASE {
        !           580:                $$ = SIBASE;
        !           581:        }
        !           582: |      OBASE {
        !           583:                $$ = SOBASE;
        !           584:        }
        !           585: |      SCALE_ {
        !           586:                $$ = SSCALE;
        !           587:        }
        !           588: ;
        !           589: 
        !           590: special_load:
        !           591:        IBASE {
        !           592:                emitop(LIBASE);
        !           593:                $$ = SIBASE;
        !           594:        }
        !           595: |      OBASE {
        !           596:                emitop(LOBASE);
        !           597:                $$ = SOBASE;
        !           598:        }
        !           599: |      SCALE_ {
        !           600:                emitop(LSCALE);
        !           601:                $$ = SSCALE;
        !           602:        }
        !           603: ;
        !           604: 
        !           605: assignment_op:
        !           606:        ADDAB {
        !           607:                $$ = ADD;
        !           608:        }
        !           609: |      SUBAB {
        !           610:                $$ = SUB;
        !           611:        }
        !           612: |      MULAB {
        !           613:                $$ = MUL;
        !           614:        }
        !           615: |      DIVAB {
        !           616:                $$ = DIV;
        !           617:        }
        !           618: |      REMAB {
        !           619:                $$ = REM;
        !           620:        }
        !           621: |      EXPAB {
        !           622:                $$ = EXP;
        !           623:        }
        !           624: ;
        !           625: 
        !           626: function_like_primitive:
        !           627:        SQRT_ {
        !           628:                $$ = SQRT;
        !           629:        }
        !           630: |      LENGTH_ {
        !           631:                $$ = LENGTH;
        !           632:        }
        !           633: |      SCALE_ {
        !           634:                $$ = SCALE;
        !           635:        }
        !           636: ;
        !           637: 
        !           638: /*
        !           639:  *     Conditionals.
        !           640:  */
        !           641: 
        !           642: jump_true:
        !           643:        /* empty */ {
        !           644:                emitop(BRALW);
        !           645:                $$ = emitzap;
        !           646:        }
        !           647: |      non_assignment_expression relational non_assignment_expression {
        !           648:                emitop($2);
        !           649:                $$ = emitzap;
        !           650:        }
        !           651: ;
        !           652: 
        !           653: jump_false:
        !           654:        /* empty */ {
        !           655:                emitop(BRNEV);
        !           656:                $$ = emitzap;
        !           657:        }
        !           658: |      non_assignment_expression relational non_assignment_expression {
        !           659:                emitop(negate($2));
        !           660:                $$ = emitzap;
        !           661:        }
        !           662: ;
        !           663: 
        !           664: relational:
        !           665:        LTP {
        !           666:                $$ = BRLT;
        !           667:        }
        !           668: |      LEP {
        !           669:                $$ = BRLE;
        !           670:        }
        !           671: |      EQP {
        !           672:                $$ = BREQ;
        !           673:        }
        !           674: |      GEP {
        !           675:                $$ = BRGE;
        !           676:        }
        !           677: |      GTP {
        !           678:                $$ = BRGT;
        !           679:        }
        !           680: |      NEP {
        !           681:                $$ = BRNE;
        !           682:        }
        !           683: ;
        !           684: 
        !           685: %%
        !           686: 
        !           687: /*
        !           688:  *     Yyerror is the error routine called on a syntax error by
        !           689:  *     yyparse.
        !           690:  */
        !           691: 
        !           692: yyerror(m)
        !           693: char *m;
        !           694: {
        !           695:        register struct yytname *ptr;
        !           696: 
        !           697:        for (ptr = yytnames; ptr->tn_name != NULL; ++ptr)
        !           698:                if (ptr->tn_val == yychar)
        !           699:                        return gerror("%s at %s", m, ptr->tn_name);
        !           700:        return gerror("%s", m);
        !           701: }

unix.superglobalmegacorp.com

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