123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- %{
- #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; }
- ;
|