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