|
|
1.1 ! root 1: %{ ! 2: #include <stdio.h> ! 3: #include <math.h> ! 4: #include "grap.h" ! 5: %} ! 6: ! 7: %token <i> FRAME TICKS GRID LABEL COORD ! 8: %token <i> LINE ARROW CIRCLE DRAW NEW PLOT PIC NEXT ! 9: %token <i> COPY THRU UNTIL ! 10: %token <i> FOR FROM TO BY AT WITH ! 11: %token <i> IF ! 12: %token <p> GRAPH THEN ELSE DOSTR ! 13: %token <i> DOT DASH INVIS SOLID ! 14: %token <i> TEXT JUST SIZE ! 15: %token <i> LOG EXP SIN COS ATAN2 SQRT RAND MAX MIN INT PRINT ! 16: %token <i> X Y SIDE IN OUT OFF UP DOWN ACROSS ! 17: %token <i> HEIGHT WIDTH RADIUS ! 18: %token <f> NUMBER ! 19: %token <op> NAME VARNAME DEFNAME ! 20: %token <p> STRING ! 21: %token <i> ST '(' ')' ! 22: ! 23: %right <f> '=' ! 24: %left <f> OR ! 25: %left <f> AND ! 26: %nonassoc <f> GT LT LE GE EQ NE ! 27: %left <f> '+' '-' ! 28: %left <f> '*' '/' ! 29: %right <f> UMINUS NOT ! 30: ! 31: %type <f> expr optexpr if_expr number assign ! 32: %type <i> optop ! 33: %type <p> optstring if ! 34: %type <op> optname iterator name ! 35: %type <pt> point ! 36: %type <i> side optside numlist comma linetype drawtype ! 37: %type <ap> linedesc optdesc stringlist string stringattr sattrlist ! 38: %type <i> frameitem framelist coordlog ! 39: ! 40: %% ! 41: ! 42: top: ! 43: graphseq { if (codegen && !synerr) graph((char *) 0); } ! 44: | /* empty */ { codegen = 0; } ! 45: | error { codegen = 0; yyerror("syntax error"); } ! 46: ; ! 47: ! 48: graphseq: ! 49: statlist ! 50: | graph statlist ! 51: | graphseq graph statlist ! 52: ; ! 53: graph: ! 54: GRAPH { graph($1); endstat(); } ! 55: ; ! 56: ! 57: statlist: ! 58: ST ! 59: | stat ST { endstat(); } ! 60: | statlist stat ST { endstat(); } ! 61: ; ! 62: ! 63: stat: ! 64: FRAME framelist { codegen = 1; } ! 65: | ticks { codegen = 1; } ! 66: | grid { codegen = 1; } ! 67: | label { codegen = 1; } ! 68: | coord ! 69: | plot { codegen = 1; } ! 70: | line { codegen = 1; } ! 71: | circle { codegen = 1; } ! 72: | draw ! 73: | next { codegen = 1; } ! 74: | PIC { codegen = 1; pic($1); } ! 75: | for ! 76: | if ! 77: | copy ! 78: | numlist { codegen = 1; numlist(); } ! 79: | assign ! 80: | PRINT expr { fprintf(stderr, "\t%g\n", $2); } ! 81: | PRINT STRING { fprintf(stderr, "\t%s\n", $2); free($2); } ! 82: | /* empty */ ! 83: ; ! 84: ! 85: numlist: ! 86: number { savenum(0, $1); $$ = 1; } ! 87: | numlist number { savenum($1, $2); $$ = $1+1; } ! 88: | numlist comma number { savenum($1, $3); $$ = $1+1; } ! 89: ; ! 90: number: ! 91: NUMBER ! 92: | '-' NUMBER %prec UMINUS { $$ = -$2; } ! 93: | '+' NUMBER %prec UMINUS { $$ = $2; } ! 94: ; ! 95: ! 96: label: ! 97: LABEL optside stringlist lablist { label($2, $3); } ! 98: ; ! 99: lablist: ! 100: labattr ! 101: | lablist labattr ! 102: | /* empty */ ! 103: ; ! 104: labattr: ! 105: UP expr { labelmove($1, $2); } ! 106: | DOWN expr { labelmove($1, $2); } ! 107: | SIDE expr { labelmove($1, $2); /* LEFT or RIGHT only */ } ! 108: ; ! 109: ! 110: framelist: ! 111: framelist frameitem ! 112: | /* empty */ { $$ = 0; } ! 113: ; ! 114: frameitem: ! 115: HEIGHT expr { frameht($2); } ! 116: | WIDTH expr { framewid($2); } ! 117: | side linedesc { frameside($1, $2); } ! 118: | linedesc { frameside(0, $1); } ! 119: ; ! 120: side: ! 121: SIDE ! 122: ; ! 123: optside: ! 124: side ! 125: | /* empty */ { $$ = 0; } ! 126: ; ! 127: ! 128: linedesc: ! 129: linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); } ! 130: ; ! 131: linetype: ! 132: DOT | DASH | SOLID | INVIS ! 133: ; ! 134: optdesc: ! 135: linedesc ! 136: | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); } ! 137: ; ! 138: ! 139: ticks: ! 140: TICKS tickdesc { ticks(); } ! 141: ; ! 142: tickdesc: ! 143: tickattr ! 144: | tickdesc tickattr ! 145: ; ! 146: tickattr: ! 147: side { tickside($1); } ! 148: | IN expr { tickdir(IN, $2, 1); } ! 149: | OUT expr { tickdir(OUT, $2, 1); } ! 150: | IN { tickdir(IN, 0.0, 0); } ! 151: | OUT { tickdir(OUT, 0.0, 0); } ! 152: | AT optname ticklist { setlist(); ticklist($2); } ! 153: | iterator { setlist(); ticklist($1); } ! 154: | side OFF { tickoff($1); } ! 155: | OFF { tickoff(LEFT|RIGHT|TOP|BOT); } ! 156: | labattr ! 157: ; ! 158: ticklist: ! 159: tickpoint ! 160: | ticklist comma tickpoint ! 161: ; ! 162: tickpoint: ! 163: expr { savetick($1, (char *) 0); } ! 164: | expr STRING { savetick($1, $2); } ! 165: ; ! 166: iterator: ! 167: FROM optname expr TO optname expr BY optop expr optstring ! 168: { iterator($3, $6, $8, $9, $10); $$ = $2; } ! 169: | FROM optname expr TO optname expr optstring ! 170: { iterator($3, $6, '+', 1.0, $7); $$ = $2; } ! 171: ; ! 172: optop: ! 173: '+' { $$ = '+'; } ! 174: | '-' { $$ = '-'; } ! 175: | '*' { $$ = '*'; } ! 176: | '/' { $$ = '/'; } ! 177: | /* empty */ { $$ = ' '; } ! 178: ; ! 179: optstring: ! 180: STRING ! 181: | /* empty */ { $$ = (char *) 0; } ! 182: ; ! 183: ! 184: grid: ! 185: GRID griddesc { ticks(); } ! 186: ; ! 187: griddesc: ! 188: gridattr ! 189: | griddesc gridattr ! 190: ; ! 191: gridattr: ! 192: side { tickside($1); } ! 193: | X { tickside(BOT); } ! 194: | Y { tickside(LEFT); } ! 195: | linedesc { griddesc($1); } ! 196: | AT optname ticklist { setlist(); gridlist($2); } ! 197: | iterator { setlist(); gridlist($1); } ! 198: | labattr ! 199: ; ! 200: ! 201: line: ! 202: LINE FROM point TO point optdesc { line($1, $3, $5, $6); } ! 203: | LINE optdesc FROM point TO point { line($1, $4, $6, $2); } ! 204: ; ! 205: circle: ! 206: CIRCLE RADIUS expr AT point { circle($3, $5); } ! 207: | CIRCLE AT point RADIUS expr { circle($5, $3); } ! 208: | CIRCLE AT point { circle(0.0, $3); } ! 209: ; ! 210: ! 211: stringlist: ! 212: string ! 213: | stringlist string { $$ = addattr($1, $2); } ! 214: ; ! 215: string: ! 216: STRING sattrlist { $$ = makesattr($1, $2); } ! 217: ; ! 218: sattrlist: ! 219: stringattr ! 220: | sattrlist stringattr ! 221: | /* empty */ { $$ = (Attr *) 0; } ! 222: ; ! 223: stringattr: ! 224: JUST { setjust($1); } ! 225: | SIZE optop expr { setsize($2, $3); } ! 226: ; ! 227: ! 228: coord: ! 229: COORD optname coordlist { coord($2); } ! 230: | COORD optname { resetcoord($2); } ! 231: ; ! 232: coordlist: ! 233: coorditem ! 234: | coordlist coorditem ! 235: ; ! 236: coorditem: ! 237: coordlog { coordlog($1); } ! 238: | X point { coord_x($2); } ! 239: | Y point { coord_y($2); } ! 240: | X optname expr TO expr { coord_x(makepoint($2, $3, $5)); } ! 241: | Y optname expr TO expr { coord_y(makepoint($2, $3, $5)); } ! 242: | X FROM optname expr TO expr { coord_x(makepoint($3, $4, $6)); } ! 243: | Y FROM optname expr TO expr { coord_y(makepoint($3, $4, $6)); } ! 244: ; ! 245: coordlog: ! 246: LOG X { $$ = XFLAG; } ! 247: | LOG Y { $$ = YFLAG; } ! 248: | LOG X LOG Y { $$ = XFLAG|YFLAG; } ! 249: | LOG Y LOG X { $$ = XFLAG|YFLAG; } ! 250: | LOG LOG { $$ = XFLAG|YFLAG; } ! 251: ; ! 252: ! 253: plot: ! 254: stringlist AT point { plot($1, $3); } ! 255: | PLOT stringlist AT point { plot($2, $4); } ! 256: | PLOT expr optstring AT point { plotnum($2, $3, $5); } ! 257: ; ! 258: ! 259: draw: ! 260: drawtype optname linedesc { drawdesc($1, $2, $3, (char *) 0); } ! 261: | drawtype optname optdesc STRING { drawdesc($1, $2, $3, $4); } ! 262: | drawtype optname STRING optdesc { drawdesc($1, $2, $4, $3); } ! 263: ; ! 264: drawtype: ! 265: DRAW ! 266: | NEW ! 267: ; ! 268: ! 269: next: ! 270: NEXT optname AT point optdesc { next($2, $4, $5); } ! 271: ! 272: copy: ! 273: COPY copylist { copy(); } ! 274: ; ! 275: copylist: ! 276: copyattr ! 277: | copylist copyattr ! 278: ; ! 279: copyattr: ! 280: STRING { copyfile($1); } ! 281: | THRU DEFNAME { copydef($2); } ! 282: | UNTIL STRING { copyuntil($2); } ! 283: ; ! 284: ! 285: for: ! 286: FOR name FROM expr TO expr BY optop expr DOSTR ! 287: { forloop($2, $4, $6, $8, $9, $10); } ! 288: | FOR name FROM expr TO expr DOSTR ! 289: { forloop($2, $4, $6, '+', 1.0, $7); } ! 290: | FOR name '=' expr TO expr BY optop expr DOSTR ! 291: { forloop($2, $4, $6, $8, $9, $10); } ! 292: | FOR name '=' expr TO expr DOSTR ! 293: { forloop($2, $4, $6, '+', 1.0, $7); } ! 294: ; ! 295: ! 296: if: ! 297: IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); } ! 298: | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); } ! 299: ; ! 300: if_expr: ! 301: expr ! 302: | STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); } ! 303: | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); } ! 304: ; ! 305: ! 306: point: ! 307: optname expr comma expr { $$ = makepoint($1, $2, $4); } ! 308: | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); } ! 309: ; ! 310: comma: ! 311: ',' { $$ = ','; } ! 312: ; ! 313: ! 314: optname: ! 315: NAME { $$ = $1; } ! 316: | /* empty */ { $$ = lookup(curr_coord, 1); } ! 317: ; ! 318: ! 319: expr: ! 320: NUMBER ! 321: | assign ! 322: | VARNAME { $$ = getvar($1); } ! 323: | expr '+' expr { $$ = $1 + $3; } ! 324: | expr '-' expr { $$ = $1 - $3; } ! 325: | expr '*' expr { $$ = $1 * $3; } ! 326: | expr '/' expr { if ($3 == 0.0) { ! 327: yyerror("division by 0"); $3 = 1; } ! 328: $$ = $1 / $3; } ! 329: | '-' expr %prec UMINUS { $$ = -$2; } ! 330: | '+' expr %prec UMINUS { $$ = $2; } ! 331: | '(' expr ')' { $$ = $2; } ! 332: | LOG '(' expr ')' { $$ = Log10($3); } ! 333: | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); } ! 334: | SIN '(' expr ')' { $$ = sin($3); } ! 335: | COS '(' expr ')' { $$ = cos($3); } ! 336: | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); } ! 337: | SQRT '(' expr ')' { $$ = Sqrt($3); } ! 338: | RAND '(' ')' { $$ = (float)rand() / 32767.0; } ! 339: | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; } ! 340: | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; } ! 341: | INT '(' expr ')' { $$ = (long) $3; } ! 342: | expr GT expr { $$ = $1 > $3; } ! 343: | expr LT expr { $$ = $1 < $3; } ! 344: | expr LE expr { $$ = $1 <= $3; } ! 345: | expr GE expr { $$ = $1 >= $3; } ! 346: | expr EQ expr { $$ = $1 == $3; } ! 347: | expr NE expr { $$ = $1 != $3; } ! 348: | expr AND expr { $$ = $1 && $3; } ! 349: | expr OR expr { $$ = $1 || $3; } ! 350: | NOT expr { $$ = !($2); } ! 351: ; ! 352: assign: ! 353: name '=' expr { $$ = setvar($1, $3); } ! 354: ; ! 355: ! 356: name: ! 357: NAME ! 358: | VARNAME ! 359: ; ! 360: ! 361: optexpr: ! 362: expr ! 363: | /* empty */ { $$ = 0.0; } ! 364: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.