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