|
|
1.1 root 1: /* awk.lx.l 4.4 90/06/25 */
2:
3: %X str chc reg comment
4:
5: %{
6: #include <string.h>
7: #include "awk.h"
8: #include "awk.def"
9: extern int yylval;
10: extern int mustfld;
11: extern int ldbg;
12: extern char *lexprog;
13:
14: #undef YY_INPUT
15: #define YY_INPUT(buf,result,max_size) \
16: { \
17: if ( lexprog ) \
18: { \
19: result = strlen( lexprog ); \
20: if ( result > max_size ) \
21: { \
22: result = max_size; \
23: strncpy( buf, lexprog, result ); \
24: } \
25: else \
26: strcpy( buf, lexprog ); \
27: lexprog += result; \
28: } \
29: else \
30: result = read( fileno(yyin), buf, max_size ); \
31: }
32:
33: int lineno = 1;
34: #define RETURN(x) {if (ldbg) ptoken(x); return(x); }
35: #define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN INITIAL;}
36: #define CBUFLEN 150
37: char cbuf[CBUFLEN];
38: int clen, cflag;
39: %}
40:
41: A [a-zA-Z_]
42: B [a-zA-Z0-9_]
43: D [0-9]
44: WS [ \t]
45:
46: %%
47: static int sc_flag = 0;
48:
49: if ( sc_flag ) {
50: BEGIN INITIAL;
51: sc_flag = 0;
52: RETURN('}');
53: }
54:
55: ^\n lineno++;
56: ^{WS}*#.*\n lineno++; /* strip comment lines */
57: {WS} ;
58: <INITIAL,reg>"\\"\n lineno++;
59: "||" RETURN(BOR);
60: BEGIN RETURN(XBEGIN);
61: END RETURN(XEND);
62: PROGEND RETURN(EOF);
63: "&&" RETURN(AND);
64: "!" RETURN(NOT);
65: "!=" { yylval = NE; RETURN(RELOP); }
66: "~" { yylval = MATCH; RETURN(MATCHOP); }
67: "!~" { yylval = NOTMATCH; RETURN(MATCHOP); }
68: "<" { yylval = LT; RETURN(RELOP); }
69: "<=" { yylval = LE; RETURN(RELOP); }
70: "==" { yylval = EQ; RETURN(RELOP); }
71: ">=" { yylval = GE; RETURN(RELOP); }
72: ">" { yylval = GT; RETURN(RELOP); }
73: ">>" { yylval = APPEND; RETURN(RELOP); }
74: "++" { yylval = INCR; RETURN(INCR); }
75: "--" { yylval = DECR; RETURN(DECR); }
76: "+=" { yylval = ADDEQ; RETURN(ASGNOP); }
77: "-=" { yylval = SUBEQ; RETURN(ASGNOP); }
78: "*=" { yylval = MULTEQ; RETURN(ASGNOP); }
79: "/=" { yylval = DIVEQ; RETURN(ASGNOP); }
80: "%=" { yylval = MODEQ; RETURN(ASGNOP); }
81: "=" { yylval = ASSIGN; RETURN(ASGNOP); }
82:
83: "$"{D}+ { if (atoi(yytext+1)==0) {
84: yylval = (hack)lookup("$record", symtab, 0);
85: RETURN(STRING);
86: } else {
87: yylval = fieldadr(atoi(yytext+1));
88: RETURN(FIELD);
89: }
90: }
91: "$"{WS}* { RETURN(INDIRECT); }
92: NF { mustfld=1; yylval = (hack)setsymtab(yytext, EMPTY, 0.0, NUM, symtab); RETURN(VAR); }
93: ({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)? {
94: yylval = (hack)setsymtab(yytext, EMPTY, atof(yytext), CON|NUM, symtab); RETURN(NUMBER); }
95: "}"{WS}*\n { sc_flag = 1; lineno++; RETURN(';'); }
96: "}" { sc_flag = 1; RETURN(';'); }
97: ;\n { lineno++; RETURN(';'); }
98: \n { lineno++; RETURN(NL); }
99: while RETURN(WHILE);
100: for RETURN(FOR);
101: if RETURN(IF);
102: else RETURN(ELSE);
103: next RETURN(NEXT);
104: exit RETURN(EXIT);
105: break RETURN(BREAK);
106: continue RETURN(CONTINUE);
107: print { yylval = PRINT; RETURN(PRINT); }
108: printf { yylval = PRINTF; RETURN(PRINTF); }
109: sprintf { yylval = SPRINTF; RETURN(SPRINTF); }
110: split { yylval = SPLIT; RETURN(SPLIT); }
111: substr RETURN(SUBSTR);
112: index RETURN(INDEX);
113: in RETURN(IN);
114: getline RETURN(GETLINE);
115: length { yylval = FLENGTH; RETURN(FNCN); }
116: log { yylval = FLOG; RETURN(FNCN); }
117: int { yylval = FINT; RETURN(FNCN); }
118: exp { yylval = FEXP; RETURN(FNCN); }
119: sqrt { yylval = FSQRT; RETURN(FNCN); }
120: {A}{B}* { yylval = (hack)setsymtab(yytext, tostring(""), 0.0, STR|NUM, symtab); RETURN(VAR); }
121: \" { BEGIN str; clen=0; }
122:
123: # { BEGIN comment; }
124: <comment>\n { BEGIN INITIAL; lineno++; RETURN(NL); }
125: <comment>. ;
126:
127: . { yylval = yytext[0]; RETURN(yytext[0]); }
128:
129: <reg>"[" { BEGIN chc; clen=0; cflag=0; }
130: <reg>"[^" { BEGIN chc; clen=0; cflag=1; }
131:
132: <reg>"?" RETURN(QUEST);
133: <reg>"+" RETURN(PLUS);
134: <reg>"*" RETURN(STAR);
135: <reg>"|" RETURN(OR);
136: <reg>"." RETURN(DOT);
137: <reg>"(" RETURN('(');
138: <reg>")" RETURN(')');
139: <reg>"^" RETURN('^');
140: <reg>"$" RETURN('$');
141: <reg>\\{D}{D}{D} { sscanf(yytext+1, "%o", &yylval); RETURN(CHAR); }
142: <reg>\\. { if (yytext[1]=='n') yylval = '\n';
143: else if (yytext[1] == 't') yylval = '\t';
144: else yylval = yytext[1];
145: RETURN(CHAR);
146: }
147: <reg>"/" { BEGIN INITIAL; unput('/'); }
148: <reg>\n { yyerror("newline in regular expression"); lineno++; BEGIN INITIAL; }
149: <reg>. { yylval = yytext[0]; RETURN(CHAR); }
150:
151: <str>\" { char *s; BEGIN INITIAL; cbuf[clen]=0; s = tostring(cbuf);
152: cbuf[clen] = ' '; cbuf[++clen] = 0;
153: yylval = (hack)setsymtab(cbuf, s, 0.0, CON|STR, symtab); RETURN(STRING); }
154: <str>\n { yyerror("newline in string"); lineno++; BEGIN INITIAL; }
155: <str>"\\\"" { cbuf[clen++]='"'; }
156: <str,chc>"\\"n { cbuf[clen++]='\n'; }
157: <str,chc>"\\"t { cbuf[clen++]='\t'; }
158: <str,chc>"\\\\" { cbuf[clen++]='\\'; }
159: <str>. { CADD; }
160:
161: <chc>"\\""]" { cbuf[clen++]=']'; }
162: <chc>"]" { BEGIN reg; cbuf[clen]=0; yylval = (hack)tostring(cbuf);
163: if (cflag==0) { RETURN(CCL); }
164: else { RETURN(NCCL); } }
165: <chc>\n { yyerror("newline in character class"); lineno++; BEGIN INITIAL; }
166: <chc>. { CADD; }
167:
168: %%
169:
170: startreg()
171: {
172: BEGIN reg;
173: }
174:
175: ptoken(n)
176: {
177: extern struct tok {
178: char *tnm;
179: int yval;
180: } tok[];
181: extern int yylval;
182:
183: printf("lex:");
184: if (n < 128) {
185: printf(" %c\n",n);
186: return;
187: }
188: if (n <= 256 || n >= LASTTOKEN) {
189: printf("? %o\n",n);
190: return;
191: }
192: printf(" %s",tok[n-257].tnm);
193: switch (n) {
194:
195: case RELOP:
196: case MATCHOP:
197: case ASGNOP:
198: case STRING:
199: case FIELD:
200: case VAR:
201: case NUMBER:
202: case FNCN:
203: printf(" (%s)", yytext);
204: break;
205:
206: case CHAR:
207: printf(" (%o)", yylval);
208: break;
209: }
210: putchar('\n');
211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.