initial setup of thesis repository
[cluster_expansion_thesis.git] / little_helpers / tikz / sketch-0.2.161 / sketch.y
blob008d48236ed48ead831e8de44a867626ca69d58d
1 /* sketch.y
2 Copyright (C) 2005,2006,2007,2008 Eugene K. Ressler, Jr.
4 This file is part of Sketch, a small, simple system for making
5 3d drawings with LaTeX and the PSTricks or TikZ package.
7 Sketch is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 Sketch is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Sketch; see the file COPYING.txt. If not, see
19 http://www.gnu.org/copyleft */
23 #include <stdio.h>
24 #include <stdlib.h>
26 #if defined(_WIN32)
27 #include <malloc.h>
28 #if !defined(alloca)
29 #define alloca _alloca
30 #endif
31 #define YYSTACK_USE_ALLOCA 1
32 // turn of warning about unused goto label in bison skeleton
33 #pragma warning(disable:4102)
34 #endif
36 #include "parse.h"
37 #include "expr.h"
38 #include "bsp.h"
39 #include "global.h"
41 int yylex(void);
43 void yyerror (char *s) /* Called by yyparse on error */
45 extern SRC_LINE line;
46 err(line, "%s", s);
49 static SYMBOL_TABLE *sym_tab;
50 static BSP_TREE bsp;
51 static FILE *yyout;
53 // exported parse tree and global environment
54 static OBJECT *objects;
58 %union {
59 char *str;
60 FLOAT flt;
61 POINT_3D pt;
62 VECTOR_3D vec;
63 TRANSFORM xf;
64 EXPR_VAL exv;
65 SYMBOL_NAME name;
66 OBJECT *obj;
67 OPTS *opts;
68 int bool;
69 int index;
72 %token <name>ID <name>PAREN_ID <name>BRACKET_ID
73 %token <name>DBL_BRACKET_ID <name>CURLY_ID <name>ANGLE_ID
74 %token <flt>NUM
75 %token <str>OPTS_STR <str>SPECIAL
76 %token <index>TICK
77 %token THEN DEF EMPTY_ANGLE
78 %token DOTS LINE CURVE POLYGON REPEAT SWEEP PUT SPECIAL
79 %token TRANSLATE ROTATE SCALE PROJECT PERSPECTIVE VIEW
80 %token SQRT SIN COS ATAN2 UNIT INVERSE
81 %token GLOBAL SET PICTUREBOX FRAME CAMERA
82 %token LANGUAGE PSTRICKS TIKZ LaTeX ConTeXt
84 %type <name> tagged_defs
85 %type <opts> options option_id_list
86 %type <flt> scalar scalar_expr opt_baseline
87 %type <pt> point point_expr
88 %type <vec> vector vector_expr
89 %type <xf> transform transform_expr
90 %type <exv> expr
91 %type <obj> defs_and_decls rev_defs_and_decls decl def_or_decl
92 %type <obj> defable points rev_points transforms rev_transforms
93 %type <bool> opt_star
94 %type <index> output_language comma_macro_package graphics_language macro_package
96 %right THEN
97 %left '-' '+'
98 %left '*' '/' '.'
99 %left NEG /* negation--unary minus */
100 %right '^' /* exponentiation */
101 %left TICK /* point and vector indexing */
105 input : defs_and_decls global_decl_block { objects = $1; }
107 /* sets global_env as a side effect */
108 global_decl_block : GLOBAL '{' global_decls '}'
109 | /* empty */
112 global_decls : global_decls global_decl
113 | global_decl
116 global_decl : SET OPTS_STR
118 set_global_env_opts(global_env, $2, line);
120 | PICTUREBOX '[' scalar_expr ']'
122 set_global_baseline(global_env, $3, line);
124 | PICTUREBOX opt_baseline point point
126 set_global_baseline(global_env, $2, line);
127 set_global_env_extent(global_env, $3, $4, line);
129 | CAMERA transform_expr
131 set_global_env_camera(global_env, $2, line);
133 | FRAME
135 set_global_env_frame(global_env, NULL, line);
137 | FRAME OPTS_STR
139 set_global_env_frame(global_env, $2, line);
141 | LANGUAGE output_language
143 set_global_output_language(global_env, $2, line);
145 | def
148 output_language : graphics_language comma_macro_package { $$ = $1 | $2; }
151 graphics_language : PSTRICKS { $$ = GEOL_PSTRICKS; }
152 | TIKZ { $$ = GEOL_TIKZ; }
155 comma_macro_package : ',' macro_package { $$ = $2; }
156 | /* empty */ { $$ = GEOL_LATEX; }
159 macro_package : LaTeX { $$ = GEOL_LATEX; }
160 | ConTeXt { $$ = GEOL_CONTEXT; }
163 opt_baseline : '[' scalar_expr ']' { $$ = $2; }
164 | /* empty */ { $$ = NO_BASELINE; }
167 defs_and_decls : rev_defs_and_decls { $$ = sibling_reverse($1); }
170 rev_defs_and_decls : rev_defs_and_decls def_or_decl { $$ = cat_objects($2, $1); }
171 | def_or_decl { $$ = $1; }
174 def_or_decl : def { $$ = NULL; }
175 | decl { $$ = $1; }
178 /* slightly strange rules are to avoid inherited attributes */
179 def : DEF ID defable { new_symbol(sym_tab, $2, 0, $3, line); }
180 | tagged_defs EMPTY_ANGLE defable { new_symbol(sym_tab, $1, 0, $3, line); }
181 | DEF ID EMPTY_ANGLE { new_symbol(sym_tab, $2, 0, new_tag_def(), line); }
184 tagged_defs : DEF ID ANGLE_ID defable { strcpy($$, new_symbol(sym_tab, $2, $3, $4, line) ? "" : $2); }
185 | tagged_defs ANGLE_ID defable { strcpy($$, new_symbol(sym_tab, $1, $2, $3, line) ? "" : $1); }
188 defable : expr { $$ = object_from_expr(&$1); }
189 | decl { $$ = $1; }
190 | OPTS_STR { $$ = new_opts_def($1, line); }
193 decl : DOTS options points { $$ = new_dots($2, $3); }
194 | LINE options points { $$ = new_line($2, $3); }
195 | CURVE options points { $$ = new_curve($2, $3); }
196 | POLYGON options points { $$ = new_polygon($2, $3); }
197 | SWEEP options '{' scalar_expr opt_star ',' transforms '}' point
199 $$ = new_sweep($2, $4, $5, $7, new_point_def($9));
201 | SWEEP options '{' scalar_expr opt_star ',' transforms '}' decl
203 $$ = new_sweep($2, $4, $5, $7, $9);
205 | REPEAT '{' scalar_expr ',' transforms '}' decl
207 $$ = new_repeat($3, $5, $7);
209 | PUT '{' transform_expr '}' decl { $$ = new_compound($3, $5); }
210 | SPECIAL options points { $$ = new_special($1, $2, $3, line); }
211 | SPECIAL options { $$ = new_special($1, $2, new_point_def(origin_3d), line); }
212 | CURLY_ID { look_up_drawable(sym_tab, &$$, line, $1); }
213 | '{' { sym_tab = new_scope(sym_tab); }
214 defs_and_decls { sym_tab = old_scope(sym_tab); }
217 if ($3 == NULL)
218 err(line, "no drawables in compound declaration");
219 $$ = $3;
223 opt_star : EMPTY_ANGLE { $$ = 1; }
224 | /* empty */ { $$ = 0; }
227 option_id_list : option_id_list ',' ID
229 $$ = look_up_and_append_to_opts(sym_tab, &$1, line, $3);
231 | ID
233 $$ = NULL;
234 $$ = look_up_and_append_to_opts(sym_tab, &$$, line, $1);
238 options : OPTS_STR { $$ = new_opts($1, line); }
239 | BRACKET_ID { look_up_opts(sym_tab, &$$, line, $1); }
240 | '[' option_id_list ']' { $$ = $2; }
241 | /* empty */ { $$ = NULL; }
244 points : rev_points { $$ = sibling_reverse($1); }
247 rev_points : rev_points point { $$ = cat_objects(new_point_def($2), $1); }
248 | point { $$ = new_point_def($1); }
251 transforms : rev_transforms { $$ = sibling_reverse($1); }
254 rev_transforms : rev_transforms ',' transform_expr { $$ = cat_objects(new_transform_def($3), $1); }
255 | transform_expr { $$ = new_transform_def($1); }
258 expr : scalar { set_float(&$$, $1); }
259 | point { set_point(&$$, $1); }
260 | vector { set_vector(&$$, $1); }
261 | transform { set_transform(&$$, $1); }
262 | expr '+' expr { do_add(&$$, &$1, &$3, line); }
263 | expr '-' expr { do_sub(&$$, &$1, &$3, line); }
264 | expr '*' expr { do_mul(&$$, &$1, &$3, line); }
265 | expr '/' expr { do_dvd(&$$, &$1, &$3, line); }
266 | expr '.' expr { do_dot(&$$, &$1, &$3, line); }
267 | expr THEN expr { do_thn(&$$, &$1, &$3, line); }
268 | '|' expr '|' { do_mag(&$$, &$2, line); }
269 | '-' expr %prec NEG { do_neg(&$$, &$2, line); }
270 | expr '^' expr { do_pwr(&$$, &$1, &$3, line); }
271 | '(' expr ')' { $$ = $2; }
272 | UNIT expr ')' { do_unit(&$$, &$2, line); }
273 | SQRT expr ')' { do_sqrt(&$$, &$2, line); }
274 | SIN expr ')' { do_sin(&$$, &$2, line); }
275 | COS expr ')' { do_cos(&$$, &$2, line); }
276 | ATAN2 expr ',' expr ')' { do_atan2(&$$, &$2, &$4, line); }
277 | expr TICK { do_index(&$$, &$1, $2, line); }
280 scalar : NUM { $$ = $1; }
281 | ID { look_up_scalar(sym_tab, &$$, line, $1); }
284 scalar_expr : expr { coerce_to_float(&$1, &$$, line); }
287 point : '(' scalar_expr ',' scalar_expr ',' scalar_expr ')'
289 $$[X] = $2; $$[Y] = $4; $$[Z] = $6;
291 | '(' scalar_expr ',' scalar_expr ')'
293 $$[X] = $2; $$[Y] = $4; $$[Z] = 0;
295 | PAREN_ID { look_up_point(sym_tab, $$, line, $1); }
298 point_expr : expr { coerce_to_point(&$1, $$, line); }
301 vector : '[' scalar_expr ',' scalar_expr ',' scalar_expr ']'
303 $$[X] = $2; $$[Y] = $4; $$[Z] = $6;
305 | '[' scalar_expr ',' scalar_expr ']'
307 $$[X] = $2; $$[Y] = $4; $$[Z] = 0;
309 | BRACKET_ID { look_up_vector(sym_tab, $$, line, $1); }
311 vector_expr : expr { coerce_to_vector(&$1, $$, line); }
314 transform : '['
315 '[' scalar_expr ',' scalar_expr ',' scalar_expr',' scalar_expr ']'
316 '[' scalar_expr ',' scalar_expr ',' scalar_expr',' scalar_expr ']'
317 '[' scalar_expr ',' scalar_expr ',' scalar_expr',' scalar_expr ']'
318 '[' scalar_expr ',' scalar_expr ',' scalar_expr',' scalar_expr ']'
320 { // transform is column major while elements are row major
321 $$[0] = $3; $$[4] = $5; $$[8] = $7; $$[12] = $9;
322 $$[1] = $12; $$[5] = $14; $$[9] = $16; $$[13] = $18;
323 $$[2] = $21; $$[6] = $23; $$[10] = $25; $$[14] = $27;
324 $$[3] = $30; $$[7] = $32; $$[11] = $34; $$[15] = $36;
326 | ROTATE scalar_expr ')'
328 set_angle_axis_rot_about_point($$, $2 * (PI/180), 0, 0);
330 | ROTATE scalar_expr ',' expr ')'
332 if (EXPR_TYPE_IS(&$4, E_POINT))
333 set_angle_axis_rot_about_point($$, $2 * (PI/180), $4.val.pt, 0);
334 else if (EXPR_TYPE_IS(&$4, E_VECTOR))
335 set_angle_axis_rot_about_point($$, $2 * (PI/180), 0, $4.val.vec);
336 else
337 err(line, "expected point or vector rotation parameter, and it's a %s",
338 expr_val_type_str[$4.tag]);
340 | ROTATE scalar_expr ',' point_expr ',' vector_expr ')'
342 set_angle_axis_rot_about_point($$, $2 * (PI/180), $4, $6);
344 | TRANSLATE vector_expr ')'
346 set_translation($$, $2[X], $2[Y], $2[Z]);
348 | SCALE expr ')'
350 if ($2.tag == E_FLOAT) {
351 FLOAT s = $2.val.flt;
352 set_scale($$, s, s, s);
354 else if ($2.tag == E_VECTOR) {
355 VECTOR v = $2.val.vec;
356 set_scale($$, v[X], v[Y], v[Z]);
358 else {
359 err(line,
360 "expected scalar or vector scale parameter, and it's a %s",
361 expr_val_type_str[$2.tag]);
362 set_ident($$);
365 | PROJECT ')' { set_parallel_projection($$); }
366 | PROJECT scalar_expr ')' { set_perspective_projection($$, $2); }
367 | PERSPECTIVE scalar_expr ')' { set_perspective_transform($$, $2); }
368 | VIEW point_expr ',' expr ',' vector_expr ')'
370 if ($4.tag == E_VECTOR)
371 set_view_transform($$, $2, $4.val.vec, $6);
372 else if ($4.tag == E_POINT)
373 set_view_transform_with_look_at($$, $2, $4.val.pt, $6);
374 else
375 err(line, "expected point or vector view parameter, and it's a %s",
376 expr_val_type_str[$4.tag]);
378 | VIEW point_expr ',' expr ')'
380 if ($4.tag == E_VECTOR)
381 set_view_transform($$, $2, $4.val.vec, NULL);
382 else if ($4.tag == E_POINT)
383 set_view_transform_with_look_at($$, $2, $4.val.pt, NULL);
384 else
385 err(line, "expected point or vector view parameter, and it's a %s",
386 expr_val_type_str[$4.tag]);
388 | VIEW point_expr ')'
390 set_view_transform($$, $2, NULL, NULL);
393 | INVERSE transform_expr ')' { do_inverse($$, $2, line); }
394 | DBL_BRACKET_ID { look_up_transform(sym_tab, $$, line, $1); }
397 transform_expr : expr { coerce_to_transform(&$1, $$, line); }
402 int parse(SYMBOL_TABLE *st)
404 int ret;
406 objects = NULL;
407 sym_tab = st;
408 ret = yyparse();
410 // should set sym_tab back to NULL
411 sym_tab = old_scope(sym_tab);
412 if (sym_tab)
413 die(no_line, "zombie symbol table");
415 return ret;
418 OBJECT *parsed_objects(void)
420 return objects;