1 %Start A str def thru sh
2 
3 %{
4 #undef	input
5 #undef	unput
6 #include <stdio.h>
7 #include <ctype.h>
8 #include "grap.h"
9 #include "y.tab.h"
10 
11 extern	struct	symtab	symtab[];
12 
13 #define	CADD	cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;}
14 #define	CBUFLEN	1500
15 char	cbuf[CBUFLEN];
16 int	clen, cflag;
17 int	c, delim;
18 %}
19 
20 A	[a-zA-Z_]
21 B	[a-zA-Z0-9_]
22 D	[0-9]
23 WS	[ \t]
24 
25 %%
26 	if (yybgin-yysvec-1 == 0) {	/* witchcraft */
27 		BEGIN A;
28 	}
29 
30 <A>{WS}		;
31 <A>"\\"\n	;
32 <A>\n		return(ST);
33 <A>";"		return(ST);
34 
35 <A>line		return(yylval.i = LINE);
36 <A>arrow	{ yylval.i = ARROW; return(LINE); }
37 <A>circle	return(yylval.i = CIRCLE);
38 <A>frame	return(FRAME);
39 <A>tick(s)?	return(TICKS);
40 <A>grid(line)?(s)?	return(GRID);
41 <A>coord(s)?	return(COORD);
42 <A>log		return(LOG);
43 <A>exp		return(EXP);
44 <A>sin		return(SIN);
45 <A>cos		return(COS);
46 <A>atan2	return(ATAN2);
47 <A>sqrt		return(SQRT);
48 <A>rand		return(RAND);
49 <A>max		return(MAX);
50 <A>min		return(MIN);
51 <A>int		return(INT);
52 <A>print	return(PRINT);
53 <A>pic{WS}.*	{ yylval.p = tostring(yytext+3); return(PIC); }
54 <A>graph{WS}.*	{ yylval.p = tostring(yytext+5); return(GRAPH); }
55 
56 <A>for		return(FOR);
57 <A>^Endfor\n	{ endfor(); }
58 <A>do		{ yylval.p = delimstr("loop body"); BEGIN A; return(DOSTR); }
59 
60 <A>copy|include	{ return(COPY); }
61 <A>thru|through	{ BEGIN thru; return(THRU); }
62 <thru>{WS}+	;
63 <thru>{A}{B}*|.	{ yylval.op = copythru(yytext); BEGIN A; return(DEFNAME); }
64 <A>until	return(UNTIL);
65 
66 <A>if		return(IF);
67 <A>then		{ yylval.p = delimstr("then part"); BEGIN A; return(THEN); }
68 <A>else		{ yylval.p = delimstr("else part"); BEGIN A; return(ELSE); }
69 
70 <A>next		return(NEXT);
71 <A>draw		return(yylval.i = DRAW);
72 <A>new		return(yylval.i = NEW);
73 <A>plot		return(yylval.i = PLOT);
74 <A>label(s)?	return(LABEL);
75 <A>x		return(X);
76 <A>y		return(Y);
77 
78 <A>top		{ yylval.i = TOP; return SIDE; }
79 <A>bot(tom)?	{ yylval.i = BOT; return SIDE; }
80 <A>left		{ yylval.i = LEFT; return SIDE; }
81 <A>right	{ yylval.i = RIGHT; return SIDE; }
82 <A>up		return(yylval.i = UP);
83 <A>down		return(yylval.i = DOWN);
84 <A>across	return(yylval.i = ACROSS);
85 <A>height|ht	return(yylval.i = HEIGHT);
86 <A>wid(th)?	return(yylval.i = WIDTH);
87 <A>rad(ius)?	return(yylval.i = RADIUS);
88 <A>invis	return(yylval.i = INVIS);
89 <A>dot(ted)	return(yylval.i = DOT);
90 <A>dash(ed)	return(yylval.i = DASH);
91 <A>solid	return(yylval.i = SOLID);
92 
93 <A>ljust	{ yylval.i = LJUST; return JUST; }
94 <A>rjust	{ yylval.i = RJUST; return JUST; }
95 <A>above	{ yylval.i = ABOVE; return JUST; }
96 <A>below	{ yylval.i = BELOW; return JUST; }
97 <A>size		return(yylval.i = SIZE);
98 
99 <A>from		return(yylval.i = FROM);
100 <A>to		return(yylval.i = TO);
101 <A>by|step	return(yylval.i = BY);
102 <A>at		return(yylval.i = AT);
103 <A>with		return(yylval.i = WITH);
104 <A>in		return(yylval.i = IN);
105 <A>out		return(yylval.i = OUT);
106 <A>off		return(yylval.i = OFF);
107 
108 <A>sh{WS}+ {	BEGIN sh;
109 		if ((delim = input()) == '{') delim = '}';	/* no nested {} */
110 		shell_init(); }
111 <sh>{A}{B}* {
112 		int c;
113 		Obj *p;
114 		if (yytext[0] == delim) {
115 			shell_exec();
116 			BEGIN A;
117 		} else {
118 			p = lookup(yytext, 0);
119 			if (p != NULL && p->type == DEFNAME) {
120 				c = input();
121 				unput(c);
122 				if (c == '(')
123 					dodef(p);
124 				else
125 					pbstr(p->val);
126 			} else
127 				shell_text(yytext);
128 		}
129 	}
130 <sh>.|\n	{ if (yytext[0] == delim) {
131 			shell_exec();
132 			BEGIN A;
133 		  } else
134 			shell_text(yytext);
135 		}
136 
137 <A>define{WS}+	{ BEGIN def; }
138 <def>{A}{B}*	{ definition(yytext); BEGIN A; }
139 
140 <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? {
141 		  yylval.f = atof(yytext); return(NUMBER); }
142 
143 <A>^"."[^{D}].*	{ if (yytext[1] == 'G' && yytext[2] == '2') {
144 			yylval.i = yytext[2];
145 			return(EOF);
146 		  } else {
147 			yylval.p = tostring(yytext);
148 			return(PIC);
149 		  }
150 		}
151 
152 <A>{A}{B}* {
153 		int c;
154 		Obj *p;
155 		p = lookup(yytext, 1);
156 		if (p->type == DEFNAME) {
157 			c = input();
158 			unput(c);
159 			if (c == '(')	/* it's name(...) */
160 				dodef(p);
161 			else	/* no argument list */
162 				pbstr(p->val);
163 		} else {
164 			yylval.op = p;
165 			return p->type;	/* NAME or VARNAME */
166 		}
167 	}
168 
169 <A>"=="		return(EQ);
170 <A>">="		return(GE);
171 <A>"<="		return(LE);
172 <A>"!="		return(NE);
173 <A>">"		return(GT);
174 <A>"<"		return(LT);
175 <A>"&&"		return(AND);
176 <A>"||"		return(OR);
177 <A>"!"		return(NOT);
178 
179 <A>\"		{ BEGIN str; clen = 0; }
180 
181 <A>#.*		;
182 
183 <A>.		{ yylval.i = yytext[0]; return(yytext[0]); }
184 
185 <str>\"		{ BEGIN A; cbuf[clen] = 0;
186 		  yylval.p = tostring(cbuf); return(STRING); }
187 <str>\n		{ yyerror("newline in string"); BEGIN A; return(ST); }
188 <str>"\\\""	{ cbuf[clen++] = '\\'; cbuf[clen++] = '"'; }
189 <str>"\\\\"	{ cbuf[clen++] = '\\'; cbuf[clen++] = '\\'; }
190 <str>.		{ CADD; }
191 
192 %%
193