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 } 212