/*
* 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 <stdlib.h>
#include <string.h>
#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 */
<FILTER>"%--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 */
<FILTER>\n { lineno++; ECHO; }
/* Anything else */
<FILTER>. { ECHO; }
%%
syntax highlighted by Code2HTML, v. 0.9.1