Annotation of 43BSDTahoe/new/pathalias/parse.y, revision 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.