|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.