Annotation of researchv10no/cmd/twig/twig.y, revision 1.1.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.