/* * Eukleides version 1.0.3 * Copyright (c) Christian Obrecht 2000-2004 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ %{ #include #include #include "types.h" #include "geometry.h" #include "drawing.h" int yylex(void); int warning(char *); int yyerror(char *); int drawing_style = FULL; symrec* tracevar; double tracestep, tracebegin; int tracestyle, traceind = -1; extern int strokes; %} %union { double number; char *string; _point *point; _vector *vector; _line *line; _segment *segment; _circle *circle; _conic *conic; symrec *ptr; int flag; } %token NUMBER TOKPI %token STRING %token VARIABLE NUMBER_VARIABLE POINT_VARIABLE VECTOR_VARIABLE %token LINE_VARIABLE SEGMENT_VARIABLE CIRCLE_VARIABLE CONIC_VARIABLE %token NOARROW ARROW BACKARROW DOUBLEARROW ENTIRE HALFLINE BACKHALFLINE %token DOT DISC BOX CROSS PLUS FULL DOTTED DASHED SIMPLE DOUBLE TRIPLE %token EXP LN SIN COS TAN ASIN ACOS ATAN TOKDEG TOKRAD TOKABS SQRT %token SIGN CEIL FLOOR ROUND TOKMIN TOKMAX TOKCLAMP ARGUMENT %token ABSCISSA ORDINATE LENGTH DISTANCE ANGLE RADIUS MAJOR MINOR ECCENTRICITY %token HEIGHT POINT VECTOR LINE SEGMENT CIRCLE CONIC PARABOLA ELLIPSE HYPERBOLA %token TRANSLATION REFLECTION ROTATION PROJECTION HOMOTHECY MIDPOINT CENTER %token VERTICES FOCI ORTHOCENTER BARYCENTER INTERSECTION TOKBEGIN END %token PARALLEL PERPENDICULAR MEDIAN ALTITUDE BISECTOR INCIRCLE TRIANGLE %token EQUILATERAL ISOSCELES RIGHT PARALLELOGRAM RECTANGLE SQUARE PENTAGON %token HEXAGON FRAME COLOR BLACK DARKGRAY GRAY LIGHTGRAY WHITE RED GREEN BLUE %token CYAN MAGENTA YELLOW STYLE THICKNESS FONT TRICKS EXPORT DRAW LABEL %token MARK UP STROKES TRACE INTERACTIVE %right '?' '|' %left OR %left AND %left NOT %left EQ NEQ %left GEQ LEQ %left '>' '<' %left '-' '+' %left '*' '/' %left NEG %right '^' %type num_exp ang_exp %type point_exp %type vector_exp %type line_exp %type segment_exp %type circle_exp %type conic_exp %type variable %type interactive_flag point_aspect line_aspect segment_aspect %type drawing_flag segment_marking_flag angle_marking_flag color_flag %type ident %% input: line | input '\n' line ; line: | command ; command: variable_assignment | multiple_assignment | triangle_assignment | polygon_assignment | interactive_assignment | drawing_command | trace_command ; variable_assignment: variable '=' num_exp { $1->type = NUMBER; $1->object.number = $3; } | variable '=' point_exp { P_assignment($1, $3); } | variable '=' vector_exp { V_assignment($1, $3); } | variable '=' line_exp { L_assignment($1, $3); } | variable '=' segment_exp { S_assignment($1, $3); } | variable '=' circle_exp { C_assignment($1, $3); } | variable '=' conic_exp { Co_assignment($1, $3); } ; variable: VARIABLE | NUMBER_VARIABLE | POINT_VARIABLE | VECTOR_VARIABLE | LINE_VARIABLE | SEGMENT_VARIABLE | CIRCLE_VARIABLE | CONIC_VARIABLE ; num_exp: NUMBER { $$ = $1; } | NUMBER_VARIABLE { $$ = $1->object.number; } | num_exp '+' num_exp { $$ = $1 + $3; } | num_exp '-' num_exp { $$ = $1 - $3; } | num_exp '*' num_exp { $$ = $1 * $3; } | num_exp '/' num_exp { if (ZERO($3)) yyerror("invalid number"); $$ = $1 / $3; } | '-' num_exp %prec NEG { $$ = -$2; } | num_exp '^' num_exp { $$ = Pow($1, $3); } | num_exp EQ num_exp { $$ = $1==$3; } | num_exp NEQ num_exp { $$ = $1!=$3; } | num_exp '<' num_exp { $$ = $1<$3; } | num_exp '>' num_exp { $$ = $1>$3; } | num_exp LEQ num_exp { $$ = $1<=$3; } | num_exp GEQ num_exp { $$ = $1>=$3; } | NOT num_exp { $$ = !$2; } | num_exp AND num_exp { $$ = $1&&$3; } | num_exp OR num_exp { $$ = $1||$3; } | num_exp '?' num_exp '|' num_exp { $$ = $1?$3:$5; } | SQRT '(' num_exp ')' { if ($3<0) yyerror("invalid number"); $$ = sqrt($3); } | EXP '(' num_exp ')' { $$ = exp($3); } | LN '(' num_exp ')' { if ($31)||($3<-1)) yyerror("invalid number"); $$ = Asin($3); } | ACOS '(' num_exp ')' { if (($3>1)||($3<-1)) yyerror("invalid number"); $$ = Acos($3); } | ATAN '(' num_exp ')' { $$ = Atan($3); } | TOKDEG '(' num_exp ')' { $$ = DEG($3); } | TOKRAD '(' num_exp ')' { $$ = RAD($3); } | TOKABS '(' num_exp ')' { $$ = fabs($3); } | SIGN '(' num_exp ')' { $$ = $3==0?0:$3>0?1:-1; } | CEIL '(' num_exp ')' { $$ = ceil($3); } | FLOOR '(' num_exp ')' { $$ = floor($3); } | ROUND '(' num_exp ')' { $$ = rint($3); } | TOKMIN '(' num_exp ',' num_exp ')' { $$ = $3<$5?$3:$5; } | TOKMAX '(' num_exp ',' num_exp ')' { $$ = $3>$5?$3:$5; } | TOKCLAMP '(' num_exp ',' num_exp ',' num_exp ')' { $$ = $3>=$5&&$3<$7?$3:$3<$5?$5:$7; } | ABSCISSA '(' point_exp ')' { $$ = $3->x; } | ABSCISSA '(' vector_exp ')' { $$ = $3->x; } | ORDINATE '(' point_exp ')' { $$ = $3->y; } | ORDINATE '(' vector_exp ')' { $$ = $3->y; } | DISTANCE '(' point_exp ',' point_exp ')' { $$ = PP_distance($3, $5); } | DISTANCE '(' point_exp ',' line_exp ')' { $$ = PL_distance($3, $5); } | LENGTH '(' vector_exp ')' { $$ = V_length($3); } | LENGTH '(' segment_exp ')' { $$ = S_length($3); } | RADIUS '(' circle_exp ')' { $$ = $3->radius; } | MAJOR '(' conic_exp ')' { $$ = $3->a; } | MINOR '(' conic_exp ')' { $$ = $3->b; } | ECCENTRICITY '(' conic_exp ')' { $$ = eccentricity($3); } | DISTANCE '(' point_exp ',' point_exp ',' point_exp ')' { $$ = height($3, $5, $7); } | ANGLE '(' vector_exp ')' { $$ = V_angle($3); } | ANGLE '(' line_exp ')' { $$ = $3->angle; } | ANGLE '(' segment_exp ')' { $$ = S_angle($3); } | ANGLE '(' conic_exp ')' { $$ = Co_angle($3); } | ANGLE '(' vector_exp ',' vector_exp ')' { $$ = VV_angle($3, $5); } | ANGLE '(' point_exp ',' point_exp ',' point_exp ')' { $$ = T_angle($3, $5, $7); } | ARGUMENT '(' circle_exp ',' point_exp ')' { $$ = C_argument($3, $5); } | ARGUMENT '(' conic_exp ',' point_exp ')' { $$ = Co_argument($3, $5); } | vector_exp '*' vector_exp { $$ = scalar($1, $3); } | '(' num_exp ')' { $$ = $2; } ; ang_exp: num_exp ':' { $$ = $1; } | num_exp '<' { $$ = DEG($1); } ; point_exp: POINT_VARIABLE { $$ = $1->object.point; } | POINT '(' num_exp ',' num_exp ')' { $$ = P_new($3, $5); } | POINT '(' num_exp ',' ang_exp ')' { $$ = P_polar($3, $5); } | POINT '(' line_exp ',' num_exp ')' { $$ = P_line($3, $5); } | POINT '(' segment_exp ',' num_exp ')' { $$ = P_segment($3, $5); } | POINT '(' circle_exp ',' ang_exp ')' { $$ = P_circle($3, $5); } | POINT '(' conic_exp ',' num_exp ')' { $$ = P_conic($3, $5); } | TRANSLATION '(' point_exp ',' vector_exp ')' { $$ = P_translation($3, $5); } | REFLECTION '(' point_exp ',' line_exp ')' { $$ = P_reflection($3, $5); } | ROTATION '(' point_exp ',' point_exp ')' { $$ = P_rotation($3, $5, 180); } | ROTATION '(' point_exp ',' point_exp ',' ang_exp ')' { $$ = P_rotation($3, $5, $7); } | PROJECTION '(' point_exp ',' line_exp ')' { $$ = P_L_projection($3, $5); } | PROJECTION '(' point_exp ',' line_exp ',' line_exp ')' { $$ = P_LL_projection($3, $5, $7); } | HOMOTHECY '(' point_exp ',' point_exp ',' num_exp ')' { $$ = P_homothecy($3, $5, $7); } | BARYCENTER '(' point_exp ',' point_exp ')' { $$ = P_2_barycenter($3, 1, $5, 1); } | BARYCENTER '(' point_exp ',' point_exp ',' point_exp ')' { $$ = P_3_barycenter($3, 1, $5, 1, $7, 1); } | BARYCENTER '(' point_exp ',' point_exp ',' point_exp ',' point_exp ')' { $$ = P_4_barycenter($3, 1, $5, 1, $7, 1, $9, 1); } | BARYCENTER '(' point_exp ',' num_exp ',' point_exp ',' num_exp ')' { $$ = P_2_barycenter($3, $5, $7, $9); } | BARYCENTER '(' point_exp ',' num_exp ',' point_exp ',' num_exp ',' point_exp ',' num_exp ')' { $$ = P_3_barycenter($3, $5, $7, $9, $11, $13); } | BARYCENTER '(' point_exp ',' num_exp ',' point_exp ',' num_exp ',' point_exp ',' num_exp ',' point_exp ',' num_exp ')' { $$ = P_4_barycenter($3, $5, $7, $9, $11, $13, $15, $17); } | INTERSECTION '(' line_exp ',' line_exp ')' { $$ = P_LL_intersection($3, $5); } | ABSCISSA '(' line_exp ',' num_exp ')' { $$ = P_abscissa($3, $5); } | ORDINATE '(' line_exp ',' num_exp ')' { $$ = P_ordinate($3, $5); } | MIDPOINT '(' segment_exp ')' { $$ = P_midpoint($3); } | TOKBEGIN '(' segment_exp ')' { $$ = P_begin($3); } | END '(' segment_exp ')' { $$ = P_end($3); } | CENTER '(' circle_exp ')' { $$ = P_center($3); } | CENTER '(' conic_exp ')' { $$ = P_Co_center($3); } | ORTHOCENTER '(' point_exp ',' point_exp ',' point_exp ')' { $$ = P_orthocenter($3, $5, $7); } | '(' point_exp ')' { $$ = $2; } ; vector_exp: VECTOR_VARIABLE { $$ = $1->object.vector; } | VECTOR '(' num_exp ',' num_exp ')' { $$ = V_NN_new($3, $5); } | VECTOR '(' num_exp ',' ang_exp ')' { $$ = V_NA_new($3, $5); } | VECTOR '(' point_exp ',' point_exp ')' { $$ = V_PP_new($3, $5); } | VECTOR '(' line_exp ')' { $$ = V_L_new($3); } | VECTOR '(' segment_exp ')' { $$ = V_S_new($3); } | ROTATION '(' vector_exp ',' ang_exp ')' { $$ = V_rotation($3, $5); } | vector_exp '+' vector_exp { $$ = V_add($1, $3); } | vector_exp '-' vector_exp { $$ = V_sub($1, $3); } | num_exp '*' vector_exp { $$ = V_mult($1, $3); } | vector_exp '/' num_exp { if ($3<0) yyerror("invalid number"); else $$ = V_mult(1 / $3, $1); } | '-' vector_exp %prec NEG { $$ = V_mult(-1, $2); } | '(' vector_exp ')' { $$ = $2; } ; line_exp: LINE_VARIABLE { $$ = $1->object.line; } | LINE '(' point_exp ',' point_exp ')' { $$ = L_PP_new($3, $5); } | LINE '(' point_exp ',' ang_exp ')' { $$ = L_PA_new($3, $5); } | LINE '(' point_exp ',' vector_exp ')' { $$ = L_PV_new($3, $5); } | LINE '(' segment_exp ')' { $$ = L_S_new($3); } | LINE '(' circle_exp ',' ang_exp ')' { $$ = L_CA_new($3, $5); } | LINE '(' conic_exp ',' num_exp ')' { $$ = L_Co_new($3, $5); } | TRANSLATION '(' line_exp ',' vector_exp ')' { $$ = L_translation($3, $5); } | REFLECTION '(' line_exp ',' line_exp ')' { $$ = L_reflection($3, $5); } | ROTATION '(' line_exp ',' point_exp ')' { $$ = L_rotation($3, $5, 180); } | ROTATION '(' line_exp ',' point_exp ',' ang_exp ')' { $$ = L_rotation($3, $5, $7); } | HOMOTHECY '(' line_exp ',' point_exp ',' num_exp ')' { $$ = L_homothecy($3, $5, $7); } | PARALLEL '(' line_exp ',' point_exp ')' { $$ = L_L_parallel($3, $5); } | PARALLEL '(' segment_exp ',' point_exp ')' { $$ = L_S_parallel($3, $5); } | PERPENDICULAR '(' line_exp ',' point_exp ')' { $$ = L_L_perpendicular($3, $5); } | PERPENDICULAR '(' segment_exp ',' point_exp ')' { $$ = L_S_perpendicular($3, $5); } | BISECTOR '(' segment_exp ')' { $$ = L_S_bisector($3); } | BISECTOR '(' point_exp ',' point_exp ',' point_exp ')' { $$ = L_P_bisector($3, $5, $7); } | BISECTOR '(' line_exp ',' line_exp ')' { $$ = L_LL_bisector($3, $5); } | ALTITUDE '(' point_exp ',' point_exp ',' point_exp ')' { $$ = L_altitude($3, $5, $7); } | MEDIAN '(' point_exp ',' point_exp ',' point_exp ')' { $$ = L_median($3, $5, $7); } | '-' line_exp %prec NEG { $$ = L_invert($2); } | '(' line_exp ')' { $$ = $2; } ; segment_exp: SEGMENT_VARIABLE { $$ = $1->object.segment; } | SEGMENT '(' point_exp ',' point_exp ')' { $$ = S_P_new($3, $5); } | SEGMENT '(' point_exp ',' vector_exp ')' { $$ = S_V_new($3, $5); } | SEGMENT '(' point_exp ',' num_exp ',' ang_exp ')' { $$ = S_NA_new($3, $5, $7); } | SEGMENT '(' circle_exp ',' ang_exp ')' { $$ = S_CA_new($3, $5); } | TRANSLATION '(' segment_exp ',' vector_exp ')' { $$ = S_translation($3, $5); } | REFLECTION '(' segment_exp ',' line_exp ')' { $$ = S_reflection($3, $5); } | ROTATION '(' segment_exp ',' point_exp ')' { $$ = S_rotation($3, $5, 180); } | ROTATION '(' segment_exp ',' point_exp ',' ang_exp ')' { $$ = S_rotation($3, $5, $7); } | HOMOTHECY '(' segment_exp ',' point_exp ',' num_exp ')' { $$ = S_homothecy($3, $5, $7); } | '-' segment_exp %prec NEG { $$ = S_invert($2); } | '(' segment_exp ')' { $$ = $2; } ; circle_exp: CIRCLE_VARIABLE { $$ = $1->object.circle; } | CIRCLE '(' point_exp ',' point_exp ')' { $$ = C_PP_new($3, $5); } | CIRCLE '(' point_exp ',' point_exp ',' point_exp ')' { $$ = C_PPP_new($3, $5, $7); } | CIRCLE '(' point_exp ',' num_exp ')' { $$ = C_PN_new($3, $5); } | TRANSLATION '(' circle_exp ',' vector_exp ')' { $$ = C_translation($3, $5); } | REFLECTION '(' circle_exp ',' line_exp ')' { $$ = C_reflection($3, $5); } | ROTATION '(' circle_exp ',' point_exp ')' { $$ = C_rotation($3, $5, 180); } | ROTATION '(' circle_exp ',' point_exp ',' ang_exp ')' { $$ = C_rotation($3, $5, $7); } | HOMOTHECY '(' circle_exp ',' point_exp ',' num_exp ')' { $$ = C_homothecy($3, $5, $7); } | INCIRCLE '(' point_exp ',' point_exp ',' point_exp ')' { $$ = C_incircle($3, $5, $7); } | '(' circle_exp ')' { $$ = $2; } ; conic_exp: CONIC_VARIABLE { $$ = $1->object.conic; } | CONIC '(' point_exp ',' line_exp ',' num_exp ')' { $$ = Co_new($3, $5, $7); } | PARABOLA '(' point_exp ',' line_exp ')' { $$ = Pa_new($3, $5); } | PARABOLA '(' point_exp ',' num_exp ',' ang_exp ')' { $$ = Co_N_new($3->x, $3->y, $7-90, fabs($5), 0, PARABOLA); } | CONIC '(' point_exp ',' point_exp ',' num_exp ')' { $$ = Co_PP_new($3, $5, $7); } | ELLIPSE '(' point_exp ',' num_exp ',' num_exp ',' ang_exp ')' { $$ = Co_N_new($3->x, $3->y, $9, fabs($5), fabs($7), ELLIPSE); } | HYPERBOLA '(' point_exp ',' num_exp ',' num_exp ',' ang_exp ')' { $$ = Co_N_new($3->x, $3->y, $9, fabs($5), fabs($7), HYPERBOLA); } | TRANSLATION '(' conic_exp ',' vector_exp ')' { $$ = Co_translation($3, $5); } | REFLECTION '(' conic_exp ',' line_exp ')' { $$ = Co_reflection($3, $5); } | ROTATION '(' conic_exp ',' point_exp ')' { $$ = Co_rotation($3, $5, 180); } | ROTATION '(' conic_exp ',' point_exp ',' ang_exp ')' { $$ = Co_rotation($3, $5, $7); } | HOMOTHECY '(' conic_exp ',' point_exp ',' num_exp ')' { $$ = Co_homothecy($3, $5, $7); } | '(' conic_exp ')' { $$ = $2; } ; multiple_assignment: variable variable INTERSECTION '(' line_exp ',' circle_exp ')' { LC_intersection($1, $2, $5, $7); } | variable variable INTERSECTION '(' circle_exp ',' circle_exp ')' { CC_intersection($1, $2, $5, $7); } | variable variable INTERSECTION '(' line_exp ',' conic_exp ')' { LCo_intersection($1, $2, $5, $7); } | variable variable VERTICES '(' conic_exp ')' { vertices($1, $2, $5); } | variable variable FOCI '(' conic_exp ')' { foci($1, $2, $5); } ; triangle_assignment: variable variable variable TRIANGLE { T_scalenes($1, $2, $3, 6, 0); } | variable variable variable TRIANGLE '(' num_exp ')' { T_scalenes($1, $2, $3, $6, 0); } | variable variable variable TRIANGLE '(' num_exp ',' ang_exp ')' { T_scalenes($1, $2, $3, $6, $8); } | variable variable variable TRIANGLE '(' num_exp ',' num_exp ',' num_exp ')' { T_3N_triangle($1, $2, $3, $6, $8, $10, 0); } | variable variable variable TRIANGLE '(' num_exp ',' num_exp ')' { T_2N_triangle($1, $2, $3, $6, $8); } | variable variable variable TRIANGLE '(' num_exp ',' num_exp ',' num_exp ',' ang_exp ')' { T_3N_triangle($1, $2, $3, $6, $8, $10, $12); } | variable variable variable TRIANGLE '(' num_exp ',' ang_exp ',' ang_exp ')' { T_2A_triangle($1, $2, $3, $6, $8, $10, 0); } | variable variable variable TRIANGLE '(' num_exp ',' ang_exp ',' ang_exp ',' ang_exp ')' { T_2A_triangle($1, $2, $3, $6, $8, $10, $12); } | variable variable variable TRIANGLE '(' ang_exp ',' ang_exp ')' { T_A_triangle($1, $2, $3, $6, $8); } | variable variable variable RIGHT { T_2N_right($1, $2, $3, 6, 4.5, 0); } | variable variable variable RIGHT '(' num_exp ')' { T_N_right($1, $2, $3, $6); } | variable variable variable RIGHT '(' num_exp ',' num_exp ')' { T_2N_right($1, $2, $3, $6, $8, 0); } | variable variable variable RIGHT '(' ang_exp ')' { T_A_triangle($1, $2, $3, $6, 90); } | variable variable variable RIGHT '(' num_exp ',' ang_exp ')' { T_2A_triangle($1, $2, $3, $6, $8, 90, 0); } | variable variable variable RIGHT '(' num_exp ',' num_exp ',' ang_exp ')' { T_2N_right($1, $2, $3, $6, $8, $10); } | variable variable variable RIGHT '(' num_exp ',' ang_exp ',' ang_exp ')' { T_2A_triangle($1, $2, $3, $6, $8, 90, $10); } | variable variable variable ISOSCELES { T_NA_isosceles($1, $2, $3, 6, 39, 0); } | variable variable variable ISOSCELES '(' ang_exp ')' { T_A_isosceles($1, $2, $3, $6); } | variable variable variable ISOSCELES '(' num_exp ',' ang_exp ')' { T_NA_isosceles($1, $2, $3, $6, $8, 0); } | variable variable variable ISOSCELES '(' num_exp ',' ang_exp ',' ang_exp ')' { T_NA_isosceles($1, $2, $3, $6, $8, $10); } | variable variable variable ISOSCELES '(' num_exp ')' { T_N_isosceles($1, $2, $3, $6); } | variable variable variable ISOSCELES '(' num_exp ',' num_exp ')' { T_2N_isosceles($1, $2, $3, $6, $8, 0); } | variable variable variable ISOSCELES '(' num_exp ',' num_exp ',' ang_exp ')' { T_2N_isosceles($1, $2, $3, $6, $8, $10); } | variable variable variable EQUILATERAL { T_E_equilateral($1, $2, $3); } | variable variable variable EQUILATERAL '(' num_exp ')' { T_equilateral($1, $2, $3, $6, 0); } | variable variable variable EQUILATERAL '(' num_exp ',' ang_exp ')' { T_equilateral($1, $2, $3, $6, $8); } ; polygon_assignment: variable variable variable variable PARALLELOGRAM { Q_E_parallelogram($1, $2, $3, $4); } | variable variable variable variable PARALLELOGRAM '(' num_exp ',' ang_exp ')' { Q_S_parallelogram($1, $2, $3, $4, $7, $9); } | variable variable variable variable PARALLELOGRAM '(' num_exp ',' num_exp ',' ang_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $9, $11, 0); } | variable variable variable variable PARALLELOGRAM '(' num_exp ',' num_exp ',' ang_exp ',' ang_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $9, $11, $13); } | variable variable variable variable PARALLELOGRAM '(' vector_exp ',' vector_exp ')' { Q_V_parallelogram($1, $2, $3, $4, $7, $9); } | variable variable variable variable RECTANGLE { Q_E_rectangle($1, $2, $3, $4); } | variable variable variable variable RECTANGLE '(' num_exp ')' { Q_S_rectangle($1, $2, $3, $4, $7); } | variable variable variable variable RECTANGLE '(' num_exp ',' num_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $9, 90, 0); } | variable variable variable variable RECTANGLE '(' num_exp ',' num_exp ',' ang_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $9, 90, $11); } | variable variable variable variable SQUARE { Q_square($1, $2, $3, $4); } | variable variable variable variable SQUARE '(' num_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $7, 90, 0); } | variable variable variable variable SQUARE '(' num_exp ',' ang_exp ')' { Q_parallelogram($1, $2, $3, $4, $7, $7, 90, $9); } | variable variable variable variable variable PENTAGON '(' point_exp ',' num_exp ',' ang_exp ')' { pentagon($1, $2, $3, $4 ,$5, $8, $10, $12); } | variable variable variable variable variable variable HEXAGON '(' point_exp ',' num_exp ',' ang_exp ')' { hexagon($1, $2, $3, $4 ,$5, $6, $9, $11, $13); } ; interactive_flag: UP { $$ = UP; } | RIGHT { $$ = RIGHT; } ; interactive_assignment: variable INTERACTIVE '(' NUMBER ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = $4; } | variable INTERACTIVE '(' '-' NUMBER ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = -$5; } | variable INTERACTIVE '(' NUMBER ',' num_exp ',' num_exp ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = $4; } | variable INTERACTIVE '(' '-' NUMBER ',' num_exp ',' num_exp ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = -$5; } | variable '=' INTERACTIVE '(' num_exp ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = $5; } | variable '=' INTERACTIVE '(' num_exp ',' num_exp ',' num_exp ',' num_exp ',' STRING ',' interactive_flag ')' { $1->type = NUMBER; $1->object.number = $5; } ; point_aspect: DOT { $$ = DOT; } | DISC { $$ = DISC; } | BOX { $$ = BOX; } | CROSS { $$ = CROSS; } | PLUS { $$ = PLUS; } ; line_aspect: ENTIRE { $$ = ENTIRE; } | HALFLINE { $$ = HALFLINE; } | BACKHALFLINE { $$ = BACKHALFLINE; } ; segment_aspect: NOARROW { $$ = NOARROW; } | ARROW { $$ = ARROW; } | BACKARROW { $$ = BACKARROW; } | DOUBLEARROW { $$ = DOUBLEARROW; } ; drawing_flag: FULL { $$ = FULL; } | DOTTED { $$ = DOTTED; } | DASHED { $$ = DASHED; } ; segment_marking_flag: SIMPLE { $$ = SIMPLE; } | DOUBLE { $$ = DOUBLE; } | TRIPLE { $$ = TRIPLE; } | CROSS { $$ = CROSS; } ; angle_marking_flag: SIMPLE { $$ = SIMPLE; } | DOUBLE { $$ = DOUBLE; } | TRIPLE { $$ = TRIPLE; } | DASHED { $$ = DASHED; } | ARROW { $$ = ARROW; } | BACKARROW { $$ = BACKARROW; } | RIGHT { $$ = RIGHT; } | DOT { $$ = DOT; } | DOTTED { $$ = DOTTED; } ; color_flag: BLACK { $$ = BLACK; } | DARKGRAY { $$ = DARKGRAY; } | GRAY { $$ = GRAY; } | LIGHTGRAY { $$ = LIGHTGRAY; } | WHITE { $$ = WHITE; } | RED { $$ = RED; } | GREEN { $$ = GREEN; } | BLUE { $$ = BLUE; } | CYAN { $$ = CYAN; } | MAGENTA { $$ = MAGENTA; } | YELLOW { $$ = YELLOW; } ; drawing_command: FRAME '(' num_exp ',' num_exp ',' num_exp ',' num_exp ')' { frame($3, $5, $7, $9, 1); } | FRAME '(' num_exp ',' num_exp ',' num_exp ',' num_exp ',' num_exp ')' { frame($3, $5, $7, $9, $11); } | BOX '(' num_exp ',' num_exp ',' num_exp ',' num_exp ')' { frame($3, $5, $7, $9, 1); } | BOX '(' num_exp ',' num_exp ',' num_exp ',' num_exp ',' num_exp ')' { frame($3, $5, $7, $9, $11); } | COLOR STRING { setcolor_string($2); } | COLOR '(' color_flag ')' { setcolor_flag($3); } | THICKNESS '(' num_exp ')' { setthickness($3); } | STYLE '(' drawing_flag ')' { drawing_style = $3; } | FONT STRING { /* Nothing to do */ } | TRICKS STRING { puttricks($2); } | STROKES '(' num_exp ')' { strokes = $3<=3?4:$3>=299?300:($3+1); } | EXPORT '(' num_exp ')' { /* Nothing to do */ } | EXPORT '(' num_exp ',' num_exp ')' { /* Nothing to do */ } | EXPORT '(' num_exp ',' num_exp ',' num_exp ')' { /* Nothing to do */ } | DRAW '(' point_exp ')' { draw_point($3, DOT, 1); } | DRAW '(' point_exp ',' point_aspect ')' { draw_point($3, $5, 1); } | DRAW '(' point_exp ',' point_aspect ',' num_exp ')' { draw_point($3, $5, $7); } | DRAW '(' vector_exp ',' point_exp ')' { draw_vector($3, $5, drawing_style); } | DRAW '(' vector_exp ',' point_exp ',' drawing_flag ')' { draw_vector($3, $5, $7); } | DRAW '(' line_exp ')' { draw_line($3, drawing_style, ENTIRE); } | DRAW '(' line_exp ',' drawing_flag ')' { draw_line($3, $5, ENTIRE); } | DRAW '(' line_exp ',' drawing_flag ',' line_aspect ')' { draw_line($3, $5, $7); } | DRAW '(' segment_exp ')' { draw_segment($3, drawing_style, NOARROW); } | DRAW '(' segment_exp ',' drawing_flag ')' { draw_segment($3, $5, NOARROW); } | DRAW '(' segment_exp ',' drawing_flag ',' segment_aspect ')' { draw_segment($3, $5, $7); } | DRAW '(' circle_exp ')' { draw_circle($3, drawing_style); } | DRAW '(' circle_exp ',' ang_exp ',' ang_exp ')' { draw_arc($3, $5, $7, drawing_style, NOARROW); } | DRAW '(' circle_exp ',' drawing_flag ')' { draw_circle($3, $5); } | DRAW '(' circle_exp ',' ang_exp ',' ang_exp ',' drawing_flag')' { draw_arc($3, $5, $7, $9, NOARROW); } | DRAW '(' circle_exp ',' ang_exp ',' ang_exp ',' drawing_flag ',' segment_aspect ')' { draw_arc($3, $5, $7, $9, $11); } | DRAW '(' conic_exp ')' { draw_conic($3, drawing_style); } | DRAW '(' conic_exp ',' drawing_flag ')' { draw_conic($3, $5); } | DRAW '(' conic_exp ',' num_exp ',' num_exp ')' { draw_conic_arc($3, $5, $7, drawing_style); } | DRAW '(' conic_exp ',' num_exp ',' num_exp ',' drawing_flag ')' { draw_conic_arc($3, $5, $7, $9); } | DRAW '(' point_exp ',' point_exp ')' { draw_digon($3, $5, drawing_style, NOARROW); } | DRAW '(' point_exp ',' point_exp ',' drawing_flag ')' { draw_digon($3, $5, $7, NOARROW); } | DRAW '(' point_exp ',' point_exp ',' drawing_flag ',' segment_aspect ')' { draw_digon($3, $5, $7, $9); } | DRAW '(' point_exp ',' point_exp ',' point_exp ')' { draw_triangle($3, $5, $7, drawing_style); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' drawing_flag ')' { draw_triangle($3, $5, $7, $9); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ')' { draw_quadrilateral($3, $5, $7, $9, drawing_style); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ',' drawing_flag ')' { draw_quadrilateral($3, $5, $7, $9, $11); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ')' { draw_pentagon($3, $5, $7, $9, $11, drawing_style); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ',' drawing_flag ')' { draw_pentagon($3, $5, $7, $9, $11, $13); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ')' { draw_hexagon($3, $5, $7, $9, $11, $13, drawing_style); } | DRAW '(' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ',' point_exp ',' drawing_flag ')' { draw_hexagon($3, $5, $7, $9, $11, $13, $15); } | DRAW '(' STRING ',' point_exp ',' ang_exp ')' { draw_P_label($3, $5, .3, $7); } | DRAW '(' STRING ',' segment_exp ',' ang_exp ')' { draw_S_label($3, $5, .3, $7); } | DRAW '(' STRING ',' point_exp ',' num_exp ',' ang_exp ')' { draw_P_label($3, $5, $7, $9); } | DRAW '(' STRING ',' segment_exp ',' num_exp ',' ang_exp ')' { draw_S_label($3, $5, $7, $9); } | DRAW '(' num_exp ',' point_exp ',' ang_exp ')' { draw_P_N($3, "%.2f", $5, .3, $7); } | DRAW '(' num_exp ',' segment_exp ',' ang_exp ')' { draw_S_N($3, "%.2f", $5, .3, $7); } | DRAW '(' num_exp ',' STRING ',' point_exp ',' ang_exp ')' { draw_P_N($3, $5, $7, .3, $9); } | DRAW '(' num_exp ',' STRING ',' segment_exp ',' ang_exp ')' { draw_S_N($3, $5, $7, .3, $9); } | DRAW '(' num_exp ',' num_exp ',' STRING ',' point_exp ',' ang_exp ')' { draw_P_NN($3, $5, $7, $9, .3, $11); } | DRAW '(' num_exp ',' num_exp ',' STRING ',' segment_exp ',' ang_exp ')' { draw_S_NN($3, $5, $7, $9, .3, $11); } | DRAW '(' num_exp ',' point_exp ',' num_exp ',' ang_exp ')' { draw_P_N($3, "%.2f", $5, $7, $9); } | DRAW '(' num_exp ',' segment_exp ',' num_exp ',' ang_exp ')' { draw_S_N($3, "%.2f", $5, $7, $9); } | DRAW '(' num_exp ',' STRING ',' point_exp ',' num_exp ',' ang_exp ')' { draw_P_N($3, $5, $7, $9, $11); } | DRAW '(' num_exp ',' STRING ',' segment_exp ',' num_exp ',' ang_exp ')' { draw_S_N($3, $5, $7, $9, $11); } | DRAW '(' num_exp ',' num_exp ',' STRING ',' point_exp ',' num_exp ',' ang_exp ')' { draw_P_NN($3, $5, $7, $9, $11, $13); } | DRAW '(' num_exp ',' num_exp ',' STRING ',' segment_exp ',' num_exp ',' ang_exp ')' { draw_S_NN($3, $5, $7, $9, $11, $13); } | LABEL '(' POINT_VARIABLE ',' num_exp ',' ang_exp ')' { draw_label($3->name, $3->object.point, $5, $7); } | LABEL '(' POINT_VARIABLE ',' ang_exp ')' { draw_label($3->name, $3->object.point, .3, $5); } | MARK '(' segment_exp ')' { mark_S($3, SIMPLE, 1); } | MARK '(' segment_exp ',' segment_marking_flag ')' { mark_S($3, $5, 1); } | MARK '(' segment_exp ',' segment_marking_flag ',' num_exp ')' { mark_S($3, $5, $7); } | MARK '(' point_exp ',' point_exp ',' point_exp ')' { mark_A($3, $5, $7, SIMPLE, 1); } | MARK '(' point_exp ',' point_exp ',' point_exp ',' angle_marking_flag ')' { mark_A($3, $5, $7, $9, 1); } | MARK '(' point_exp ',' point_exp ',' point_exp ',' angle_marking_flag ',' num_exp ')' { mark_A($3, $5, $7, $9, $11); } | '\\' ident { default_frame(); printf("\\%s",$2); } pst_opts pst_args {printf("\n");} ; pst_opts: /* nothing */ | '[' { printf("["); } pst_opt_list ']' { printf("]"); } ; pst_args: /* nothing */ | '(' pst_arg_list ')' ; pst_arg_list: pst_arg | pst_arg ',' pst_arg_list ; pst_arg: point_exp { printf("(%.4f,%.4f)",$1->x,$1->y); } | num_exp { printf("{%.4f}",$1); } | STRING { printf("{%s}",$1); } ; pst_opt_list: pst_opt | pst_opt ',' { fputs(",",stdout); } pst_opt_list ; pst_opt: STRING { fputs($1,stdout); } | ident '=' STRING { printf("%s=%s",$1,$3); } | ident '=' num_exp { printf("%s=%.4f",$1,$3); } ; ident: STRING { $$=$1; } | VARIABLE { $$=$1->name; } | ANGLE { $$="angle"; } | RADIUS { $$="radius"; } | STYLE { $$="style"; } ; newlines: | '\n' newlines ; trace_command: TRACE '(' variable ',' num_exp ',' num_exp ')' { if (traceind>0) { yyerror("parse error"); return 0; } tracevar = $3; $3->type = NUMBER; $3->object.number = $5; traceind = 0; tracebegin = $5; tracestep = ($7-$5)/(strokes-1); tracestyle = drawing_style; } | TRACE '(' variable ',' num_exp ',' num_exp ',' drawing_flag ')' { if (traceind>0) { yyerror("parse error"); return 0; } tracevar = $3; $3->type = NUMBER; $3->object.number = $5; traceind = 0; tracebegin = $5; tracestep = ($7-$5)/(strokes-1); tracestyle = $9; } | point_exp newlines '}' { if (traceind >= 0) { add_point($1, tracestyle); traceind++; tracevar->object.number = tracebegin+traceind*tracestep; if (traceind == strokes) { traceind = -1; printf("\n"); } } } ; %%