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