/* * 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. */ %x FILTER %{ #include #include #include "types.h" #include "parser.tab.h" #define FILTER_MODE 0 #define NORMAL_MODE 1 #define TRACE_MODE 2 #define STRING_MODE 3 #define COMMENT_MODE 4 int warning(char *); extern int filter, undefined, lineno, drawing_style, first, inputmode; int count, pos; extern char * buffer; symrec *sym_table = NULL; /* Symbol table management */ symrec *putsym (char *sym_name) { symrec *ptr; ptr = (symrec *)malloc (sizeof (symrec)); ptr->name = (char *) malloc (strlen (sym_name) + 1); strcpy (ptr->name, sym_name); ptr->type = VARIABLE; ptr->next = sym_table; sym_table = ptr; return ptr; } symrec *getsym (char *sym_name) { symrec *ptr; for (ptr = sym_table; ptr != NULL; ptr = ptr->next) if (strcmp (ptr->name, sym_name) == 0) return ptr; return NULL; } void clearsym(void) { symrec *ptr, *prev; ptr = sym_table; while (ptr != NULL) { free(ptr->name); prev = ptr; ptr = ptr->next; free(prev); } sym_table = NULL; } saverec *save_table = NULL; void save(void * s) { saverec *ptr; ptr = (saverec *)malloc(sizeof(saverec)); ptr->s = s; ptr->next = save_table; save_table = ptr; } void clearsave(void) { saverec *ptr, *prev; ptr = save_table; while (ptr != NULL) { free(ptr->s); prev = ptr; ptr = ptr->next; free(prev); } save_table = NULL; } #undef YY_INPUT #define YY_INPUT(buf,result,max) (result = char_input(buf,max)) /* Input function */ int char_input(char *buf, int max) { int n; static int cursor = 0, bracepos, loopcount, lastmode; n = 0; while (buffer[cursor] != '\0' && n < max) { buf[n] = buffer[cursor]; switch (buffer[cursor]) { case '%': if (inputmode == FILTER_MODE && strncmp("%--eukleides",buffer+cursor,12) == 0) inputmode = COMMENT_MODE; if (inputmode == NORMAL_MODE) { inputmode = COMMENT_MODE; if (strncmp("%--end",buffer+cursor,6) == 0 || strncmp("%--stop",buffer+cursor,7) == 0) inputmode = FILTER_MODE; }; break; case '\n': if (inputmode == STRING_MODE || inputmode == COMMENT_MODE) inputmode = NORMAL_MODE; break; case '"': if (inputmode == NORMAL_MODE || inputmode == TRACE_MODE) { lastmode = inputmode; inputmode = STRING_MODE; } else if (inputmode == STRING_MODE) inputmode = lastmode; break; case '{': if (inputmode == NORMAL_MODE) { bracepos = cursor-1; buffer[cursor] = ';'; loopcount = 300; inputmode = TRACE_MODE; } break; case '}': if (inputmode == TRACE_MODE) { if (--loopcount) cursor = bracepos; else inputmode = NORMAL_MODE; } }; cursor++; n++; } return n; } int yywrap(void) { return 1; } %} %% %{ if (filter) BEGIN FILTER; else BEGIN INITIAL; %} /* Ignore whitespace */ [\t ]+ /* Stop compiling */ "%--stop"[\t ]*\n { lineno++; filter = 1; undefined = 1; printf("\\endpspicture\n"); printf("%% End of figure\n"); BEGIN FILTER; } "%--end"[\t ]*\n { lineno++; filter = 1; clearsave(); /* Clear memory */ clearsym(); sym_table = NULL; undefined = 1; drawing_style = FULL; printf("\\endpspicture\n"); printf("%% End of figure\n"); BEGIN FILTER; } /* Comments */ %.*\n { lineno++; } %.* { return '\n'; } /* Numbers */ (([0-9]+)|([0-9]*\.[0-9]+)) { yylval.number = atof(yytext); return NUMBER; } /* Strings */ \"[^\"\n]*[\"\n] { yylval.string = strdup(yytext+1); if (yylval.string[yyleng-2] != '"') { warning("Unterminated character string"); lineno++; } else yylval.string[yyleng-2] = '\0'; return STRING; } \$[^\$\n]*[\$\n] { yylval.string = strdup(yytext); if (yylval.string[yyleng-1] != '$') { warning("Unterminated character string"); lineno++; } return STRING; } /* Reserved words */ point { return POINT; } vector { return VECTOR; } line { return LINE; } segment { return SEGMENT; } circle { return CIRCLE; } conic { return CONIC; } parabola { return PARABOLA; } ellipse { return ELLIPSE; } hyperbola { return HYPERBOLA; } translation { return TRANSLATION; } reflection { return REFLECTION; } rotation { return ROTATION; } projection { return PROJECTION; } homothecy { return HOMOTHECY; } intersection { return INTERSECTION; } parallel { return PARALLEL; } perpendicular { return PERPENDICULAR; } midpoint { return MIDPOINT; } begin { return TOKBEGIN; } end { return END; } center { return CENTER; } vertices { return VERTICES; } foci { return FOCI; } triangle { return TRIANGLE; } equilateral { return EQUILATERAL; } isosceles { return ISOSCELES; } right { return RIGHT; } barycenter { return BARYCENTER; } median { return MEDIAN; } altitude { return ALTITUDE; } orthocenter { return ORTHOCENTER; } bisector { return BISECTOR; } incircle { return INCIRCLE; } parallelogram { return PARALLELOGRAM; } rectangle { return RECTANGLE; } square { return SQUARE; } pentagon { return PENTAGON; } hexagon { return HEXAGON; } abscissa { return ABSCISSA; } ordinate { return ORDINATE; } length { return LENGTH; } distance { return DISTANCE; } angle { return ANGLE; } arg { return ARGUMENT; } radius { return RADIUS; } major { return MAJOR; } minor { return MINOR; } eccentricity { return ECCENTRICITY; } height { return HEIGHT; } exp { return EXP; } ln { return LN; } pi { return TOKPI; } sin { return SIN; } cos { return COS; } tan { return TAN; } asin { return ASIN; } acos { return ACOS; } atan { return ATAN; } deg { return TOKDEG; } rad { return TOKRAD; } sqrt { return SQRT; } abs { return TOKABS; } sign { return SIGN; } ceil { return CEIL; } floor { return FLOOR; } round { return ROUND; } min { return TOKMIN; } max { return TOKMAX; } clamp { return TOKCLAMP; } "==" { return EQ; } "!=" { return NEQ; } "<=" { return LEQ; } ">=" { return GEQ; } and { return AND; } or { return OR; } not { return NOT; } frame { return FRAME; } color { return COLOR; } black { return BLACK; } darkgray { return DARKGRAY; } gray { return GRAY; } lightgray { return LIGHTGRAY; } white { return WHITE; } red { return RED; } green { return GREEN; } blue { return BLUE; } cyan { return CYAN; } magenta { return MAGENTA; } yellow { return YELLOW; } thickness { return THICKNESS; } font { return FONT; } tricks { return TRICKS; } export { return EXPORT; } draw { return DRAW; } label { return LABEL; } mark { return MARK; } dot { return DOT; } disc { return DISC; } box { return BOX; } cross { return CROSS; } plus { return PLUS; } noarrow { return NOARROW; } arrow { return ARROW; } backarrow { return BACKARROW; } doublearrow { return DOUBLEARROW; } entire { return ENTIRE;} halfline { return HALFLINE; } backhalfline { return BACKHALFLINE; } style { return STYLE; } full { return FULL; } dotted { return DOTTED; } dashed { return DASHED; } simple { return SIMPLE; } double { return DOUBLE; } triple { return TRIPLE; } interactive { return INTERACTIVE; } up { return UP; } strokes { return STROKES; } trace { return TRACE; } /* Variables */ [a-zA-Z_][a-zA-Z0-9_']* { symrec *s; s = getsym (yytext); if (s == NULL) s = putsym (yytext); yylval.ptr = s; switch (s->type) { case NUMBER : return NUMBER_VARIABLE; case POINT : return POINT_VARIABLE; case VECTOR : return VECTOR_VARIABLE; case LINE : return LINE_VARIABLE; case SEGMENT : return SEGMENT_VARIABLE; case CIRCLE : return CIRCLE_VARIABLE; case CONIC : return CONIC_VARIABLE; case VARIABLE : return VARIABLE; } } /* Semi-colons and \r are handled as \n */ (;)|(\r) { return '\n'; } /* New line */ \n { lineno++; return '\n'; } /* Trace command block */ "{" { if (first) { count = 300; pos = lineno; first = 0; return '\n'; } else return '{'; } "}" { if (count == 300) lineno -= 299*(lineno-pos); if (--count == 0) first = 1; return '}'; } /* Anything else */ . { return yytext[0]; } /* Start compiling */ "%--eukleides"[\t ]*\n { lineno++; filter = 0; printf("%% Generated by eukleides 1.0.3\n"); printf("\\psset{linecolor=black, linewidth=.5pt, arrowsize=2pt 4}\n"); BEGIN INITIAL; } /* New line */ \n { lineno++; ECHO; } /* Anything else */ . { ECHO; } %%