|
|
1.1 root 1: %Start A str sc reg comment
2:
3: %{
4: /*
5: Copyright (c) 1989 AT&T
6: All Rights Reserved
7:
8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.
9:
10: The copyright notice above does not evidence any
11: actual or intended publication of such source code.
12: */
13:
14: #undef input /* defeat lex */
15: #undef unput
16:
17: #include <stdlib.h>
18: #include <string.h>
19: #include "awk.h"
20: #include "y.tab.h"
21:
22: extern YYSTYPE yylval;
23: extern int infunc;
24:
25: int lineno = 1;
26: int bracecnt = 0;
27: int brackcnt = 0;
28: int parencnt = 0;
29: #define DEBUG
30: #ifdef DEBUG
31: # define RET(x) {if(dbg)printf("lex %s [%s]\n", tokname(x), yytext); return(x); }
32: #else
33: # define RET(x) return(x)
34: #endif
35:
36: #define CADD cbuf[clen++] = yytext[0]; \
37: if (clen >= CBUFLEN-1) { \
38: ERROR "string/reg expr %.10s... too long", cbuf SYNTAX; \
39: BEGIN A; \
40: }
41:
42: uchar cbuf[CBUFLEN];
43: uchar *s;
44: int clen, cflag;
45: %}
46:
47: A [a-zA-Z_]
48: B [a-zA-Z0-9_]
49: D [0-9]
50: O [0-7]
51: H [0-9a-fA-F]
52: WS [ \t]
53:
54: %%
55: switch (yybgin-yysvec-1) { /* witchcraft */
56: case 0:
57: BEGIN A;
58: break;
59: case sc:
60: BEGIN A;
61: RET('}');
62: }
63:
64: <A>\n { lineno++; RET(NL); }
65: <A>#.* { ; } /* strip comments */
66: <A>{WS}+ { ; }
67: <A>; { RET(';'); }
68:
69: <A>"\\"\n { lineno++; }
70: <A>BEGIN { RET(XBEGIN); }
71: <A>END { RET(XEND); }
72: <A>func(tion)? { if (infunc) ERROR "illegal nested function" SYNTAX; RET(FUNC); }
73: <A>return { if (!infunc) ERROR "return not in function" SYNTAX; RET(RETURN); }
74: <A>"&&" { RET(AND); }
75: <A>"||" { RET(BOR); }
76: <A>"!" { RET(NOT); }
77: <A>"!=" { yylval.i = NE; RET(NE); }
78: <A>"~" { yylval.i = MATCH; RET(MATCHOP); }
79: <A>"!~" { yylval.i = NOTMATCH; RET(MATCHOP); }
80: <A>"<" { yylval.i = LT; RET(LT); }
81: <A>"<=" { yylval.i = LE; RET(LE); }
82: <A>"==" { yylval.i = EQ; RET(EQ); }
83: <A>">=" { yylval.i = GE; RET(GE); }
84: <A>">" { yylval.i = GT; RET(GT); }
85: <A>">>" { yylval.i = APPEND; RET(APPEND); }
86: <A>"++" { yylval.i = INCR; RET(INCR); }
87: <A>"--" { yylval.i = DECR; RET(DECR); }
88: <A>"+=" { yylval.i = ADDEQ; RET(ASGNOP); }
89: <A>"-=" { yylval.i = SUBEQ; RET(ASGNOP); }
90: <A>"*=" { yylval.i = MULTEQ; RET(ASGNOP); }
91: <A>"/=" { yylval.i = DIVEQ; RET(ASGNOP); }
92: <A>"%=" { yylval.i = MODEQ; RET(ASGNOP); }
93: <A>"^=" { yylval.i = POWEQ; RET(ASGNOP); }
94: <A>"**=" { yylval.i = POWEQ; RET(ASGNOP); }
95: <A>"=" { yylval.i = ASSIGN; RET(ASGNOP); }
96: <A>"**" { RET(POWER); }
97: <A>"^" { RET(POWER); }
98:
99: <A>"$"{D}+ { yylval.cp = fieldadr(atoi(yytext+1)); RET(FIELD); }
100: <A>"$NF" { unputstr("(NF)"); return(INDIRECT); }
101: <A>"$"{A}{B}* { int c, n;
102: c = input(); unput(c);
103: if (c == '(' || c == '[' || infunc && (n=isarg(yytext+1)) >= 0) {
104: unputstr(yytext+1);
105: return(INDIRECT);
106: } else {
107: yylval.cp = setsymtab(yytext+1,"",0.0,STR|NUM,symtab);
108: RET(IVAR);
109: }
110: }
111: <A>"$" { RET(INDIRECT); }
112: <A>NF { yylval.cp = setsymtab(yytext, "", 0.0, NUM, symtab); RET(VARNF); }
113:
114: <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)? {
115: yylval.cp = setsymtab(yytext, tostring(yytext), atof(yytext), CON|NUM, symtab);
116: /* should this also have STR set? */
117: RET(NUMBER); }
118:
119: <A>while { RET(WHILE); }
120: <A>for { RET(FOR); }
121: <A>do { RET(DO); }
122: <A>if { RET(IF); }
123: <A>else { RET(ELSE); }
124: <A>next { RET(NEXT); }
125: <A>exit { RET(EXIT); }
126: <A>break { RET(BREAK); }
127: <A>continue { RET(CONTINUE); }
128: <A>print { yylval.i = PRINT; RET(PRINT); }
129: <A>printf { yylval.i = PRINTF; RET(PRINTF); }
130: <A>sprintf { yylval.i = SPRINTF; RET(SPRINTF); }
131: <A>split { yylval.i = SPLIT; RET(SPLIT); }
132: <A>substr { RET(SUBSTR); }
133: <A>sub { yylval.i = SUB; RET(SUB); }
134: <A>gsub { yylval.i = GSUB; RET(GSUB); }
135: <A>index { RET(INDEX); }
136: <A>match { RET(MATCHFCN); }
137: <A>in { RET(IN); }
138: <A>getline { RET(GETLINE); }
139: <A>close { RET(CLOSE); }
140: <A>delete { RET(DELETE); }
141: <A>length { yylval.i = FLENGTH; RET(BLTIN); }
142: <A>log { yylval.i = FLOG; RET(BLTIN); }
143: <A>int { yylval.i = FINT; RET(BLTIN); }
144: <A>exp { yylval.i = FEXP; RET(BLTIN); }
145: <A>sqrt { yylval.i = FSQRT; RET(BLTIN); }
146: <A>sin { yylval.i = FSIN; RET(BLTIN); }
147: <A>cos { yylval.i = FCOS; RET(BLTIN); }
148: <A>atan2 { yylval.i = FATAN; RET(BLTIN); }
149: <A>system { yylval.i = FSYSTEM; RET(BLTIN); }
150: <A>rand { yylval.i = FRAND; RET(BLTIN); }
151: <A>srand { yylval.i = FSRAND; RET(BLTIN); }
152: <A>toupper { yylval.i = FTOUPPER; RET(BLTIN); }
153: <A>tolower { yylval.i = FTOLOWER; RET(BLTIN); }
154: <A>fflush { yylval.i = FFLUSH; RET(BLTIN); }
155:
156: <A>{A}{B}* { int n, c;
157: c = input(); unput(c); /* look for '(' */
158: if (c != '(' && infunc && (n=isarg(yytext)) >= 0) {
159: yylval.i = n;
160: RET(ARG);
161: } else {
162: yylval.cp = setsymtab(yytext,"",0.0,STR|NUM,symtab);
163: if (c == '(') {
164: RET(CALL);
165: } else {
166: RET(VAR);
167: }
168: }
169: }
170: <A>\" { BEGIN str; clen = 0; }
171:
172: <A>"}" { if (--bracecnt < 0) ERROR "extra }" SYNTAX; BEGIN sc; RET(';'); }
173: <A>"]" { if (--brackcnt < 0) ERROR "extra ]" SYNTAX; RET(']'); }
174: <A>")" { if (--parencnt < 0) ERROR "extra )" SYNTAX; RET(')'); }
175:
176: <A>. { if (yytext[0] == '{') bracecnt++;
177: else if (yytext[0] == '[') brackcnt++;
178: else if (yytext[0] == '(') parencnt++;
179: RET(yylval.i = yytext[0]); /* everything else */ }
180:
181: <reg>\\. { cbuf[clen++] = '\\'; cbuf[clen++] = yytext[1]; }
182: <reg>\n { ERROR "newline in regular expression %.10s...", cbuf SYNTAX; lineno++; BEGIN A; }
183: <reg>"/" { BEGIN A;
184: cbuf[clen] = 0;
185: yylval.s = tostring(cbuf);
186: unput('/');
187: RET(REGEXPR); }
188: <reg>. { CADD; }
189:
190: <str>\" { BEGIN A;
191: cbuf[clen] = 0; s = tostring(cbuf);
192: cbuf[clen] = ' '; cbuf[++clen] = 0;
193: yylval.cp = setsymtab(cbuf, s, 0.0, CON|STR, symtab);
194: RET(STRING); }
195: <str>\n { ERROR "newline in string %.10s...", cbuf SYNTAX; lineno++; BEGIN A; }
196: <str>"\\\"" { cbuf[clen++] = '"'; }
197: <str>"\\"n { cbuf[clen++] = '\n'; }
198: <str>"\\"t { cbuf[clen++] = '\t'; }
199: <str>"\\"f { cbuf[clen++] = '\f'; }
200: <str>"\\"r { cbuf[clen++] = '\r'; }
201: <str>"\\"b { cbuf[clen++] = '\b'; }
202: <str>"\\"v { cbuf[clen++] = '\v'; } /* these ANSIisms may not be known by */
203: <str>"\\"a { cbuf[clen++] = '\007'; } /* your compiler. hence 007 for bell */
204: <str>"\\\\" { cbuf[clen++] = '\\'; }
205: <str>"\\"({O}{O}{O}|{O}{O}|{O}) { int n;
206: sscanf(yytext+1, "%o", &n); cbuf[clen++] = n; }
207: <str>"\\"x({H}+) { int n; /* ANSI permits any number! */
208: sscanf(yytext+2, "%x", &n); cbuf[clen++] = n; }
209: <str>"\\". { cbuf[clen++] = yytext[1]; }
210: <str>. { CADD; }
211:
212: %%
213:
214: void startreg(void)
215: {
216: BEGIN reg;
217: clen = 0;
218: }
219:
220: /* input() and unput() are transcriptions of the standard lex
221: macros for input and output with additions for error message
222: printing. God help us all if someone changes how lex works.
223: */
224:
225: uchar ebuf[300];
226: uchar *ep = ebuf;
227:
228: input(void)
229: {
230: register int c;
231: extern uchar *lexprog;
232:
233: if (yysptr > yysbuf)
234: c = U(*--yysptr);
235: else if (lexprog != NULL) { /* awk '...' */
236: if (c = *lexprog)
237: lexprog++;
238: } else /* awk -f ... */
239: c = pgetc();
240: if (c == '\n')
241: yylineno++;
242: else if (c == EOF)
243: c = 0;
244: if (ep >= ebuf + sizeof ebuf)
245: ep = ebuf;
246: return *ep++ = c;
247: }
248:
249: void unput(int c)
250: {
251: yytchar = c;
252: if (yytchar == '\n')
253: yylineno--;
254: *yysptr++ = yytchar;
255: if (--ep < ebuf)
256: ep = ebuf + sizeof(ebuf) - 1;
257: }
258:
259:
260: void unputstr(char *s)
261: {
262: int i;
263:
264: for (i = strlen(s)-1; i >= 0; i--)
265: unput(s[i]);
266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.