picy.y (9194B)
1 %{ 2 #include <stdio.h> 3 #include <math.h> 4 #include "pic.h" 5 YYSTYPE y; 6 int yylex(void); 7 %} 8 9 %token <i> BOX 1 /* DON'T CHANGE THESE! */ 10 %token <i> LINE 2 11 %token <i> ARROW 3 12 %token <i> CIRCLE 4 13 %token <i> ELLIPSE 5 14 %token <i> ARC 6 15 %token <i> SPLINE 7 16 %token <i> BLOCK 8 17 %token <p> TEXT 9 18 %token <p> TROFF 10 19 %token <i> MOVE 11 20 %token <i> BLOCKEND 12 21 %token <i> PLACE 13 22 %token <i> PRINT RESET THRU UNTIL 23 %token <o> FOR IF COPY 24 %token <p> THENSTR ELSESTR DOSTR PLACENAME VARNAME SPRINTF 25 %token <st> DEFNAME 26 %token <i> ATTR TEXTATTR 27 %token <i> LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN 28 %token <i> HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE 29 %token <i> CORNER HERE LAST NTH SAME BETWEEN AND 30 %token <i> EAST WEST NORTH SOUTH NE NW SE SW START END 31 %token <i> DOTX DOTY DOTHT DOTWID DOTRAD 32 %token <f> NUMBER 33 %token <f> LOG EXP SIN COS ATAN2 SQRT RAND MIN MAX INT 34 %token <i> DIR 35 %token <i> DOT DASH CHOP FILL 36 %token <o> ST /* statement terminator */ 37 38 %right <f> '=' 39 %left <f> OROR 40 %left <f> ANDAND 41 %nonassoc <f> GT LT LE GE EQ NEQ 42 %left <f> '+' '-' 43 %left <f> '*' '/' '%' 44 %right <f> UMINUS NOT 45 %right <f> '^' 46 47 %type <f> expr if_expr asgn 48 %type <p> name text 49 %type <i> optop exprlist 50 %type <o> if for copy 51 52 /* this is a lie: picture and position are really the whole union */ 53 %type <o> leftbrace picture piclist position lbracket 54 %type <o> prim place blockname 55 %type <i> textlist textattr /* not a sensible value */ 56 %type <i> last type 57 58 %% 59 60 top: 61 piclist 62 | /* empty */ 63 | error { ERROR "syntax error" WARNING; } 64 ; 65 66 piclist: 67 picture 68 | piclist picture 69 ; 70 71 picture: 72 prim ST { codegen = 1; makeiattr(0, 0); } 73 | leftbrace piclist '}' { rightthing($1, '}'); $$ = $2; } 74 | PLACENAME ':' picture { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } 75 | PLACENAME ':' ST picture { y.o=$4; makevar($1,PLACENAME,y); $$ = $4; } 76 | PLACENAME ':' position ST { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } 77 | asgn ST { y.f = $1; $$ = y.o; $$ = makenode(PLACE, 0); } 78 | DIR { setdir($1); $$ = makenode(PLACE, 0); } 79 | PRINT expr ST { printexpr($2); $$ = makenode(PLACE, 0); } 80 | PRINT position ST { printpos($2); $$ = makenode(PLACE, 0); } 81 | PRINT text ST { printf("%s\n", $2); free($2); $$ = makenode(PLACE, 0); } 82 | RESET varlist ST { resetvar(); makeiattr(0, 0); $$ = makenode(PLACE, 0); } 83 | copy 84 | for 85 | if 86 | ST 87 ; 88 89 varlist: 90 /* empty */ 91 | VARNAME { makevattr($1); } 92 | varlist VARNAME { makevattr($2); } 93 | varlist ',' VARNAME { makevattr($3); } 94 ; 95 96 asgn: 97 VARNAME '=' expr { $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); } 98 ; 99 100 copy: 101 COPY copylist { copy(); } 102 ; 103 copylist: 104 copyattr 105 | copylist copyattr 106 ; 107 copyattr: 108 text { copyfile($1); } 109 | THRU DEFNAME { copydef($2); } 110 | UNTIL text { copyuntil($2); } 111 ; 112 113 for: 114 FOR name FROM expr TO expr BY optop expr DOSTR 115 { forloop($2, $4, $6, $8, $9, $10); } 116 | FOR name FROM expr TO expr DOSTR 117 { forloop($2, $4, $6, '+', 1.0, $7); } 118 | FOR name '=' expr TO expr BY optop expr DOSTR 119 { forloop($2, $4, $6, $8, $9, $10); } 120 | FOR name '=' expr TO expr DOSTR 121 { forloop($2, $4, $6, '+', 1.0, $7); } 122 ; 123 124 if: 125 IF if_expr THENSTR ELSESTR { ifstat($2, $3, $4); } 126 | IF if_expr THENSTR { ifstat($2, $3, (char *) 0); } 127 ; 128 if_expr: 129 expr 130 | text EQ text { $$ = strcmp($1,$3) == 0; free($1); free($3); } 131 | text NEQ text { $$ = strcmp($1,$3) != 0; free($1); free($3); } 132 ; 133 134 name: 135 VARNAME { y.f = 0; makevar($1, VARNAME, y); } 136 ; 137 optop: 138 '+' { $$ = '+'; } 139 | '-' { $$ = '-'; } 140 | '*' { $$ = '*'; } 141 | '/' { $$ = '/'; } 142 | /* empty */ { $$ = ' '; } 143 ; 144 145 146 leftbrace: 147 '{' { $$ = leftthing('{'); } 148 ; 149 150 prim: 151 BOX attrlist { $$ = boxgen(); } 152 | CIRCLE attrlist { $$ = circgen($1); } 153 | ELLIPSE attrlist { $$ = circgen($1); } 154 | ARC attrlist { $$ = arcgen($1); } 155 | LINE attrlist { $$ = linegen($1); } 156 | ARROW attrlist { $$ = linegen($1); } 157 | SPLINE attrlist { $$ = linegen($1); } 158 | MOVE attrlist { $$ = movegen(); } 159 | textlist attrlist { $$ = textgen(); } 160 | TROFF { $$ = troffgen($1); } 161 | lbracket piclist ']' { $<o>$=rightthing($1,']'); } attrlist 162 { $$ = blockgen($1, $<o>4); } 163 ; 164 165 lbracket: 166 '[' { $$ = leftthing('['); } 167 ; 168 169 attrlist: 170 attrlist attr 171 | /* empty */ 172 ; 173 174 attr: 175 ATTR expr { makefattr($1, !DEFAULT, $2); } 176 | ATTR { makefattr($1, DEFAULT, 0.0); } 177 | expr { makefattr(curdir(), !DEFAULT, $1); } 178 | DIR expr { makefattr($1, !DEFAULT, $2); } 179 | DIR { makefattr($1, DEFAULT, 0.0); } 180 | FROM position { makeoattr($1, $2); } 181 | TO position { makeoattr($1, $2); } 182 | AT position { makeoattr($1, $2); } 183 | BY position { makeoattr($1, $2); } 184 | WITH CORNER { makeiattr(WITH, $2); } 185 | WITH '.' PLACENAME { makeoattr(PLACE, getblock(getlast(1,BLOCK), $3)); } 186 | WITH '.' PLACENAME CORNER 187 { makeoattr(PLACE, getpos(getblock(getlast(1,BLOCK), $3), $4)); } 188 | WITH position { makeoattr(PLACE, $2); } 189 | SAME { makeiattr(SAME, $1); } 190 | TEXTATTR { maketattr($1, (char *) 0); } 191 | HEAD { makeiattr(HEAD, $1); } 192 | DOT expr { makefattr(DOT, !DEFAULT, $2); } 193 | DOT { makefattr(DOT, DEFAULT, 0.0); } 194 | DASH expr { makefattr(DASH, !DEFAULT, $2); } 195 | DASH { makefattr(DASH, DEFAULT, 0.0); } 196 | CHOP expr { makefattr(CHOP, !DEFAULT, $2); } 197 | CHOP { makefattr(CHOP, DEFAULT, 0.0); } 198 | FILL expr { makefattr(FILL, !DEFAULT, $2); } 199 | FILL { makefattr(FILL, DEFAULT, 0.0); } 200 | textlist 201 ; 202 203 textlist: 204 textattr 205 | textlist textattr 206 ; 207 textattr: 208 text { maketattr(CENTER, $1); } 209 | text TEXTATTR { maketattr($2, $1); } 210 | textattr TEXTATTR { addtattr($2); } 211 ; 212 text: 213 TEXT 214 | SPRINTF '(' text ')' { $$ = sprintgen($3); } 215 | SPRINTF '(' text ',' exprlist ')' { $$ = sprintgen($3); } 216 ; 217 218 exprlist: 219 expr { exprsave($1); $$ = 0; } 220 | exprlist ',' expr { exprsave($3); } 221 ; 222 223 position: /* absolute, not relative */ 224 place 225 | '(' position ')' { $$ = $2; } 226 | expr ',' expr { $$ = makepos($1, $3); } 227 | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); } 228 | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); } 229 | position '+' '(' expr ',' expr ')' { $$ = fixpos($1, $4, $6); } 230 | position '-' '(' expr ',' expr ')' { $$ = fixpos($1, -$4, -$6); } 231 | position '+' place { $$ = addpos($1, $3); } 232 | position '-' place { $$ = subpos($1, $3); } 233 | '(' place ',' place ')' { $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); } 234 | expr LT position ',' position GT { $$ = makebetween($1, $3, $5); } 235 | expr BETWEEN position AND position { $$ = makebetween($1, $3, $5); } 236 ; 237 238 place: 239 PLACENAME { y = getvar($1); $$ = y.o; } 240 | PLACENAME CORNER { y = getvar($1); $$ = getpos(y.o, $2); } 241 | CORNER PLACENAME { y = getvar($2); $$ = getpos(y.o, $1); } 242 | HERE { $$ = gethere(); } 243 | last type { $$ = getlast($1, $2); } 244 | last type CORNER { $$ = getpos(getlast($1, $2), $3); } 245 | CORNER last type { $$ = getpos(getlast($2, $3), $1); } 246 | NTH type { $$ = getfirst($1, $2); } 247 | NTH type CORNER { $$ = getpos(getfirst($1, $2), $3); } 248 | CORNER NTH type { $$ = getpos(getfirst($2, $3), $1); } 249 | blockname 250 | blockname CORNER { $$ = getpos($1, $2); } 251 | CORNER blockname { $$ = getpos($2, $1); } 252 ; 253 254 blockname: 255 last BLOCK '.' PLACENAME { $$ = getblock(getlast($1,$2), $4); } 256 | NTH BLOCK '.' PLACENAME { $$ = getblock(getfirst($1,$2), $4); } 257 | PLACENAME '.' PLACENAME { y = getvar($1); $$ = getblock(y.o, $3); } 258 ; 259 260 last: 261 last LAST { $$ = $1 + 1; } 262 | NTH LAST { $$ = $1; } 263 | LAST { $$ = 1; } 264 ; 265 266 type: 267 BOX 268 | CIRCLE 269 | ELLIPSE 270 | ARC 271 | LINE 272 | ARROW 273 | SPLINE 274 | BLOCK 275 ; 276 277 expr: 278 NUMBER 279 | VARNAME { $$ = getfval($1); } 280 | asgn 281 | expr '+' expr { $$ = $1 + $3; } 282 | expr '-' expr { $$ = $1 - $3; } 283 | expr '*' expr { $$ = $1 * $3; } 284 | expr '/' expr { if ($3 == 0.0) { 285 ERROR "division by 0" WARNING; $3 = 1; } 286 $$ = $1 / $3; } 287 | expr '%' expr { if ((long)$3 == 0) { 288 ERROR "mod division by 0" WARNING; $3 = 1; } 289 $$ = (long)$1 % (long)$3; } 290 | '-' expr %prec UMINUS { $$ = -$2; } 291 | '(' expr ')' { $$ = $2; } 292 | place DOTX { $$ = getcomp($1, $2); } 293 | place DOTY { $$ = getcomp($1, $2); } 294 | place DOTHT { $$ = getcomp($1, $2); } 295 | place DOTWID { $$ = getcomp($1, $2); } 296 | place DOTRAD { $$ = getcomp($1, $2); } 297 | PLACENAME '.' VARNAME { y = getvar($1); $$ = getblkvar(y.o, $3); } 298 | last BLOCK '.' VARNAME { $$ = getblkvar(getlast($1,$2), $4); } 299 | NTH BLOCK '.' VARNAME { $$ = getblkvar(getfirst($1,$2), $4); } 300 | expr GT expr { $$ = $1 > $3; } 301 | expr LT expr { $$ = $1 < $3; } 302 | expr LE expr { $$ = $1 <= $3; } 303 | expr GE expr { $$ = $1 >= $3; } 304 | expr EQ expr { $$ = $1 == $3; } 305 | expr NEQ expr { $$ = $1 != $3; } 306 | expr ANDAND expr { $$ = $1 && $3; } 307 | expr OROR expr { $$ = $1 || $3; } 308 | NOT expr { $$ = !($2); } 309 | LOG '(' expr ')' { $$ = Log10($3); } 310 | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); } 311 | expr '^' expr { $$ = pow($1, $3); } 312 | SIN '(' expr ')' { $$ = sin($3); } 313 | COS '(' expr ')' { $$ = cos($3); } 314 | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); } 315 | SQRT '(' expr ')' { $$ = Sqrt($3); } 316 | RAND '(' ')' { $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ } 317 | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; } 318 | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; } 319 | INT '(' expr ')' { $$ = (long) $3; } 320 ;