Annotation of 43BSD/contrib/pathalias/parse.y, revision 1.1.1.1

1.1       root        1: %{
                      2: /* pathalias -- by steve bellovin, as told to peter honeyman */
                      3: #ifndef lint
                      4: static char    *sccsid = "@(#)parse.y  8.2 (down!honey) 86/01/29";
                      5: #endif lint
                      6: 
                      7: #include "def.h"
                      8: 
                      9: /* I thank Paul Haahr and Greg Noel for helping to clean this up. */
                     10: %}
                     11: 
                     12: %union {
                     13:        node    *y_node;
                     14:        Cost    y_cost;
                     15:        char    y_net;
                     16:        char    *y_name;
                     17:        struct {
                     18:                node *ys_node;
                     19:                Cost ys_cost;
                     20:                char ys_net;
                     21:                char ys_dir;
                     22:        } y_s;
                     23: }
                     24: 
                     25: %type <y_s>    site
                     26: %type <y_node> links aliases plist network nlist host Psite Site
                     27: %type <y_cost> cost cexpr
                     28: 
                     29: %token <y_name>        SITE HOST
                     30: %token <y_cost>        COST
                     31: %token <y_net> NET
                     32: %token NL PRIVATE
                     33: 
                     34: %left  '+' '-'
                     35: %left  '*' '/'
                     36: 
                     37: %%
                     38: map    :       /* empty */
                     39:        |       map             NL
                     40:        |       map links       NL
                     41:        |       map aliases     NL
                     42:        |       map network     NL
                     43:        |       map private     NL
                     44:        |       error           NL
                     45:        ;
                     46: 
                     47: links  : host site cost {
                     48:                if (GATEWAYED($2.ys_node))
                     49:                        addgateway($1, $2.ys_node, $3, $2.ys_net, $2.ys_dir);
                     50:                else
                     51:                        addlink($1, $2.ys_node, $3, $2.ys_net, $2.ys_dir);
                     52:          }
                     53:                                
                     54:        | links ',' site cost {
                     55:                if (GATEWAYED($3.ys_node))
                     56:                        addgateway($1, $3.ys_node, $4, $3.ys_net, $3.ys_dir);
                     57:                else
                     58:                        addlink($1, $3.ys_node, $4, $3.ys_net, $3.ys_dir);
                     59:          }
                     60:        | links ','     /* permit this benign error */
                     61:        ;
                     62: 
                     63: aliases        : host '=' Site         {alias($1, $3);}
                     64:        | aliases ',' Site      {alias($1, $3);}
                     65:        | aliases ','   /* permit this benign error */
                     66:        ;
                     67: 
                     68: network        : host '=' '{' nlist '}' cost   {fixnet($1, $4, $6, DEFNET, DEFDIR);}
                     69:        | host '=' NET '{' nlist '}' cost       {fixnet($1, $5, $7, $3, LRIGHT);}
                     70:        | host '=' '{' nlist '}' NET cost       {fixnet($1, $4, $7, $6, LLEFT);}
                     71:        ;
                     72: 
                     73: private        : PRIVATE '{' plist '}' ;
                     74: 
                     75: host   : HOST          {$$ = addnode($1);}
                     76:        | PRIVATE       {$$ = addnode("private");}
                     77:        ;
                     78: 
                     79: Site   : SITE  {$$ = addnode($1);} ;
                     80: 
                     81: site   : Site {
                     82:                $$.ys_node = $1;
                     83:                $$.ys_net = DEFNET;
                     84:                $$.ys_dir = DEFDIR;
                     85:          }
                     86:        | NET Site {
                     87:                $$.ys_node = $2;
                     88:                $$.ys_net = $1;
                     89:                $$.ys_dir = LRIGHT;
                     90:          }
                     91:        | Site NET {
                     92:                $$.ys_node = $1;
                     93:                $$.ys_net = $2;
                     94:                $$.ys_dir = LLEFT;
                     95:          }
                     96:        ;
                     97: 
                     98: Psite  : SITE  {$$ = addprivate($1);} ;
                     99: 
                    100: plist  : Psite         {$1->n_flag |= ISPRIVATE;}
                    101:        | plist ',' Psite       {$3->n_flag |= ISPRIVATE;}
                    102:        | plist ','     /* permit this benign error  */
                    103:        ;
                    104: 
                    105: nlist  : Site
                    106:        | nlist ',' Site {
                    107:                if ($3->n_net == 0) {
                    108:                        $3->n_net = $1;
                    109:                        $$ = $3;
                    110:                }
                    111:          }
                    112:        | nlist ','     /* permit this benign error */
                    113:        ;
                    114:                
                    115: cost   : {$$ = DEFCOST;        /* empty -- cost is always optional */}
                    116:        | '(' {Scanstate = COSTING;} cexpr {Scanstate = OTHER;} ')'
                    117:                {$$ = $3;}
                    118:        ;
                    119: 
                    120: cexpr  : COST
                    121:        | '(' cexpr ')'   {$$ = $2;}
                    122:        | cexpr '+' cexpr {$$ = $1 + $3;}
                    123:        | cexpr '-' cexpr {$$ = $1 - $3;}
                    124:        | cexpr '*' cexpr {$$ = $1 * $3;}
                    125:        | cexpr '/' cexpr {
                    126:                if ($3 == 0)
                    127:                        yyerror("zero divisor\n");
                    128:                else
                    129:                        $$ = $1 / $3;
                    130:          }
                    131:        ;
                    132: %%
                    133: 
                    134: yyerror(s)
                    135: char *s;
                    136: {
                    137:        /* a concession to bsd error(1) */
                    138:        if (Cfile)
                    139:                fprintf(stderr, "\"%s\", ", Cfile);
                    140:        else
                    141:                fprintf(stderr, "%s: ", ProgName);
                    142:        fprintf(stderr, "line %d: %s\n", Lineno, s);
                    143: }
                    144: 
                    145: /*
                    146:  * patch in the costs of getting on/off the network.
                    147:  *
                    148:  * for each network member on netlist, add links:
                    149:  *     network -> member       cost = 0;
                    150:  *     member -> network       cost = parameter.
                    151:  *
                    152:  * if network and member both require gateways, assume network
                    153:  * is a gateway to member (but not v.v., to avoid such travesties
                    154:  * as topaz!seismo.css.gov.edu.rutgers).
                    155:  *
                    156:  * note that members can have varying costs to a network, by suitable
                    157:  * multiple declarations.  this is a feechur, albeit a useless one.
                    158:  */
                    159: fixnet(network, nlist, cost, netchar, netdir)
                    160: register node  *network;
                    161: node   *nlist;
                    162: Cost   cost;
                    163: char   netchar, netdir;
                    164: {
                    165:        register node   *member, *nextnet;
                    166:        link    *l;
                    167: 
                    168:        network->n_flag |= NNET;
                    169: 
                    170:        /* now insert the links */
                    171:        for (member = nlist ; member; member = nextnet) {
                    172:                /* network -> member, cost is 0 */
                    173:                if (GATEWAYED(network) && GATEWAYED(member))
                    174:                        (void) addgateway(network, member, (Cost) 0, netchar, netdir);
                    175:                else
                    176:                        (void) addlink(network, member, (Cost) 0, netchar, netdir);
                    177: 
                    178:                /* member -> network, cost is parameter */
                    179:                (void) addlink(member, network, cost, netchar, netdir);
                    180:                nextnet = member->n_net;
                    181:                member->n_net = 0;      /* clear for later use */
                    182:        }
                    183: }
                    184: 
                    185: /* scanner */
                    186: 
                    187: #define LBRACE '{'
                    188: #define RBRACE '}'
                    189: #define LPAREN '('
                    190: #define RPAREN ')'
                    191: #define QUOTE '"'
                    192: 
                    193: Cost isacost();
                    194: 
                    195: yylex()
                    196: {
                    197:        register int    c;
                    198:        Cost    cost;
                    199:        char    errbuf[128];
                    200:        static char     buf[128];       /* for return to yacc part */
                    201: 
                    202: tailrecursion:
                    203:        if (feof(stdin) && yywrap())
                    204:                return(EOF);
                    205: 
                    206:        if ((c = getchar()) == EOF)
                    207:                goto tailrecursion;
                    208: 
                    209:        while (c == ' ' || c == '\t')
                    210:                c = getchar();
                    211: 
                    212:        if (c == '\n') {
                    213:                Lineno++;
                    214:                c = getchar();
                    215:                if (c == ' ' || c == '\t')
                    216:                        goto tailrecursion;
                    217:                ungetc(c, stdin);
                    218:                Scanstate = NEWLINE;
                    219:                return(NL);
                    220:        }
                    221: 
                    222:        if (c == '#') {
                    223:                while ((c = getchar()) != '\n')
                    224:                        if (c == EOF)
                    225:                                goto tailrecursion;
                    226:                ungetc(c, stdin);
                    227:                goto tailrecursion;
                    228:        }
                    229: 
                    230:        ungetc(c, stdin);
                    231: 
                    232:        switch(Scanstate) {
                    233:        case COSTING:
                    234:                if (isdigit(c)) {
                    235:                        cost = 0;
                    236:                        for (c = getchar(); isdigit(c); c = getchar())
                    237:                                cost = (cost * 10) + c - '0';
                    238: 
                    239:                        ungetc(c, stdin);
                    240:                        yylval.y_cost = cost;
                    241:                        return(COST);
                    242:                }
                    243: 
                    244:                
                    245:                if (getword(buf) == 0) {
                    246:                        if ((yylval.y_cost = isacost(buf)) == 0) {
                    247:                                sprintf(errbuf, "unknown cost (%s), using default", buf);
                    248:                                yyerror(errbuf);
                    249:                                yylval.y_cost = DEFCOST;
                    250:                        }
                    251:                        return(COST);
                    252:                }
                    253: 
                    254:                return(getchar());      /* can't be EOF */
                    255: 
                    256:        case NEWLINE:
                    257:                Scanstate = OTHER;
                    258:                if (getword(buf) != 0)
                    259:                        return(getchar());      /* can't be EOF */
                    260:                /* `private' (but not `"private"')? */
                    261:                if (c == 'p' && strcmp(buf, "private") == 0)
                    262:                        return(PRIVATE);
                    263: 
                    264:                yylval.y_name = buf;
                    265:                return(HOST);
                    266:        }
                    267: 
                    268:        if (getword(buf) == 0) {
                    269:                yylval.y_name = buf;
                    270:                return(SITE);
                    271:        }
                    272: 
                    273:        c = getchar();  /* can't be EOF */
                    274: 
                    275:        if (index(Netchars, c)) {
                    276:                yylval.y_net = c;
                    277:                return(NET);
                    278:        }
                    279: 
                    280:        return(c);
                    281: }
                    282: 
                    283: /*
                    284:  * fill str with the next word in [0-9A-Za-z][-._0-9A-Za-z]+ or a quoted
                    285:  * string that contains no newline.  return -1 on failure or EOF, 0 o.w.
                    286:  */ 
                    287: getword(str)
                    288: register char  *str;
                    289: {
                    290:        register int    c;
                    291: 
                    292:        c = getchar();
                    293:        if (c == QUOTE) {
                    294:                for ( ; (*str = getchar()) != '"'; str++) {
                    295:                        if (*str == '\n') {
                    296:                                yyerror("newline in quoted string\n");
                    297:                                ungetc('\n', stdin);
                    298:                                return(-1);
                    299:                        }
                    300:                }
                    301:                *str = 0;
                    302:                return(0);
                    303:        }
                    304: 
                    305:        /* host name must start with alphanumeric or `.' */
                    306:        if (!isalnum(c) && c != '.') {
                    307:                ungetc(c, stdin);
                    308:                return(-1);
                    309:        }
                    310: 
                    311: yymore:
                    312:        do {
                    313:                *str++ = c;
                    314:                c = getchar();
                    315:        } while (isalnum(c) || c == '.' || c == '_');
                    316: 
                    317:        if (c == '-' && Scanstate != COSTING)
                    318:                goto yymore;
                    319: 
                    320:        ungetc(c, stdin);
                    321:        *str = 0;
                    322:        return(0);
                    323: }
                    324: 
                    325: static struct ctable {
                    326:        char *cname;
                    327:        Cost cval;
                    328: } ctable[] = {
                    329:        /*
                    330:         * this list is searched sequentially (with strcmps!).
                    331:         * it is too long.  (they are ordered by frequency of
                    332:         * appearance in a "typical" dataset.)
                    333:         *
                    334:         * adding a 0 cost token breaks isacost().  don't do it.
                    335:         */
                    336:        {"DEMAND", 300},
                    337:        {"DAILY", 5000},
                    338:        {"DIRECT", 200},
                    339:        {"EVENING", 1800},
                    340:        {"LOCAL", 25},
                    341:        {"LOW", 5},     /* baud rate penalty */
                    342:        {"HOURLY", 500},
                    343:        {"POLLED", 5000},
                    344:        {"DEDICATED", 95},
                    345:        {"WEEKLY", 30000},
                    346:        {"DEAD", INF/2},
                    347:        {"HIGH", -5},   /* baud rate bonus */
                    348:        /* the remainder are reviled */
                    349:        {"ARPA", 100},
                    350:        {"DIALED", 300},
                    351:        {"A", 300},
                    352:        {"B", 500},
                    353:        {"C", 1800},
                    354:        {"D", 5000},
                    355:        {"E", 30000},
                    356:        {"F", INF/2},
                    357:        0
                    358: };
                    359: 
                    360: STATIC Cost
                    361: isacost(buf)
                    362: register char  *buf;
                    363: {
                    364:        register struct ctable  *ct;
                    365: 
                    366:        for (ct = ctable; ct->cname; ct++)
                    367:                if (strcmp(buf, ct->cname) == 0)
                    368:                        return(ct->cval);
                    369: 
                    370:        return((Cost) 0);
                    371: }
                    372: 
                    373: yywrap()
                    374: {
                    375:        char    errbuf[100];
                    376: 
                    377:        fixprivate();   /* munge private host definitions */
                    378: 
                    379:        if (Ifiles == 0) 
                    380:                return(1);
                    381: 
                    382:        fclose(stdin);
                    383:        while (*Ifiles) {
                    384:                Lineno = 1;
                    385:                if (fopen((Cfile = *Ifiles++), "r"))
                    386:                        return(0);
                    387:                sprintf(errbuf, "%s: %s", ProgName, Cfile);
                    388:                perror(errbuf);
                    389:        }
                    390:        return(1);
                    391: }

unix.superglobalmegacorp.com

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