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