Let's try this. It's BUGGERED.
This commit is contained in:
parent
76e6aca867
commit
5cedca1b69
118 changed files with 26947 additions and 1 deletions
396
src/cmd/grap/grap.y
Normal file
396
src/cmd/grap/grap.y
Normal file
|
|
@ -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; }
|
||||
;
|
||||
Loading…
Add table
Add a link
Reference in a new issue