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