Annotation of researchv10no/cmd/awk/awk.lx.l, revision 1.1.1.1

1.1       root        1: %Start A str sc reg comment
                      2: 
                      3: %{
                      4: /*
                      5: Copyright (c) 1989 AT&T
                      6:        All Rights Reserved
                      7: 
                      8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.
                      9: 
                     10: The copyright notice above does not evidence any
                     11: actual or intended publication of such source code.
                     12: */
                     13: 
                     14: #undef input   /* defeat lex */
                     15: #undef unput
                     16: 
                     17: #include <stdlib.h>
                     18: #include <string.h>
                     19: #include "awk.h"
                     20: #include "y.tab.h"
                     21: 
                     22: extern YYSTYPE yylval;
                     23: extern int     infunc;
                     24: 
                     25: int    lineno  = 1;
                     26: int    bracecnt = 0;
                     27: int    brackcnt  = 0;
                     28: int    parencnt = 0;
                     29: #define DEBUG
                     30: #ifdef DEBUG
                     31: #      define  RET(x)  {if(dbg)printf("lex %s [%s]\n", tokname(x), yytext); return(x); }
                     32: #else
                     33: #      define  RET(x)  return(x)
                     34: #endif
                     35: 
                     36: #define        CADD    cbuf[clen++] = yytext[0]; \
                     37:                if (clen >= CBUFLEN-1) { \
                     38:                        ERROR "string/reg expr %.10s... too long", cbuf SYNTAX; \
                     39:                        BEGIN A; \
                     40:                }
                     41: 
                     42: uchar  cbuf[CBUFLEN];
                     43: uchar  *s;
                     44: int    clen, cflag;
                     45: %}
                     46: 
                     47: A      [a-zA-Z_]
                     48: B      [a-zA-Z0-9_]
                     49: D      [0-9]
                     50: O      [0-7]
                     51: H      [0-9a-fA-F]
                     52: WS     [ \t]
                     53: 
                     54: %%
                     55:        switch (yybgin-yysvec-1) {      /* witchcraft */
                     56:        case 0:
                     57:                BEGIN A;
                     58:                break;
                     59:        case sc:
                     60:                BEGIN A;
                     61:                RET('}');
                     62:        }
                     63: 
                     64: <A>\n          { lineno++; RET(NL); }
                     65: <A>#.*         { ; }   /* strip comments */
                     66: <A>{WS}+       { ; }
                     67: <A>;           { RET(';'); }
                     68: 
                     69: <A>"\\"\n      { lineno++; }
                     70: <A>BEGIN       { RET(XBEGIN); }
                     71: <A>END         { RET(XEND); }
                     72: <A>func(tion)? { if (infunc) ERROR "illegal nested function" SYNTAX; RET(FUNC); }
                     73: <A>return      { if (!infunc) ERROR "return not in function" SYNTAX; RET(RETURN); }
                     74: <A>"&&"                { RET(AND); }
                     75: <A>"||"                { RET(BOR); }
                     76: <A>"!"         { RET(NOT); }
                     77: <A>"!="                { yylval.i = NE; RET(NE); }
                     78: <A>"~"         { yylval.i = MATCH; RET(MATCHOP); }
                     79: <A>"!~"                { yylval.i = NOTMATCH; RET(MATCHOP); }
                     80: <A>"<"         { yylval.i = LT; RET(LT); }
                     81: <A>"<="                { yylval.i = LE; RET(LE); }
                     82: <A>"=="                { yylval.i = EQ; RET(EQ); }
                     83: <A>">="                { yylval.i = GE; RET(GE); }
                     84: <A>">"         { yylval.i = GT; RET(GT); }
                     85: <A>">>"                { yylval.i = APPEND; RET(APPEND); }
                     86: <A>"++"                { yylval.i = INCR; RET(INCR); }
                     87: <A>"--"                { yylval.i = DECR; RET(DECR); }
                     88: <A>"+="                { yylval.i = ADDEQ; RET(ASGNOP); }
                     89: <A>"-="                { yylval.i = SUBEQ; RET(ASGNOP); }
                     90: <A>"*="                { yylval.i = MULTEQ; RET(ASGNOP); }
                     91: <A>"/="                { yylval.i = DIVEQ; RET(ASGNOP); }
                     92: <A>"%="                { yylval.i = MODEQ; RET(ASGNOP); }
                     93: <A>"^="                { yylval.i = POWEQ; RET(ASGNOP); }
                     94: <A>"**="       { yylval.i = POWEQ; RET(ASGNOP); }
                     95: <A>"="         { yylval.i = ASSIGN; RET(ASGNOP); }
                     96: <A>"**"                { RET(POWER); }
                     97: <A>"^"         { RET(POWER); }
                     98: 
                     99: <A>"$"{D}+     { yylval.cp = fieldadr(atoi(yytext+1)); RET(FIELD); }
                    100: <A>"$NF"       { unputstr("(NF)"); return(INDIRECT); }
                    101: <A>"$"{A}{B}*  { int c, n;
                    102:                  c = input(); unput(c);
                    103:                  if (c == '(' || c == '[' || infunc && (n=isarg(yytext+1)) >= 0) {
                    104:                        unputstr(yytext+1);
                    105:                        return(INDIRECT);
                    106:                  } else {
                    107:                        yylval.cp = setsymtab(yytext+1,"",0.0,STR|NUM,symtab);
                    108:                        RET(IVAR);
                    109:                  }
                    110:                }
                    111: <A>"$"         { RET(INDIRECT); }
                    112: <A>NF          { yylval.cp = setsymtab(yytext, "", 0.0, NUM, symtab); RET(VARNF); }
                    113: 
                    114: <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?        {
                    115:                  yylval.cp = setsymtab(yytext, tostring(yytext), atof(yytext), CON|NUM, symtab);
                    116:                /* should this also have STR set? */
                    117:                  RET(NUMBER); }
                    118: 
                    119: <A>while       { RET(WHILE); }
                    120: <A>for         { RET(FOR); }
                    121: <A>do          { RET(DO); }
                    122: <A>if          { RET(IF); }
                    123: <A>else                { RET(ELSE); }
                    124: <A>next                { RET(NEXT); }
                    125: <A>exit                { RET(EXIT); }
                    126: <A>break       { RET(BREAK); }
                    127: <A>continue    { RET(CONTINUE); }
                    128: <A>print       { yylval.i = PRINT; RET(PRINT); }
                    129: <A>printf      { yylval.i = PRINTF; RET(PRINTF); }
                    130: <A>sprintf     { yylval.i = SPRINTF; RET(SPRINTF); }
                    131: <A>split       { yylval.i = SPLIT; RET(SPLIT); }
                    132: <A>substr      { RET(SUBSTR); }
                    133: <A>sub         { yylval.i = SUB; RET(SUB); }
                    134: <A>gsub                { yylval.i = GSUB; RET(GSUB); }
                    135: <A>index       { RET(INDEX); }
                    136: <A>match       { RET(MATCHFCN); }
                    137: <A>in          { RET(IN); }
                    138: <A>getline     { RET(GETLINE); }
                    139: <A>close       { RET(CLOSE); }
                    140: <A>delete      { RET(DELETE); }
                    141: <A>length      { yylval.i = FLENGTH; RET(BLTIN); }
                    142: <A>log         { yylval.i = FLOG; RET(BLTIN); }
                    143: <A>int         { yylval.i = FINT; RET(BLTIN); }
                    144: <A>exp         { yylval.i = FEXP; RET(BLTIN); }
                    145: <A>sqrt                { yylval.i = FSQRT; RET(BLTIN); }
                    146: <A>sin         { yylval.i = FSIN; RET(BLTIN); }
                    147: <A>cos         { yylval.i = FCOS; RET(BLTIN); }
                    148: <A>atan2       { yylval.i = FATAN; RET(BLTIN); }
                    149: <A>system      { yylval.i = FSYSTEM; RET(BLTIN); }
                    150: <A>rand                { yylval.i = FRAND; RET(BLTIN); }
                    151: <A>srand       { yylval.i = FSRAND; RET(BLTIN); }
                    152: <A>toupper     { yylval.i = FTOUPPER; RET(BLTIN); }
                    153: <A>tolower     { yylval.i = FTOLOWER; RET(BLTIN); }
                    154: <A>fflush      { yylval.i = FFLUSH; RET(BLTIN); }
                    155: 
                    156: <A>{A}{B}*     { int n, c;
                    157:                  c = input(); unput(c);        /* look for '(' */
                    158:                  if (c != '(' && infunc && (n=isarg(yytext)) >= 0) {
                    159:                        yylval.i = n;
                    160:                        RET(ARG);
                    161:                  } else {
                    162:                        yylval.cp = setsymtab(yytext,"",0.0,STR|NUM,symtab);
                    163:                        if (c == '(') {
                    164:                                RET(CALL);
                    165:                        } else {
                    166:                                RET(VAR);
                    167:                        }
                    168:                  }
                    169:                }
                    170: <A>\"          { BEGIN str; clen = 0; }
                    171: 
                    172: <A>"}"         { if (--bracecnt < 0) ERROR "extra }" SYNTAX; BEGIN sc; RET(';'); }
                    173: <A>"]"         { if (--brackcnt < 0) ERROR "extra ]" SYNTAX; RET(']'); }
                    174: <A>")"         { if (--parencnt < 0) ERROR "extra )" SYNTAX; RET(')'); }
                    175: 
                    176: <A>.           { if (yytext[0] == '{') bracecnt++;
                    177:                  else if (yytext[0] == '[') brackcnt++;
                    178:                  else if (yytext[0] == '(') parencnt++;
                    179:                  RET(yylval.i = yytext[0]); /* everything else */ }
                    180: 
                    181: <reg>\\.       { cbuf[clen++] = '\\'; cbuf[clen++] = yytext[1]; }
                    182: <reg>\n                { ERROR "newline in regular expression %.10s...", cbuf SYNTAX; lineno++; BEGIN A; }
                    183: <reg>"/"       { BEGIN A;
                    184:                  cbuf[clen] = 0;
                    185:                  yylval.s = tostring(cbuf);
                    186:                  unput('/');
                    187:                  RET(REGEXPR); }
                    188: <reg>.         { CADD; }
                    189: 
                    190: <str>\"                { BEGIN A;
                    191:                  cbuf[clen] = 0; s = tostring(cbuf);
                    192:                  cbuf[clen] = ' '; cbuf[++clen] = 0;
                    193:                  yylval.cp = setsymtab(cbuf, s, 0.0, CON|STR, symtab);
                    194:                  RET(STRING); }
                    195: <str>\n                { ERROR "newline in string %.10s...", cbuf SYNTAX; lineno++; BEGIN A; }
                    196: <str>"\\\""    { cbuf[clen++] = '"'; }
                    197: <str>"\\"n     { cbuf[clen++] = '\n'; }
                    198: <str>"\\"t     { cbuf[clen++] = '\t'; }
                    199: <str>"\\"f     { cbuf[clen++] = '\f'; }
                    200: <str>"\\"r     { cbuf[clen++] = '\r'; }
                    201: <str>"\\"b     { cbuf[clen++] = '\b'; }
                    202: <str>"\\"v     { cbuf[clen++] = '\v'; }        /* these ANSIisms may not be known by */
                    203: <str>"\\"a     { cbuf[clen++] = '\007'; }      /* your compiler. hence 007 for bell */
                    204: <str>"\\\\"    { cbuf[clen++] = '\\'; }
                    205: <str>"\\"({O}{O}{O}|{O}{O}|{O}) { int n;
                    206:                  sscanf(yytext+1, "%o", &n); cbuf[clen++] = n; }
                    207: <str>"\\"x({H}+) { int n;      /* ANSI permits any number! */
                    208:                  sscanf(yytext+2, "%x", &n); cbuf[clen++] = n; }
                    209: <str>"\\".     { cbuf[clen++] = yytext[1]; }
                    210: <str>.         { CADD; }
                    211: 
                    212: %%
                    213: 
                    214: void startreg(void)
                    215: {
                    216:        BEGIN reg;
                    217:        clen = 0;
                    218: }
                    219: 
                    220: /* input() and unput() are transcriptions of the standard lex
                    221:    macros for input and output with additions for error message
                    222:    printing.  God help us all if someone changes how lex works.
                    223: */
                    224: 
                    225: uchar  ebuf[300];
                    226: uchar  *ep = ebuf;
                    227: 
                    228: input(void)
                    229: {
                    230:        register int c;
                    231:        extern uchar *lexprog;
                    232: 
                    233:        if (yysptr > yysbuf)
                    234:                c = U(*--yysptr);
                    235:        else if (lexprog != NULL) {     /* awk '...' */
                    236:                if (c = *lexprog)
                    237:                        lexprog++;
                    238:        } else                          /* awk -f ... */
                    239:                c = pgetc();
                    240:        if (c == '\n')
                    241:                yylineno++;
                    242:        else if (c == EOF)
                    243:                c = 0;
                    244:        if (ep >= ebuf + sizeof ebuf)
                    245:                ep = ebuf;
                    246:        return *ep++ = c;
                    247: }
                    248: 
                    249: void unput(int c)
                    250: {
                    251:        yytchar = c;
                    252:        if (yytchar == '\n')
                    253:                yylineno--;
                    254:        *yysptr++ = yytchar;
                    255:        if (--ep < ebuf)
                    256:                ep = ebuf + sizeof(ebuf) - 1;
                    257: }
                    258: 
                    259: 
                    260: void unputstr(char *s)
                    261: {
                    262:        int i;
                    263: 
                    264:        for (i = strlen(s)-1; i >= 0; i--)
                    265:                unput(s[i]);
                    266: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.