Annotation of researchv10no/cmd/twig/twig.y, revision 1.1

1.1     ! root        1: %term ERROR
        !             2: %{
        !             3: #include "common.h"
        !             4: #include "code.h"
        !             5: #include "sym.h"
        !             6: #define UNDEFINED -1
        !             7: #define GIVENUP        -2
        !             8: 
        !             9: int debug_flag = 0;
        !            10: int Dflag = 0;
        !            11: int tflag = 0;
        !            12: int line_xref_flag = 0;
        !            13: int ntrees = 0;
        !            14: int nerrors = 0;
        !            15: int fatalerrors = 0;
        !            16: int tree_lineno;
        !            17: FILE *outfile;
        !            18: FILE *symfile;
        !            19: Code *epilogue;
        !            20: 
        !            21: SymbolEntry ErrorSymbol;
        !            22: %}
        !            23: %union {
        !            24:        Node *y_nodep;
        !            25:        SymbolEntry *y_symp;
        !            26:        Code *y_code;
        !            27:        int y_int;
        !            28: }
        !            29: %start pattern_spec
        !            30: %term K_NODE K_LABEL K_PROLOGUE K_CONST K_INSERT
        !            31: %term K_COST K_ACTION
        !            32: %token <y_symp> ID
        !            33: %token <y_int> NUMBER
        !            34: %token <y_code> CBLOCK
        !            35: %type <y_nodep> tree tree_list
        !            36: %type <y_symp> id_list label assoc_list assoc assoc_list2 assoc2
        !            37: %type <y_symp> const_list const_def
        !            38: %type <y_int> arity_spec constant
        !            39: %type <y_symp> action cost
        !            40: %%
        !            41: 
        !            42: pattern_spec: declarations patternsOrInserts = 
        !            43:        { if (nerrors==0) machine_build(); };
        !            44: 
        !            45: declarations: declarations decl
        !            46:                | decl;
        !            47: 
        !            48: decl:  K_NODE assoc_list ';' = { SymbolEnterList ($2, A_NODE); }
        !            49: 
        !            50:        | K_NODE assoc_list2 ';'
        !            51:                = {
        !            52:                        SymbolEnterList($2, A_NODE);
        !            53:                        SymbolCheckNodeValues();
        !            54:                }
        !            55: 
        !            56:        | K_CONST const_list ';' = { SymbolEnterList ($2, A_CONST); }
        !            57: 
        !            58:        | K_LABEL id_list ';' = { SymbolEnterList ($2, A_LABEL); }
        !            59: 
        !            60:        | K_PROLOGUE CBLOCK ';' = { CodeWrite(outfile, $2); CodeFreeBlock($2); }
        !            61: 
        !            62:        | K_COST ID CBLOCK ';'
        !            63:                = { $2->sd.ca.code = $3; $2->sd.ca.assoc = NULL;
        !            64:                 SymbolEnter ($2, A_COST); }
        !            65: 
        !            66:        | K_ACTION ID CBLOCK ';'
        !            67:                = { $2->sd.ca.code = $3; $2->sd.ca.assoc = NULL;
        !            68:                 SymbolEnter ($2, A_ACTION); }
        !            69:  
        !            70:        | K_PROLOGUE error ';'
        !            71:        | K_ACTION error ';'
        !            72:        | K_COST error ';'
        !            73:        ;
        !            74: 
        !            75: /*
        !            76:  * The rule id_list, assoc_list, and const_list build lists of identifiers.
        !            77:  * The field "next" is used as a link.  This field is also used by the symbol
        !            78:  * table manager and thus the next field may not be used unless the identifiers
        !            79:  * have not already been defined.
        !            80:  */
        !            81: 
        !            82: id_list:
        !            83:        id_list ID = {
        !            84:                                if(CheckIsUndefined($2)) {
        !            85:                                        $2->next = $1;
        !            86:                                        $$ = $2;
        !            87:                                } else $$ = $1;
        !            88:                        }
        !            89:        | ID { if(CheckIsUndefined($1)) $$ = $1; else $$ = NULL; }
        !            90:        | id_list error;
        !            91: 
        !            92: /*
        !            93:  * Assoc_list2 allows user assignment of node values
        !            94:  */
        !            95: assoc_list2:
        !            96:        assoc_list2 assoc2
        !            97:                = {
        !            98:                        if($2->attr==A_ERROR)
        !            99:                                $$ = $1;
        !           100:                        else { $2->next = $1; $$ = $2; }
        !           101:                }
        !           102:        | assoc2 { $$ = $1->attr==A_ERROR ? NULL : $1; }
        !           103:        | assoc_list2 error;
        !           104: 
        !           105: assoc_list:
        !           106:        assoc_list assoc = { 
        !           107:                                        if($2->attr==A_ERROR) $$ = $1;
        !           108:                                        else { $2->next = $1; $$ = $2; }
        !           109:                                }
        !           110:        | assoc { $$ = $1->attr==A_ERROR ? NULL : $1; }
        !           111:        | assoc_list error;
        !           112: 
        !           113: assoc: ID arity_spec
        !           114:                = {
        !           115:                        if (CheckIsUndefined($1)) {
        !           116:                                $1->sd.arity = $2; $$ = $1;
        !           117:                        } else $$ = &ErrorSymbol;
        !           118:                };
        !           119: 
        !           120: assoc2:
        !           121:        ID arity_spec '=' constant {
        !           122:                                if(CheckIsUndefined($1)) {
        !           123:                                        $1->unique = $4; $1->sd.arity = $2;
        !           124:                                        $$ = $1;
        !           125:                                } else $$ = &ErrorSymbol;
        !           126:                        };
        !           127: 
        !           128: arity_spec:
        !           129:        '(' constant ')' = { $$ = $2; };
        !           130:        | '(' '*' ')' = { $$=GIVENUP; };
        !           131:        | = { $$ = UNDEFINED; };
        !           132: 
        !           133: const_list:
        !           134:        const_list const_def = {
        !           135:                                if ($2->attr==A_ERROR) $$ = $1;
        !           136:                                else { $2->next = $1; $$ = $2; }
        !           137:                        }
        !           138:        | const_def { $$ = $1->attr==A_ERROR ? NULL : $1; }
        !           139:        | const_list error;
        !           140: 
        !           141: const_def:
        !           142:        ID '=' constant = {
        !           143:                                if(CheckIsUndefined($1)) {
        !           144:                                        $1->sd.cvalue = $3; $$ = $1;
        !           145:                                } else $$ = &ErrorSymbol;
        !           146:                };
        !           147: 
        !           148: constant:
        !           149:        NUMBER
        !           150:        | ID = {
        !           151:                if(!CheckIsDefined($1)) $$ = UNDEFINED;
        !           152:                else if($1->attr!=A_CONST) {
        !           153:                        sem_error("non-constant id used");
        !           154:                        $$ = -1;
        !           155:                } else $$ = $1->sd.cvalue;
        !           156:        };
        !           157: 
        !           158: patternsOrInserts: patternsOrInserts pattern
        !           159:        | patternsOrInserts insert
        !           160:        | insert
        !           161:        | pattern
        !           162:        ;
        !           163: 
        !           164: insert:        K_INSERT CBLOCK ';' = { epilogue = CodeAppend(epilogue, $2); }
        !           165:        | K_INSERT error ';'
        !           166:        ;
        !           167: 
        !           168: pattern:
        !           169:        label ':' tree cost action ';' = {
        !           170:                    if ($1->attr==A_ERROR) {
        !           171:                        error(0, "\"label: tree\" pair ignored");
        !           172:                        TreeFree($3);
        !           173:                    } else {
        !           174:                        if(nerrors==0)
        !           175:                                cgotofn(SymbolEnterTreeIntoLabel($1,
        !           176:                                        $3, $4, $5, tree_lineno));
        !           177:                        if(debug_flag&DB_TREE)
        !           178:                                TreePrint($3, 1);
        !           179:                    }
        !           180:                }
        !           181:        | error ';' ;
        !           182: 
        !           183: action:        '=' CBLOCK { SymbolEntry *sp = SymbolAllocate (SymbolGenUnique());
        !           184:                sp->sd.ca.code = $2; sp->sd.ca.assoc = NULL;
        !           185:                SymbolEnter(sp, A_ACTION); $$ = sp; }
        !           186:        | '=' ID { if(CheckIsDefined($2)) {
        !           187:                        if ($2->attr!=A_ACTION) {
        !           188:                                sem_error ("non action id: %s", $2->name);
        !           189:                                $$ = &ErrorSymbol;
        !           190:                        } else $$ = $2;
        !           191:                } else $$ = &ErrorSymbol; }
        !           192:        | { $$ = NULL;};
        !           193: 
        !           194: cost:  CBLOCK { SymbolEntry *sp = SymbolAllocate (SymbolGenUnique());
        !           195:                sp->sd.ca.code = $1; sp->sd.ca.assoc = NULL;
        !           196:                SymbolEnter (sp, A_COST); $$ = sp;
        !           197:                }
        !           198:        | ID { if (CheckIsDefined($1)) {
        !           199:                        if ($1->attr!=A_COST) {
        !           200:                                sem_error ("non cost id: %s", $1->name);
        !           201:                                $$ = &ErrorSymbol;
        !           202:                        } else $$ = $1;
        !           203:                } else $$ = &ErrorSymbol; }
        !           204:        | { $$ = NULL; };
        !           205: 
        !           206: /* labels play the same role that non-terminals do in YACC */
        !           207: label: ID = {
        !           208:                tree_lineno = yyline;   /* record line no */
        !           209:                if(!CheckIsDefined($1))
        !           210:                        $1->attr = A_ERROR;
        !           211:                else if(!is_label($1)) {
        !           212:                        sem_error("non label id: %s", $1->name);
        !           213:                        $1->attr = A_ERROR;
        !           214:                }
        !           215:                $$ = $1;
        !           216:        };
        !           217: 
        !           218: tree:  ID {CheckIsNodeOrPred($1);} '(' tree_list ')'
        !           219:        = {
        !           220:                int count;
        !           221:                Node *ap; 
        !           222:                /* check the arity of the node */
        !           223:                for(count=0, ap = $4; ap!=NULL; ap=ap->siblings) count++;
        !           224:                switch($1->attr) {
        !           225:                        case A_NODE:
        !           226:                                set_arity($1, &$1->sd.arity, count);
        !           227:                                break;
        !           228:                }
        !           229: 
        !           230:                $$ = TreeBuild ($1, $4);
        !           231:        }
        !           232:        | ID
        !           233:        = {
        !           234:                CheckIsDefined($1);
        !           235:                switch ($1->attr) {
        !           236:                        case A_NODE:
        !           237:                                set_arity($1, &$1->sd.arity, 0);
        !           238:                                break;
        !           239:                }
        !           240:                $$ = TreeBuild ($1, NULL);
        !           241:        };
        !           242: 
        !           243: tree_list: tree_list ',' tree = {
        !           244:                        /*
        !           245:                         * build sibling list in reverse order TreeBuild will
        !           246:                         * put it right later.
        !           247:                         */
        !           248:                        $3->siblings = $1;
        !           249:                        $$ = $3;
        !           250:                }
        !           251:        | tree = { $1->siblings = NULL; $$ = $1; }
        !           252:        | error { $$ = NULL; };
        !           253:        | tree_list error;
        !           254: 
        !           255: %%
        !           256: 
        !           257: extern char *process_suffix();
        !           258: 
        !           259: set_arity(symp, arityp, count)
        !           260:        SymbolEntry *symp;
        !           261:        int *arityp;
        !           262:        int count;
        !           263: {
        !           264:        if(*arityp!=GIVENUP) {
        !           265:                if (*arityp==UNDEFINED)
        !           266:                        *arityp = count;
        !           267:                else if (*arityp!=count) {
        !           268:                        sem_error("inconsistent arity for %s", symp->name);
        !           269:                        *arityp = GIVENUP;
        !           270:                }
        !           271:        }
        !           272: }
        !           273: 
        !           274: is_node(symp)
        !           275:        SymbolEntry *symp;
        !           276: { return(symp->attr==A_NODE); }
        !           277: 
        !           278: is_label(symp)
        !           279:        SymbolEntry *symp;
        !           280: { return(symp->attr==A_LABEL); }
        !           281: 
        !           282: CheckIsNodeOrPred (symp)
        !           283:        SymbolEntry *symp;
        !           284: {
        !           285:        if (symp->attr==A_ERROR)
        !           286:                return;
        !           287:        if (symp->attr!=A_NODE)
        !           288:                sem_error ("non-node identifier %s", symp->name);
        !           289: }
        !           290: 
        !           291: CheckIsUndefined(symp)
        !           292:        SymbolEntry *symp;
        !           293: {
        !           294:        if (symp->attr==A_ERROR)
        !           295:                return(0);
        !           296:        if (symp->attr!=A_UNDEFINED) {
        !           297:                sem_error ("multiple declaration: %s", symp->name);
        !           298:                return(0);
        !           299:        } else return(1);
        !           300: }
        !           301: 
        !           302: CheckIsDefined(symp)
        !           303:        SymbolEntry *symp;
        !           304: {
        !           305:        if (symp->attr==A_ERROR)
        !           306:                return(0);
        !           307:        if (symp->attr==A_UNDEFINED) {
        !           308:                sem_error ("undefined identifier: %s", symp->name);
        !           309:                symp->attr=A_ERROR;
        !           310:                return(0);
        !           311:        } else return(1);
        !           312: }
        !           313: 
        !           314: 
        !           315: 
        !           316: /*VARARGS*/
        !           317: yyerror(fmt, s1, s2, s3)
        !           318:        char *fmt, *s1, *s2, *s3;
        !           319: {
        !           320:        fprintf(stderr, "line %d: ", yyline);
        !           321:        fprintf(stderr, fmt, s1, s2, s3);
        !           322:        if (token_buffer[0]!=0)
        !           323:                fprintf(stderr, " at \"%s\"\n", token_buffer);
        !           324: }
        !           325: 
        !           326: /*VARARGS*/
        !           327: yyerror2 (fmt, s1, s2, s3)
        !           328:        char *fmt, *s1, *s2, *s3;
        !           329: {
        !           330:        fprintf(stderr, "line %d: ", yyline);
        !           331:        fprintf(stderr, fmt, s1, s2, s3);
        !           332:        putchar('\n');
        !           333: }
        !           334: 
        !           335: char *cmdnam;
        !           336: char *inFileName;
        !           337: char *outFileName;
        !           338: char prefixFile[100];
        !           339: static char usage[] = "usage: mt [-d] file";
        !           340: #define USAGE  error(1, usage)
        !           341: char *prefix_base = PREFIX_BASE;
        !           342: char *suffix = "c1";
        !           343: 
        !           344: main(argc, argv)
        !           345:        int argc;
        !           346:        char **argv;
        !           347: {
        !           348:        int i;
        !           349:        char *cp;
        !           350: 
        !           351: #ifndef PREFIX_BASE
        !           352:        error(1,"PREFIX_BASE has not been defined; recompile twig");
        !           353: #endif
        !           354: 
        !           355:        cmdnam = argv[0];
        !           356:        argv++;
        !           357:        inFileName = NULL;
        !           358: 
        !           359:        while(--argc > 0) {
        !           360:                if (*argv[0]=='-')
        !           361:                        switch(argv[0][1]) {
        !           362:                        /* to see what each of these flags mean...
        !           363:                         * see common.h */
        !           364:                        case 'd': {
        !           365:                                char *cp;
        !           366:                                for(cp = &argv[0][2]; *cp!='\0'; cp++) 
        !           367:                                        switch(*cp) {
        !           368:                                        case 'l': debug_flag |= DB_LEX; break;
        !           369:                                        case 'm': debug_flag |= DB_MACH; break;
        !           370:                                        case 's': debug_flag |= DB_SYM; break;
        !           371:                                        case 't': debug_flag |= DB_TREE; break;
        !           372:                                        case 'M': debug_flag |= DB_MEM; break;
        !           373:                                        }
        !           374:                                }
        !           375:                                break;
        !           376:                        case 'D': Dflag++; break;
        !           377:                        case 't': tflag++; break;
        !           378:                        case 'w': suffix = process_suffix(&argv[0][2]); break;
        !           379:                        case 'l': prefix_base = &argv[0][2]; break;
        !           380:                        case 'x': line_xref_flag++; break;
        !           381:                        default:
        !           382:                                USAGE;
        !           383:                        }
        !           384:                else inFileName = argv[0];
        !           385:                argv++;
        !           386:        }
        !           387:        if(inFileName==NULL)
        !           388:                USAGE;
        !           389:                        
        !           390:        if(freopen(inFileName, "r", stdin)==NULL)
        !           391:                error(1, "can't open %s", inFileName);
        !           392:        if((cp=strrchr(inFileName, '.'))!=NULL && strcmp(cp,".mt")==0) {
        !           393:                if ((outfile = fopen("walker.c" , "w"))==NULL)
        !           394:                        error(1, "can't write %s", outFileName);
        !           395:                if ((symfile = fopen("symbols.h", "w"))==NULL)
        !           396:                        error(1, "can't write %s", outFileName);
        !           397:        } else error(1, "input file must have suffix .mt");
        !           398: 
        !           399:        ErrorSymbol.attr = A_LABEL;
        !           400:        TreeInit();
        !           401:        SymbolInit();
        !           402:        LexInit();
        !           403:        yyparse();
        !           404: 
        !           405:        SymbolDump();
        !           406:        if(nerrors == 0) {
        !           407:                if(!tflag) {
        !           408:                        FILE *prefix;
        !           409:                        char c;
        !           410:                        sprintf(prefixFile, "%s.%s", prefix_base, suffix);
        !           411:                        prefix = fopen(prefixFile, "r");
        !           412:                        assert(prefix!=NULL);
        !           413:                        if(Dflag)
        !           414:                                fputs("#define DEBUG 1\n", outfile);
        !           415:                        if(line_xref_flag)
        !           416:                                fputs("#define LINE_XREF 1\n", outfile);
        !           417:                        fprintf(outfile,"# line 1 \"%s\"\n", prefixFile);
        !           418:                        while((c=getc(prefix))!=EOF) putc(c, outfile);
        !           419:                }
        !           420:                MachineGen();
        !           421:                SymbolGenerateWalkerCode();
        !           422:                CodeWrite(outfile, epilogue);
        !           423:                CodeFreeBlock(epilogue);
        !           424:        }
        !           425: 
        !           426:        /* cleanup */
        !           427:        cleanup(0);
        !           428: }
        !           429: 
        !           430: cleanup(retcode)
        !           431:        int retcode;
        !           432: {
        !           433:        lexCleanup();
        !           434:        if(retcode==0) {
        !           435:                SymbolFinish();
        !           436:        }
        !           437:        exit(retcode);
        !           438: }
        !           439: 
        !           440: /*VARARGS*/
        !           441: error(rc, fmt, a1, a2, a3)
        !           442:        int rc;
        !           443:        char *fmt, *a1, *a2, *a3;
        !           444: {
        !           445:        fprintf(stderr, "%s: ", cmdnam);
        !           446:        fprintf(stderr, fmt, a1, a2, a3);
        !           447:        putc ('\n', stderr);
        !           448:        if(rc)
        !           449:                exit (rc);
        !           450: }
        !           451: 
        !           452: /*VARARGS*/
        !           453: sem_error (fmt, a1, a2, a3)
        !           454:        char *fmt, *a1, *a2, *a3;
        !           455: {
        !           456:        fprintf (stderr, "line %d: ", yyline);
        !           457:        sem_error2(fmt, a1, a2, a3);
        !           458:        nerrors++;
        !           459:        fatalerrors++;
        !           460: }
        !           461: 
        !           462: /*VARARGS*/
        !           463: sem_error2(fmt, a1, a2, a3)
        !           464:        char *fmt, *a1, *a2, *a3;
        !           465: {
        !           466:        fprintf (stderr, fmt, a1, a2, a3);
        !           467:        putc('\n', stderr);
        !           468:        nerrors++;
        !           469: }
        !           470: 
        !           471: char *
        !           472: process_suffix(suf)
        !           473:        char *suf;
        !           474: {
        !           475:        extern int gen_table2;
        !           476:        if(strcmp(suf,"exper")==0) {
        !           477:                /* experimental walker */
        !           478:                /* expect this to change alot */
        !           479:                gen_table2++;
        !           480:        }
        !           481:        return(suf);
        !           482: }

unix.superglobalmegacorp.com

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