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