1 %Start A str def sc br thru sh
2 %e 1700
3 %k 120
4 %a 1800
5 %o 1500
6 %p 5000
7 %n 700
8 
9 %{
10 #undef	input
11 #undef	unput
12 #include <stdio.h>
13 #include <ctype.h>
14 #include "pic.h"
15 #include "y.tab.h"
16 
17 extern	float	atof();
18 extern	struct	symtab	symtab[];
19 extern	char	*filename, *copythru();
20 
21 #define	CADD	cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;}
22 #define	CBUFLEN	500
23 char	cbuf[CBUFLEN];
24 int	c, clen, cflag, delim;
25 int	ifsw	= 0;	/* 1 if if statement in progress */
26 %}
27 
28 A	[a-zA-Z_]
29 B	[a-zA-Z0-9_]
30 D	[0-9]
31 WS	[ \t]
32 
33 %%
34 	switch (yybgin-yysvec-1) {	/* witchcraft */
35 	case 0:
36 		BEGIN A;
37 		break;
38 	case sc:
39 		BEGIN A;
40 		return('}');
41 	case br:
42 		BEGIN A;
43 		return(']');
44 	}
45 
46 <A>{WS}		;
47 <A>"\\"\n	;
48 <A>\n		{ return(ST); }
49 <A>";"		{ return(ST); }
50 <A>"}"		{ BEGIN sc; return(ST); }
51 <A>"]"		{ BEGIN br; return(ST); }
52 
53 <A>^".PS".*	{ if (curfile == infile) yyerror(".PS found inside .PS/.PE"); }
54 <A>^"."P[EF].*	{ if (curfile == infile) {
55 			yylval.i = yytext[2];
56 			return(EOF);
57 		  }
58 		}
59 <A>^".".*	{ yylval.p = tostring(yytext); return(TROFF); }
60 
61 <A>print	return(yylval.i = PRINT);
62 <A>box		return(yylval.i = BOX);
63 <A>circle	return(yylval.i = CIRCLE);
64 <A>arc		return(yylval.i = ARC);
65 <A>ellipse	return(yylval.i = ELLIPSE);
66 <A>arrow	return(yylval.i = ARROW);
67 <A>spline	return(yylval.i = SPLINE);
68 <A>line		return(yylval.i = LINE);
69 <A>move		return(yylval.i = MOVE);
70 <A>"[]"		return(yylval.i = BLOCK);
71 <A>reset	return(RESET);
72 <A>sprintf	return(SPRINTF);
73 
74 <A>same		return(SAME);
75 <A>between	return(BETWEEN);
76 <A>and		return(AND);
77 
78 <A>of		;
79 <A>the		;
80 <A>way		;
81 
82 <A>"."(e|east)		{ yylval.i = EAST; return(CORNER); }
83 <A>"."(r|right)		{ yylval.i = EAST; return(CORNER); }
84 <A>"."(w|west)		{ yylval.i = WEST; return(CORNER); }
85 <A>"."(l|left)		{ yylval.i = WEST; return(CORNER); }
86 <A>"."(n|north)		{ yylval.i = NORTH; return(CORNER); }
87 <A>"."(t|top)		{ yylval.i = NORTH; return(CORNER); }
88 <A>"."(s|south)		{ yylval.i = SOUTH; return(CORNER); }
89 <A>"."(b|bot|bottom)	{ yylval.i = SOUTH; return(CORNER); }
90 <A>"."(c|center)	{ yylval.i = CENTER; return(CORNER); }
91 <A>".start"		{ yylval.i = START; return(CORNER); }
92 <A>".end"		{ yylval.i = END; return(CORNER); }
93 <A>".ne"		{ yylval.i = NE; return(CORNER); }
94 <A>".se"		{ yylval.i = SE; return(CORNER); }
95 <A>".nw"		{ yylval.i = NW; return(CORNER); }
96 <A>".sw"		{ yylval.i = SW; return(CORNER); }
97 
98 <A>top" "+of		{ yylval.i = NORTH; return(CORNER); }
99 <A>north" "+of		{ yylval.i = NORTH; return(CORNER); }
100 <A>bottom" "+of		{ yylval.i = SOUTH; return(CORNER); }
101 <A>south" "+of		{ yylval.i = SOUTH; return(CORNER); }
102 <A>left" "+of		{ yylval.i = WEST; return(CORNER); }
103 <A>west" "+of		{ yylval.i = WEST; return(CORNER); }
104 <A>right" "+of		{ yylval.i = EAST; return(CORNER); }
105 <A>east" "+of		{ yylval.i = EAST; return(CORNER); }
106 <A>center" "+of		{ yylval.i = CENTER; return(CORNER); }
107 <A>start" "+of		{ yylval.i = START; return(CORNER); }
108 <A>end" "+of		{ yylval.i = END; return(CORNER); }
109 
110 <A>height|ht	{ yylval.i = HEIGHT; return(ATTR); }
111 <A>width|wid	{ yylval.i = WIDTH; return(ATTR); }
112 <A>radius|rad	{ yylval.i = RADIUS; return(ATTR); }
113 <A>diameter|diam { yylval.i = DIAMETER; return(ATTR); }
114 <A>size		{ yylval.i = SIZE; return(ATTR); }
115 <A>left		{ yylval.i = LEFT; return(DIR); }
116 <A>right	{ yylval.i = RIGHT; return(DIR); }
117 <A>up		{ yylval.i = UP; return(DIR); }
118 <A>down		{ yylval.i = DOWN; return(DIR); }
119 <A>cw		{ yylval.i = CW; return(ATTR); }
120 <A>clockwise	{ yylval.i = CW; return(ATTR); }
121 <A>ccw		{ yylval.i = CCW; return(ATTR); }
122 <A>invis(ible)?	{ yylval.i = INVIS; return(ATTR); }
123 <A>dot(ted)?	return(yylval.i = DOT);
124 <A>dash(ed)?	return(yylval.i = DASH);
125 <A>chop		return(yylval.i = CHOP);
126 
127 <A>spread	{ yylval.i = SPREAD; return TEXTATTR; }
128 <A>fill		{ yylval.i = FILL; return TEXTATTR; }
129 <A>ljust	{ yylval.i = LJUST; return TEXTATTR; }
130 <A>rjust	{ yylval.i = RJUST; return TEXTATTR; }
131 <A>above	{ yylval.i = ABOVE; return TEXTATTR; }
132 <A>below	{ yylval.i = BELOW; return TEXTATTR; }
133 <A>center	{ yylval.i = CENTER; return TEXTATTR; }
134 
135 <A>"<-"		{ yylval.i = HEAD1; return(HEAD); }
136 <A>"->"		{ yylval.i = HEAD2; return(HEAD); }
137 <A>"<->"	{ yylval.i = HEAD12; return(HEAD); }
138 
139 <A>".x"			return(yylval.i = DOTX);
140 <A>".y"			return(yylval.i = DOTY);
141 <A>"."(ht|height)	return(yylval.i = DOTHT);
142 <A>"."(wid|width)	return(yylval.i = DOTWID);
143 <A>"."(rad|radius)	return(yylval.i = DOTRAD);
144 
145 <A>from		return(yylval.i = FROM);
146 <A>to		return(yylval.i = TO);
147 <A>at		return(yylval.i = AT);
148 <A>by		return(yylval.i = BY);
149 <A>with		return(yylval.i = WITH);
150 <A>last		return(yylval.i = LAST);
151 
152 <A>log		return(LOG);
153 <A>exp		return(EXP);
154 <A>sin		return(SIN);
155 <A>cos		return(COS);
156 <A>atan2	return(ATAN2);
157 <A>sqrt		return(SQRT);
158 <A>rand		return(RAND);
159 <A>max		return(MAX);
160 <A>min		return(MIN);
161 <A>int		return(INT);
162 
163 <A>"=="		return(EQ);
164 <A>">="		return(GE);
165 <A>"<="		return(LE);
166 <A>"!="		return(NEQ);
167 <A>">"		return(GT);
168 <A>"<"		return(LT);
169 <A>"&&"		return(ANDAND);
170 <A>"||"		return(OROR);
171 <A>"!"		return(NOT);
172 
173 <A>Here		return(yylval.i = HERE);
174 
175 <A>for		return(FOR);
176 <A>^Endfor\n	{ endfor(); }
177 <A>do		{ yylval.p = delimstr("loop body"); return(DOSTR); }
178 
179 <A>copy|include		return(COPY);
180 <A>(thru|through){WS}+	{ BEGIN thru; return(THRU); }
181 <thru>{A}{B}*|.		{ yylval.p = copythru(yytext); BEGIN A; return(DEFNAME); }
182 <A>until		return(UNTIL);
183 
184 <A>if		{ ifsw = 1; return(IF); }
185 <A>then		{ if (!ifsw) { yylval.i = THEN; return(ATTR); }
186 		  yylval.p = delimstr("then part"); ifsw = 0;
187 		  return(THENSTR); }
188 <A>else		{ yylval.p = delimstr("else part"); return(ELSESTR); }
189 
190 <A>sh{WS}+	{ BEGIN sh;
191 		  if ((delim = input()) == '{') delim = '}';	/* no nested {} */
192 		  shell_init(); }
193 <sh>{A}{B}*	{ struct symtab *p;
194 		  if (yytext[0] == delim) {
195 			shell_exec();
196 			BEGIN A;
197 		  } else {
198 			p = lookup(yytext, 0);
199 			if (p != NULL && p->s_type == DEFNAME) {
200 				c = input();
201 				unput(c);
202 				if (c == '(')
203 					dodef(p);
204 				else
205 					pbstr(p->s_val.p);
206 			} else
207 				shell_text(yytext);
208 		  }
209 		}
210 <sh>.|\n	{ if (yytext[0] == delim) {
211 			shell_exec();
212 			BEGIN A;
213 		  } else
214 			shell_text(yytext);
215 		}
216 
217 <A>define{WS}+		{ BEGIN def; }
218 <def>{A}{B}*		{ definition(yytext); BEGIN A; }
219 <A>undef(ine)?{WS}+{A}{B}*	{ undefine(yytext); }
220 
221 <A>first		{ yylval.i = 1; return(NTH); }
222 <A>{D}+(th|nd|rd|st)	{ yylval.i = atoi(yytext); return(NTH); }
223 <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? {
224 		  	yylval.f = atof(yytext); return(NUMBER); }
225 
226 <A>{A}{B}* {	struct symtab *p;
227 		p = lookup(yytext);
228 		if (p != NULL && p->s_type == DEFNAME) {
229 			c = input();
230 			unput(c);
231 			if (c == '(')	/* it's name(...) */
232 				dodef(p);
233 			else {	/* no argument list */
234 				pbstr(p->s_val);
235 				dprintf("pushing back `%s'\n", p->s_val);
236 			}
237 		} else if (islower(yytext[0])) {
238 			yylval.p = tostring(yytext);
239 			return(VARNAME);
240 		} else {
241 			yylval.p = tostring(yytext);
242 			return(PLACENAME);
243 		}
244 	}
245 
246 <A>\"		{ BEGIN str; clen=0; }
247 <str>\"		{ cbuf[clen]=0; yylval.p = tostring(cbuf); BEGIN A; return(TEXT); }
248 <str>\n		{ yyerror("newline in string"); BEGIN A; return(ST); }
249 <str>"\\\""	{ cbuf[clen++]='"'; }
250 <str>"\\"t	{ cbuf[clen++]='\t'; }
251 <str>"\\\\"	{ cbuf[clen++]='\\'; }
252 <str>.		{ CADD; }
253 
254 <A>#.*		;
255 
256 <A>.		return(yylval.i = yytext[0]);
257 
258 %%
259