removed error message, it's handled elsewhere now
[unix-history] / usr / src / usr.bin / pascal / pdx / command / token.l
CommitLineData
6858bd7a
ML
1%{
2/* Copyright (c) 1982 Regents of the University of California */
3
4static char sccsid[] = "@(#)token.l 1.1 %G%";
5
6/*
7 * Token definitions for pdx scanner.
8 */
9
10#include "defs.h"
11#include "command.h"
12#include "y.tab.h"
13#include "symtab.h"
14#include "sym.h"
15#include "process.h"
16#include "process/pxinfo.h"
17
18char *initfile = ".pdxinit";
19
20/*
21 * This is a silly "lex" thing.
22 */
23
24#define yywrap() (1)
25
26/*
27 * Override Lex default input macros.
28 */
29
30#undef input
31#undef unput
32
33#define unput(c) ungetc(c, yyin)
34
35%}
36
37blank [ \t]
38white {blank}+
39alpha [a-zA-Z]
40digit [0-9]
41n {digit}+
42h [0-9a-fA-F]+
43e (("e"|"E")("+"|"-")?{n})
44alphanum [a-zA-Z0-9]
45ident {alpha}{alphanum}*
46filenm [^ \t\n"<>!*"]+
47qfilenm {filenm}/":"
48string '[^']+'('[^']*')*
49newline "\n"
50char .
51
52%Start file sh
53
54%%
55
56{white} ;
57^sh{white}.*$ { BEGIN 0; yylval.y_string = &yytext[3]; return(SH); }
58^sh { BEGIN 0; yylval.y_string = NIL; return(SH); }
59^{ident} { return(findcmd(yytext)); }
60{n}?\.{n}{e}? { yylval.y_real = atof(yytext); return(REAL); }
610{n} { yylval.y_long = octal(yytext); return(INT); }
620x{h} { yylval.y_long = hex(yytext); return(INT); }
63{n} { yylval.y_long = atol(yytext); return(INT); }
64<file>{filenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
65{qfilenm} { yylval.y_string = strdup(yytext); return(FILENAME); }
66at { return(AT); }
67{ident} { return(ident(yytext)); }
68{string} { yylval.y_string = yytext; return(STRING); }
69"%dp" { yylval.y_long = (long) DP; return(INT); }
70{newline} { BEGIN 0; nlflag = TRUE; return('\n'); }
71{char} { return(yylval.y_int = yytext[0]); }
72
73%%
74
75LOCAL SYMTAB *dbtab, *specialtab;
76
77/*
78 * Look for the given string in the debugger keyword table.
79 * If it's there, return the associated token, otherwise report an error.
80 */
81
82LOCAL int findcmd(s)
83char *s;
84{
85 register SYM *p;
86
87 if ((p = st_lookup(dbtab, s)) == NIL) {
88 error("\"%s\" is not a command", s);
89 }
90 yylval.y_int = tokval(p);
91 switch (toknum(p)) {
92 case ALIAS:
93 case DUMP:
94 case EDIT:
95 case CHFILE:
96 case RUN:
97 case SOURCE:
98 case STATUS:
99 BEGIN file;
100 break;
101
102 default:
103 /* do nothing */;
104 }
105 return(toknum(p));
106}
107
108/*
109 * Look for a symbol, first in the special table (if, in, etc.)
110 * then in the symbol table. If it's there, return the SYM pointer,
111 * otherwise it's an error.
112 */
113
114LOCAL int ident(s)
115char *s;
116{
117 register SYM *p;
118
119 if ((p = st_lookup(specialtab, s)) != NIL) {
120 yylval.y_sym = p;
121 return(toknum(p));
122 }
123 p = st_lookup(symtab, s);
124 if (p == NIL) {
125 if (strcmp(s, "nil") == 0) {
126 yylval.y_long = 0L;
127 return(INT);
128 } else {
129 error("\"%s\" is not defined", s);
130 }
131 }
132 yylval.y_sym = p;
133 return(NAME);
134}
135
136/*
137 * Convert a string to octal. No check that digits are less than 8.
138 */
139
140LOCAL int octal(s)
141char *s;
142{
143 register char *p;
144 register int n;
145
146 n = 0;
147 for (p = s; *p != '\0'; p++) {
148 n = 8*n + (*p - '0');
149 }
150 return(n);
151}
152
153/*
154 * Convert a string to hex.
155 */
156
157LOCAL int hex(s)
158char *s;
159{
160 register char *p;
161 register int n;
162
163 n = 0;
164 for (p = s+2; *p != '\0'; p++) {
165 n *= 16;
166 if (*p >= 'a' && *p <= 'f') {
167 n += (*p - 'a' + 10);
168 } else if (*p >= 'A' && *p <= 'F') {
169 n += (*p - 'A' + 10);
170 } else {
171 n += (*p - '0');
172 }
173 }
174 return(n);
175}
176
177/*
178 * Initialize the debugger keyword table (dbtab) and special symbol
179 * table (specialtab).
180 */
181
182#define db_keyword(nm, n) make_keyword(dbtab, nm, n)
183#define sp_keyword(nm, n) make_keyword(specialtab, nm, n)
184
185lexinit()
186{
187 dbtab = st_creat(150);
188 db_keyword("alias", ALIAS);
189 db_keyword("assign", ASSIGN);
190 db_keyword("call", CALL);
191 db_keyword("cont", CONT);
192 db_keyword("delete", DELETE);
193 db_keyword("dump", DUMP);
194 db_keyword("edit", EDIT);
195 db_keyword("file", CHFILE);
196 db_keyword("gripe", GRIPE);
197 db_keyword("help", HELP);
198 db_keyword("list", LIST);
199 db_keyword("next", NEXT);
200 db_keyword("pi", REMAKE);
201 db_keyword("print", PRINT);
202 db_keyword("quit", QUIT);
203 db_keyword("run", RUN);
204 db_keyword("sh", SH);
205 db_keyword("source", SOURCE);
206 db_keyword("status", STATUS);
207 db_keyword("step", STEP);
208 db_keyword("stop", STOP);
209 db_keyword("stopi", STOPI);
210 db_keyword("trace", TRACE);
211 db_keyword("tracei", TRACEI);
212 db_keyword("whatis", WHATIS);
213 db_keyword("where", WHERE);
214 db_keyword("which", WHICH);
215 db_keyword("xd", XD);
216 db_keyword("xi", XI);
217
218 specialtab = st_creat(10);
219 sp_keyword("div", DIV);
220 sp_keyword("mod", MOD);
221 sp_keyword("in", IN);
222 sp_keyword("if", IF);
223 sp_keyword("and", AND);
224 sp_keyword("or", OR);
225}
226
227/*
228 * Send an alias directive over to the symbol table manager.
229 */
230
231alias(new, old)
232char *new, *old;
233{
234 if (old == NIL) {
235 print_alias(dbtab, new);
236 } else {
237 enter_alias(dbtab, new, old);
238 }
239}
240
241/*
242 * Input file management routines, "yyin" is Lex's idea of
243 * where the input comes from.
244 */
245
246#define MAXINPUT 10
247
248LOCAL FILE *infp[MAXINPUT];
249LOCAL FILE **curfp = &infp[0];
250
251LOCAL BOOLEAN isnewfile;
252
253/*
254 * Initially, we set the input to the initfile if it exists.
255 * If it does exist, we play a game or two to avoid generating
256 * multiple prompts.
257 */
258
259initinput()
260{
261 FILE *fp;
262
263 fp = fopen(initfile, "r");
264 if (fp != NIL) {
265 fclose(fp);
266 setinput(initfile);
267 }
268 nlflag = TRUE;
269}
270
271/*
272 * Set the input to the named file. It is expected that the file exists
273 * and is readable.
274 */
275
276setinput(filename)
277char *filename;
278{
279 register FILE *fp;
280
281 if ((fp = fopen(filename, "r")) == NIL) {
282 error("can't open %s", filename);
283 }
284 if (curfp >= &infp[MAXINPUT]) {
285 error("unreasonable input nesting on %s", filename);
286 }
287 *curfp++ = yyin;
288 yyin = fp;
289 isnewfile = TRUE;
290}
291
292BOOLEAN isstdin()
293{
294 return((BOOLEAN) (yyin == stdin));
295}
296
297LOCAL int input()
298{
299 register int c;
300
301 if (isnewfile) {
302 isnewfile = FALSE;
303 return('\n');
304 }
305 while ((c = getc(yyin)) == EOF) {
306 if (curfp == &infp[0]) {
307 return(0);
308 } else {
309 fclose(yyin);
310 yyin = *--curfp;
311 if (yyin == stdin) {
312 prompt();
313 }
314 }
315 }
316 return(c);
317}
318
319/*
320 * Handle an input string by stripping the quotes and converting
321 * two interior quotes to one. Copy to newly allocated space and
322 * return a pointer to it.
323 *
324 * The handling of strings here is not particularly efficient,
325 * nor need it be.
326 */
327
328LOCAL char *pstring(p)
329char *p;
330{
331 int i, len;
332 char *r, *newp;
333
334 len = strlen(p);
335 r = newp = alloc(len - 2 + 1, char);
336 for (i = 1; i < len - 1; i++) {
337 if (p[i] == '\'' && p[i+1] == '\'') {
338 i++;
339 }
340 *newp++ = p[i];
341 }
342 *newp = '\0';
343 return(r);
344}
345
346/*
347 * prompt for a command
348 */
349
350prompt()
351{
352 nlflag = FALSE;
353 if (yyin == stdin) {
354 printf("> ");
355 fflush(stdout);
356 }
357}