|
|
1.1 ! root 1: %{ ! 2: #include <stdio.h> ! 3: #include "pic.h" ! 4: #include <math.h> ! 5: #include <stdlib.h> ! 6: #include <string.h> ! 7: ! 8: YYSTYPE y; ! 9: ! 10: extern void yyerror(char *); ! 11: extern int yylex(void); ! 12: %} ! 13: ! 14: %token <i> BOX 1 /* DON'T CHANGE THESE! */ ! 15: %token <i> LINE 2 ! 16: %token <i> ARROW 3 ! 17: %token <i> CIRCLE 4 ! 18: %token <i> ELLIPSE 5 ! 19: %token <i> ARC 6 ! 20: %token <i> SPLINE 7 ! 21: %token <i> BLOCK 8 ! 22: %token <p> TEXT 9 ! 23: %token <p> TROFF 10 ! 24: %token <i> MOVE 11 ! 25: %token <i> BLOCKEND 12 ! 26: %token <i> PLACE 13 ! 27: %token <i> PRINT RESET THRU UNTIL ! 28: %token <o> FOR IF COPY ! 29: %token <p> THENSTR ELSESTR DOSTR PLACENAME VARNAME SPRINTF ! 30: %token <st> DEFNAME ! 31: %token <i> ATTR TEXTATTR ! 32: %token <i> LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN ! 33: %token <i> HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE ! 34: %token <i> CORNER HERE LAST NTH SAME BETWEEN AND ! 35: %token <i> EAST WEST NORTH SOUTH NE NW SE SW START END ! 36: %token <i> DOTX DOTY DOTHT DOTWID DOTRAD ! 37: %token <f> NUMBER ! 38: %token <f> LOG EXP SIN COS ATAN2 SQRT RAND MIN MAX INT ! 39: %token <i> DIR ! 40: %token <i> DOT DASH CHOP FILL NOEDGE ! 41: %token <o> ST /* statement terminator */ ! 42: ! 43: %right <f> '=' ! 44: %left <f> OROR ! 45: %left <f> ANDAND ! 46: %nonassoc <f> GT LT LE GE EQ NEQ ! 47: %left <f> '+' '-' ! 48: %left <f> '*' '/' '%' ! 49: %right <f> UMINUS NOT ! 50: %right <f> '^' ! 51: ! 52: %type <f> expr if_expr asgn ! 53: %type <p> name text ! 54: %type <i> optop exprlist ! 55: %type <o> if for copy ! 56: ! 57: /* this is a lie: picture and position are really the whole union */ ! 58: %type <o> leftbrace picture piclist position lbracket ! 59: %type <o> prim place blockname ! 60: %type <i> textlist textattr /* not a sensible value */ ! 61: %type <i> last type ! 62: ! 63: %% ! 64: ! 65: top: ! 66: piclist ! 67: | /* empty */ ! 68: | error { ERROR "syntax error" WARNING; } ! 69: ; ! 70: ! 71: piclist: ! 72: picture ! 73: | piclist picture ! 74: ; ! 75: ! 76: picture: ! 77: prim ST { codegen = 1; makeiattr(0, 0); } ! 78: | leftbrace piclist '}' { rightthing($1, '}'); $$ = $2; } ! 79: | PLACENAME ':' picture { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } ! 80: | PLACENAME ':' ST picture { y.o=$4; makevar($1,PLACENAME,y); $$ = $4; } ! 81: | PLACENAME ':' position ST { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } ! 82: | asgn ST { y.f = $1; $$ = y.o; $$ = makenode(PLACE, 0); } ! 83: | DIR { setdir($1); $$ = makenode(PLACE, 0); } ! 84: | PRINT expr ST { printexpr($2); $$ = makenode(PLACE, 0); } ! 85: | PRINT position ST { printpos($2); $$ = makenode(PLACE, 0); } ! 86: | PRINT text ST { printf("%s\n", $2); free($2); $$ = makenode(PLACE, 0); } ! 87: | RESET varlist ST { resetvar(); makeiattr(0, 0); $$ = makenode(PLACE, 0); } ! 88: | copy ! 89: | for ! 90: | if ! 91: | ST ! 92: ; ! 93: ! 94: varlist: ! 95: /* empty */ ! 96: | VARNAME { makevattr($1); } ! 97: | varlist VARNAME { makevattr($2); } ! 98: | varlist ',' VARNAME { makevattr($3); } ! 99: ; ! 100: ! 101: asgn: ! 102: VARNAME '=' expr { $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); } ! 103: ; ! 104: ! 105: copy: ! 106: COPY copylist { copy(); } ! 107: ; ! 108: copylist: ! 109: copyattr ! 110: | copylist copyattr ! 111: ; ! 112: copyattr: ! 113: text { copyfile($1); } ! 114: | THRU DEFNAME { copydef($2); } ! 115: | UNTIL text { copyuntil($2); } ! 116: ; ! 117: ! 118: for: ! 119: FOR name FROM expr TO expr BY optop expr DOSTR ! 120: { forloop($2, $4, $6, $8, $9, $10); } ! 121: | FOR name FROM expr TO expr DOSTR ! 122: { forloop($2, $4, $6, '+', 1.0, $7); } ! 123: | FOR name '=' expr TO expr BY optop expr DOSTR ! 124: { forloop($2, $4, $6, $8, $9, $10); } ! 125: | FOR name '=' expr TO expr DOSTR ! 126: { forloop($2, $4, $6, '+', 1.0, $7); } ! 127: ; ! 128: ! 129: if: ! 130: IF if_expr THENSTR ELSESTR { ifstat($2, $3, $4); } ! 131: | IF if_expr THENSTR { ifstat($2, $3, (char *) 0); } ! 132: ; ! 133: if_expr: ! 134: expr ! 135: | text EQ text { $$ = strcmp($1,$3) == 0; free($1); free($3); } ! 136: | text NEQ text { $$ = strcmp($1,$3) != 0; free($1); free($3); } ! 137: ; ! 138: ! 139: name: ! 140: VARNAME { y.f = 0; makevar($1, VARNAME, y); } ! 141: ; ! 142: optop: ! 143: '+' { $$ = '+'; } ! 144: | '-' { $$ = '-'; } ! 145: | '*' { $$ = '*'; } ! 146: | '/' { $$ = '/'; } ! 147: | /* empty */ { $$ = ' '; } ! 148: ; ! 149: ! 150: ! 151: leftbrace: ! 152: '{' { $$ = leftthing('{'); } ! 153: ; ! 154: ! 155: prim: ! 156: BOX attrlist { $$ = boxgen(); } ! 157: | CIRCLE attrlist { $$ = circgen($1); } ! 158: | ELLIPSE attrlist { $$ = circgen($1); } ! 159: | ARC attrlist { $$ = arcgen($1); } ! 160: | LINE attrlist { $$ = linegen($1); } ! 161: | ARROW attrlist { $$ = linegen($1); } ! 162: | SPLINE attrlist { $$ = linegen($1); } ! 163: | MOVE attrlist { $$ = movegen(); } ! 164: | textlist attrlist { $$ = textgen(); } ! 165: | TROFF { $$ = troffgen($1); } ! 166: | lbracket piclist ']' { $<o>$=rightthing($1,']'); } attrlist ! 167: { $$ = blockgen($1, $<o>4); } ! 168: ; ! 169: ! 170: lbracket: ! 171: '[' { $$ = leftthing('['); } ! 172: ; ! 173: ! 174: attrlist: ! 175: attrlist attr ! 176: | /* empty */ ! 177: ; ! 178: ! 179: attr: ! 180: ATTR expr { makefattr($1, !DEFAULT, $2); } ! 181: | ATTR { makefattr($1, DEFAULT, 0.0); } ! 182: | expr { makefattr(curdir(), !DEFAULT, $1); } ! 183: | DIR expr { makefattr($1, !DEFAULT, $2); } ! 184: | DIR { makefattr($1, DEFAULT, 0.0); } ! 185: | FROM position { makeoattr($1, $2); } ! 186: | TO position { makeoattr($1, $2); } ! 187: | AT position { makeoattr($1, $2); } ! 188: | BY position { makeoattr($1, $2); } ! 189: | WITH CORNER { makeiattr(WITH, $2); } ! 190: | WITH '.' PLACENAME { makeoattr(PLACE, getblock(getlast(1,BLOCK), $3)); } ! 191: | WITH '.' PLACENAME CORNER ! 192: { makeoattr(PLACE, getpos(getblock(getlast(1,BLOCK), $3), $4)); } ! 193: | WITH position { makeoattr(PLACE, $2); } ! 194: | SAME { makeiattr(SAME, $1); } ! 195: | TEXTATTR { maketattr($1, (char *) 0); } ! 196: | HEAD { makeiattr(HEAD, $1); } ! 197: | DOT expr { makefattr(DOT, !DEFAULT, $2); } ! 198: | DOT { makefattr(DOT, DEFAULT, 0.0); } ! 199: | DASH expr { makefattr(DASH, !DEFAULT, $2); } ! 200: | DASH { makefattr(DASH, DEFAULT, 0.0); } ! 201: | CHOP expr { makefattr(CHOP, !DEFAULT, $2); } ! 202: | CHOP { makefattr(CHOP, DEFAULT, 0.0); } ! 203: | CHOP PLACENAME { makeattr(CHOP, PLACENAME, getvar($2)); } ! 204: | FILL expr { makefattr(FILL, !DEFAULT, $2); } ! 205: | FILL { makefattr(FILL, DEFAULT, 0.0); } ! 206: | NOEDGE { makeiattr(NOEDGE, 0); } ! 207: | textlist ! 208: ; ! 209: ! 210: textlist: ! 211: textattr ! 212: | textlist textattr ! 213: ; ! 214: textattr: ! 215: text { maketattr(CENTER, $1); } ! 216: | text TEXTATTR { maketattr($2, $1); } ! 217: | textattr TEXTATTR { addtattr($2); } ! 218: ; ! 219: text: ! 220: TEXT ! 221: | SPRINTF '(' text ')' { $$ = sprintgen($3); } ! 222: | SPRINTF '(' text ',' exprlist ')' { $$ = sprintgen($3); } ! 223: ; ! 224: ! 225: exprlist: ! 226: expr { exprsave($1); $$ = 0; } ! 227: | exprlist ',' expr { exprsave($3); } ! 228: ; ! 229: ! 230: position: /* absolute, not relative */ ! 231: place ! 232: | '(' position ')' { $$ = $2; } ! 233: | expr ',' expr { $$ = makepos($1, $3); } ! 234: | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); } ! 235: | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); } ! 236: | position '+' '(' expr ',' expr ')' { $$ = fixpos($1, $4, $6); } ! 237: | position '-' '(' expr ',' expr ')' { $$ = fixpos($1, -$4, -$6); } ! 238: | position '+' place { $$ = addpos($1, $3); } ! 239: | position '-' place { $$ = subpos($1, $3); } ! 240: | '(' place ',' place ')' { $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); } ! 241: | expr LT position ',' position GT { $$ = makebetween($1, $3, $5); } ! 242: | expr BETWEEN position AND position { $$ = makebetween($1, $3, $5); } ! 243: ; ! 244: ! 245: place: ! 246: PLACENAME { y = getvar($1); $$ = y.o; } ! 247: | PLACENAME CORNER { y = getvar($1); $$ = getpos(y.o, $2); } ! 248: | CORNER PLACENAME { y = getvar($2); $$ = getpos(y.o, $1); } ! 249: | HERE { $$ = gethere(); } ! 250: | last type { $$ = getlast($1, $2); } ! 251: | last type CORNER { $$ = getpos(getlast($1, $2), $3); } ! 252: | CORNER last type { $$ = getpos(getlast($2, $3), $1); } ! 253: | NTH type { $$ = getfirst($1, $2); } ! 254: | NTH type CORNER { $$ = getpos(getfirst($1, $2), $3); } ! 255: | CORNER NTH type { $$ = getpos(getfirst($2, $3), $1); } ! 256: | blockname ! 257: | blockname CORNER { $$ = getpos($1, $2); } ! 258: | CORNER blockname { $$ = getpos($2, $1); } ! 259: ; ! 260: ! 261: blockname: ! 262: last BLOCK '.' PLACENAME { $$ = getblock(getlast($1,$2), $4); } ! 263: | NTH BLOCK '.' PLACENAME { $$ = getblock(getfirst($1,$2), $4); } ! 264: | PLACENAME '.' PLACENAME { y = getvar($1); $$ = getblock(y.o, $3); } ! 265: ; ! 266: ! 267: last: ! 268: last LAST { $$ = $1 + 1; } ! 269: | NTH LAST { $$ = $1; } ! 270: | LAST { $$ = 1; } ! 271: ; ! 272: ! 273: type: ! 274: BOX ! 275: | CIRCLE ! 276: | ELLIPSE ! 277: | ARC ! 278: | LINE ! 279: | ARROW ! 280: | SPLINE ! 281: | BLOCK ! 282: ; ! 283: ! 284: expr: ! 285: NUMBER ! 286: | VARNAME { $$ = getfval($1); } ! 287: | asgn ! 288: | expr '+' expr { $$ = $1 + $3; } ! 289: | expr '-' expr { $$ = $1 - $3; } ! 290: | expr '*' expr { $$ = $1 * $3; } ! 291: | expr '/' expr { if ($3 == 0.0) { ! 292: ERROR "division by 0" WARNING; $3 = 1; } ! 293: $$ = $1 / $3; } ! 294: | expr '%' expr { if ((long)$3 == 0) { ! 295: ERROR "mod division by 0" WARNING; $3 = 1; } ! 296: $$ = (long)$1 % (long)$3; } ! 297: | '-' expr %prec UMINUS { $$ = -$2; } ! 298: | '(' expr ')' { $$ = $2; } ! 299: | place DOTX { $$ = getcomp($1, $2); } ! 300: | place DOTY { $$ = getcomp($1, $2); } ! 301: | place DOTHT { $$ = getcomp($1, $2); } ! 302: | place DOTWID { $$ = getcomp($1, $2); } ! 303: | place DOTRAD { $$ = getcomp($1, $2); } ! 304: | PLACENAME '.' VARNAME { y = getvar($1); $$ = getblkvar(y.o, $3); } ! 305: | last BLOCK '.' VARNAME { $$ = getblkvar(getlast($1,$2), $4); } ! 306: | NTH BLOCK '.' VARNAME { $$ = getblkvar(getfirst($1,$2), $4); } ! 307: | expr GT expr { $$ = $1 > $3; } ! 308: | expr LT expr { $$ = $1 < $3; } ! 309: | expr LE expr { $$ = $1 <= $3; } ! 310: | expr GE expr { $$ = $1 >= $3; } ! 311: | expr EQ expr { $$ = $1 == $3; } ! 312: | expr NEQ expr { $$ = $1 != $3; } ! 313: | expr ANDAND expr { $$ = $1 && $3; } ! 314: | expr OROR expr { $$ = $1 || $3; } ! 315: | NOT expr { $$ = !($2); } ! 316: | LOG '(' expr ')' { $$ = Log10($3); } ! 317: | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); } ! 318: | expr '^' expr { $$ = pow($1, $3); } ! 319: | SIN '(' expr ')' { $$ = sin($3); } ! 320: | COS '(' expr ')' { $$ = cos($3); } ! 321: | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); } ! 322: | SQRT '(' expr ')' { $$ = Sqrt($3); } ! 323: | RAND '(' ')' { $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ } ! 324: | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; } ! 325: | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; } ! 326: | INT '(' expr ')' { $$ = (long) $3; } ! 327: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.