| %{ |
| #include <stdio.h> |
| #include <math.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "grap.h" |
| |
| /*#define RAND_MAX 32767 /* if your rand() returns bigger, change this too */ |
| |
| extern int yylex(void); |
| extern int yyparse(void); |
| |
| %} |
| |
| %token <i> FRAME TICKS GRID LABEL COORD |
| %token <i> LINE ARROW CIRCLE DRAW NEW PLOT NEXT |
| %token <p> PIC |
| %token <i> COPY THRU UNTIL |
| %token <i> FOR FROM TO BY AT WITH |
| %token <i> IF |
| %token <p> GRAPH THEN ELSE DOSTR |
| %token <i> DOT DASH INVIS SOLID |
| %token <i> TEXT JUST SIZE |
| %token <i> LOG EXP SIN COS ATAN2 SQRT RAND MAX MIN INT PRINT SPRINTF |
| %token <i> X Y SIDE IN OUT OFF UP DOWN ACROSS |
| %token <i> HEIGHT WIDTH RADIUS |
| %token <f> NUMBER |
| %token <op> NAME VARNAME DEFNAME |
| %token <p> STRING |
| %token <i> ST '(' ')' ',' |
| |
| %right <f> '=' |
| %left <f> OR |
| %left <f> AND |
| %nonassoc <f> GT LT LE GE EQ NE |
| %left <f> '+' '-' |
| %left <f> '*' '/' '%' |
| %right <f> UMINUS NOT |
| %right <f> '^' |
| |
| %type <f> expr optexpr if_expr number assign |
| %type <i> optop |
| %type <p> optstring if |
| %type <op> optname iterator name |
| %type <pt> point |
| %type <i> side optside numlist comma linetype drawtype |
| %type <ap> linedesc optdesc stringlist string stringattr sattrlist exprlist |
| %type <i> frameitem framelist coordlog |
| %type <f> string_expr |
| |
| %% |
| |
| top: |
| graphseq { if (codegen && !synerr) graph((char *) 0); } |
| | /* empty */ { codegen = 0; } |
| | error { codegen = 0; ERROR "syntax error" WARNING; } |
| ; |
| |
| graphseq: |
| statlist |
| | graph statlist |
| | graphseq graph statlist |
| ; |
| graph: |
| GRAPH { graph($1); endstat(); } |
| ; |
| |
| statlist: |
| ST |
| | stat ST { endstat(); } |
| | statlist stat ST { endstat(); } |
| ; |
| |
| stat: |
| FRAME framelist { codegen = 1; } |
| | ticks { codegen = 1; } |
| | grid { codegen = 1; } |
| | label { codegen = 1; } |
| | coord |
| | plot { codegen = 1; } |
| | line { codegen = 1; } |
| | circle { codegen = 1; } |
| | draw |
| | next { codegen = 1; } |
| | PIC { codegen = 1; pic($1); } |
| | for |
| | if |
| | copy |
| | numlist { codegen = 1; numlist(); } |
| | assign |
| | PRINT expr { fprintf(stderr, "\t%g\n", $2); } |
| | PRINT string { fprintf(stderr, "\t%s\n", $2->sval); freeattr($2); } |
| | /* empty */ |
| ; |
| |
| numlist: |
| number { savenum(0, $1); $$ = 1; } |
| | numlist number { savenum($1, $2); $$ = $1+1; } |
| | numlist comma number { savenum($1, $3); $$ = $1+1; } |
| ; |
| number: |
| NUMBER |
| | '-' NUMBER %prec UMINUS { $$ = -$2; } |
| | '+' NUMBER %prec UMINUS { $$ = $2; } |
| ; |
| |
| label: |
| LABEL optside stringlist lablist { label($2, $3); } |
| ; |
| lablist: |
| labattr |
| | lablist labattr |
| | /* empty */ |
| ; |
| labattr: |
| UP expr { labelmove($1, $2); } |
| | DOWN expr { labelmove($1, $2); } |
| | SIDE expr { labelmove($1, $2); /* LEFT or RIGHT only */ } |
| | WIDTH expr { labelwid($2); } |
| ; |
| |
| framelist: |
| framelist frameitem |
| | /* empty */ { $$ = 0; } |
| ; |
| frameitem: |
| HEIGHT expr { frameht($2); } |
| | WIDTH expr { framewid($2); } |
| | side linedesc { frameside($1, $2); } |
| | linedesc { frameside(0, $1); } |
| ; |
| side: |
| SIDE |
| ; |
| optside: |
| side |
| | /* empty */ { $$ = 0; } |
| ; |
| |
| linedesc: |
| linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); } |
| ; |
| linetype: |
| DOT | DASH | SOLID | INVIS |
| ; |
| optdesc: |
| linedesc |
| | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); } |
| ; |
| |
| ticks: |
| TICKS tickdesc { ticks(); } |
| ; |
| tickdesc: |
| tickattr |
| | tickdesc tickattr |
| ; |
| tickattr: |
| side { tickside($1); } |
| | IN expr { tickdir(IN, $2, 1); } |
| | OUT expr { tickdir(OUT, $2, 1); } |
| | IN { tickdir(IN, 0.0, 0); } |
| | OUT { tickdir(OUT, 0.0, 0); } |
| | AT optname ticklist { setlist(); ticklist($2, AT); } |
| | iterator { setlist(); ticklist($1, AT); } |
| | side OFF { tickoff($1); } |
| | OFF { tickoff(LEFT|RIGHT|TOP|BOT); } |
| | labattr |
| ; |
| ticklist: |
| tickpoint |
| | ticklist comma tickpoint |
| ; |
| tickpoint: |
| expr { savetick($1, (char *) 0); } |
| | expr string { savetick($1, $2->sval); } |
| ; |
| iterator: |
| FROM optname expr TO optname expr BY optop expr optstring |
| { iterator($3, $6, $8, $9, $10); $$ = $2; } |
| | FROM optname expr TO optname expr optstring |
| { iterator($3, $6, '+', 1.0, $7); $$ = $2; } |
| ; |
| optop: |
| '+' { $$ = '+'; } |
| | '-' { $$ = '-'; } |
| | '*' { $$ = '*'; } |
| | '/' { $$ = '/'; } |
| | /* empty */ { $$ = ' '; } |
| ; |
| optstring: |
| string { $$ = $1->sval; } |
| | /* empty */ { $$ = (char *) 0; } |
| ; |
| |
| grid: |
| GRID griddesc { ticks(); } |
| ; |
| griddesc: |
| gridattr |
| | griddesc gridattr |
| ; |
| gridattr: |
| side { tickside($1); } |
| | X { tickside(BOT); } |
| | Y { tickside(LEFT); } |
| | linedesc { griddesc($1); } |
| | AT optname ticklist { setlist(); gridlist($2); } |
| | iterator { setlist(); gridlist($1); } |
| | TICKS OFF { gridtickoff(); } |
| | OFF { gridtickoff(); } |
| | labattr |
| ; |
| |
| line: |
| LINE FROM point TO point optdesc { line($1, $3, $5, $6); } |
| | LINE optdesc FROM point TO point { line($1, $4, $6, $2); } |
| ; |
| circle: |
| CIRCLE RADIUS expr AT point { circle($3, $5); } |
| | CIRCLE AT point RADIUS expr { circle($5, $3); } |
| | CIRCLE AT point { circle(0.0, $3); } |
| ; |
| |
| stringlist: |
| string |
| | stringlist string { $$ = addattr($1, $2); } |
| ; |
| string: |
| STRING sattrlist { $$ = makesattr($1); } |
| | SPRINTF '(' STRING ')' sattrlist |
| { $$ = makesattr(sprntf($3, (Attr*) 0)); } |
| | SPRINTF '(' STRING ',' exprlist ')' sattrlist |
| { $$ = makesattr(sprntf($3, $5)); } |
| ; |
| exprlist: |
| expr { $$ = makefattr(NUMBER, $1); } |
| | exprlist ',' expr { $$ = addattr($1, makefattr(NUMBER, $3)); } |
| ; |
| sattrlist: |
| stringattr |
| | sattrlist stringattr |
| | /* empty */ { $$ = (Attr *) 0; } |
| ; |
| stringattr: |
| JUST { setjust($1); } |
| | SIZE optop expr { setsize($2, $3); } |
| ; |
| |
| coord: |
| COORD optname coordlist { coord($2); } |
| | COORD optname { resetcoord($2); } |
| ; |
| coordlist: |
| coorditem |
| | coordlist coorditem |
| ; |
| coorditem: |
| coordlog { coordlog($1); } |
| | X point { coord_x($2); } |
| | Y point { coord_y($2); } |
| | X optname expr TO expr { coord_x(makepoint($2, $3, $5)); } |
| | Y optname expr TO expr { coord_y(makepoint($2, $3, $5)); } |
| | X FROM optname expr TO expr { coord_x(makepoint($3, $4, $6)); } |
| | Y FROM optname expr TO expr { coord_y(makepoint($3, $4, $6)); } |
| ; |
| coordlog: |
| LOG X { $$ = XFLAG; } |
| | LOG Y { $$ = YFLAG; } |
| | LOG X LOG Y { $$ = XFLAG|YFLAG; } |
| | LOG Y LOG X { $$ = XFLAG|YFLAG; } |
| | LOG LOG { $$ = XFLAG|YFLAG; } |
| ; |
| |
| plot: |
| stringlist AT point { plot($1, $3); } |
| | PLOT stringlist AT point { plot($2, $4); } |
| | PLOT expr optstring AT point { plotnum($2, $3, $5); } |
| ; |
| |
| draw: |
| drawtype optname linedesc { drawdesc($1, $2, $3, (char *) 0); } |
| | drawtype optname optdesc string { drawdesc($1, $2, $3, $4->sval); } |
| | drawtype optname string optdesc { drawdesc($1, $2, $4, $3->sval); } |
| ; |
| drawtype: |
| DRAW |
| | NEW |
| ; |
| |
| next: |
| NEXT optname AT point optdesc { next($2, $4, $5); } |
| |
| copy: |
| COPY copylist { copy(); } |
| ; |
| copylist: |
| copyattr |
| | copylist copyattr |
| ; |
| copyattr: |
| string { copyfile($1->sval); } |
| | THRU DEFNAME { copydef($2); } |
| | UNTIL string { copyuntil($2->sval); } |
| ; |
| |
| for: |
| FOR name FROM expr TO expr BY optop expr DOSTR |
| { forloop($2, $4, $6, $8, $9, $10); } |
| | FOR name FROM expr TO expr DOSTR |
| { forloop($2, $4, $6, '+', 1.0, $7); } |
| | FOR name '=' expr TO expr BY optop expr DOSTR |
| { forloop($2, $4, $6, $8, $9, $10); } |
| | FOR name '=' expr TO expr DOSTR |
| { forloop($2, $4, $6, '+', 1.0, $7); } |
| ; |
| |
| if: |
| IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); } |
| | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); } |
| ; |
| if_expr: |
| expr |
| | string_expr |
| | if_expr AND string_expr { $$ = $1 && $3; } |
| | if_expr OR string_expr { $$ = $1 || $3; } |
| ; |
| string_expr: |
| STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); } |
| | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); } |
| ; |
| |
| point: |
| optname expr comma expr { $$ = makepoint($1, $2, $4); } |
| | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); } |
| ; |
| comma: |
| ',' { $$ = ','; } |
| ; |
| |
| optname: |
| NAME { $$ = $1; } |
| | /* empty */ { $$ = lookup(curr_coord, 1); } |
| ; |
| |
| expr: |
| NUMBER |
| | assign |
| | '(' string_expr ')' { $$ = $2; } |
| | VARNAME { $$ = getvar($1); } |
| | expr '+' expr { $$ = $1 + $3; } |
| | expr '-' expr { $$ = $1 - $3; } |
| | expr '*' expr { $$ = $1 * $3; } |
| | expr '/' expr { if ($3 == 0.0) { |
| ERROR "division by 0" WARNING; $3 = 1; } |
| $$ = $1 / $3; } |
| | expr '%' expr { if ((long)$3 == 0) { |
| ERROR "mod division by 0" WARNING; $3 = 1; } |
| $$ = (long)$1 % (long)$3; } |
| | '-' expr %prec UMINUS { $$ = -$2; } |
| | '+' expr %prec UMINUS { $$ = $2; } |
| | '(' expr ')' { $$ = $2; } |
| | LOG '(' expr ')' { $$ = Log10($3); } |
| | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); } |
| | expr '^' expr { $$ = pow($1, $3); } |
| | SIN '(' expr ')' { $$ = sin($3); } |
| | COS '(' expr ')' { $$ = cos($3); } |
| | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); } |
| | SQRT '(' expr ')' { $$ = Sqrt($3); } |
| | RAND '(' ')' { $$ = (double)rand() / (double)RAND_MAX; } |
| | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; } |
| | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; } |
| | INT '(' expr ')' { $$ = (long) $3; } |
| | expr GT expr { $$ = $1 > $3; } |
| | expr LT expr { $$ = $1 < $3; } |
| | expr LE expr { $$ = $1 <= $3; } |
| | expr GE expr { $$ = $1 >= $3; } |
| | expr EQ expr { $$ = $1 == $3; } |
| | expr NE expr { $$ = $1 != $3; } |
| | expr AND expr { $$ = $1 && $3; } |
| | expr OR expr { $$ = $1 || $3; } |
| | NOT expr { $$ = !($2); } |
| ; |
| assign: |
| name '=' expr { $$ = setvar($1, $3); } |
| ; |
| |
| name: |
| NAME |
| | VARNAME |
| ; |
| |
| optexpr: |
| expr |
| | /* empty */ { $$ = 0.0; } |
| ; |