plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

grap.y (9294B)


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