aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/grap/grap.y
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-05-15 23:24:00 +0000
committerrsc <devnull@localhost>2004-05-15 23:24:00 +0000
commit5cedca1b69d020c32466f70843a11767773d7e3b (patch)
treea15a3d84e92aa262543b0010763a5e6920c9ba24 /src/cmd/grap/grap.y
parent76e6aca867e3e48ea04fbcf7284c45369a69829e (diff)
downloadplan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.gz
plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.bz2
plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.zip
Let's try this. It's BUGGERED.
Diffstat (limited to 'src/cmd/grap/grap.y')
-rw-r--r--src/cmd/grap/grap.y396
1 files changed, 396 insertions, 0 deletions
diff --git a/src/cmd/grap/grap.y b/src/cmd/grap/grap.y
new file mode 100644
index 00000000..6d96b2f1
--- /dev/null
+++ b/src/cmd/grap/grap.y
@@ -0,0 +1,396 @@
+%{
+#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; }
+ ;