Annotation of researchv10no/cmd/pico/lex.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <ctype.h>
                      3: #include "pico.h"
                      4: #include "y.tab.h"
                      5: 
                      6: #define Prompt2                /* if (INPUT == stdin) fprintf(stderr, ":%d ", pline) */
                      7: 
                      8: extern FILE    *INPUT;
                      9: 
                     10: Symbol *whichcmd(), *lookup(), *getname();
                     11: char   *getstring();
                     12: 
                     13: int    linenumber = 1;
                     14: int    pline      =  0;
                     15: int    lexlast    = -1;
                     16: int    LO         = -1;
                     17: char   lastyy     = '\n';
                     18: char   nolf       = 1;
                     19: char   nesting    = 0;
                     20: char   operator   = 0;
                     21: char   lastdepth  = 0;
                     22: 
                     23: /*
                     24:  * if the last token seen was not an operator the next
                     25:  * newline will be interpreted as a statement separator
                     26:  */
                     27: 
                     28: #define ADDEQ  210
                     29: #define SUBEQ  211
                     30: #define MULEQ  212
                     31: #define DIVEQ  213
                     32: #define MODEQ  214
                     33: #define INC    215
                     34: #define DEC    216
                     35: 
                     36: yylex()
                     37: { int c;
                     38:        while ((c = ylexlex()) == SCOM)
                     39:        {       do c = ylexlex();
                     40:                while (c != ECOM);
                     41:        }
                     42:        /* fprintf(stderr, "lex: %d [[%c]]\n", c, (isalnum(c))?c:'-');/*  */
                     43:        switch (c) {
                     44:        case '+':       case '-':       case '*':
                     45:        case '/':       case '%':       case '^':
                     46:        case POW:       case GT:        case GE:
                     47:        case LT:        case LE:        case EQ:
                     48:        case NE:        case ANDAND:    case OROR:
                     49:        case OR:        case AND:       case LSH:
                     50:        case RSH:       case ',':       case NOT:
                     51:        case '~':       case '?':       case ':':
                     52:        case ASSIGN:    case '(':       case '[':
                     53:                operator = 1;
                     54:                break;
                     55:        case ADDEQ:     operator = 1; LO = OADD; return OPER;
                     56:        case SUBEQ:     operator = 1; LO = OSUB; return OPER;
                     57:        case MULEQ:     operator = 1; LO = OMUL; return OPER;
                     58:        case DIVEQ:     operator = 1; LO = DIVV; return OPER;
                     59:        case MODEQ:     operator = 1; LO = MODU; return OPER;
                     60:        case INC:       operator = 0; LO = OADD; return POST;
                     61:        case DEC:       operator = 0; LO = OSUB; return POST;
                     62:        default:
                     63:                operator = 0;
                     64:                break;
                     65:        }
                     66:        return c;
                     67: }
                     68: 
                     69: ylexlex()
                     70: { int c;
                     71: 
                     72: again: switch (c = getc(INPUT)) {
                     73:        case  EOF: undirect(); checkit();
                     74:        case  ' ':
                     75:        case   27:
                     76:        case '\t': goto again;
                     77: 
                     78:        case '\\': if ((c = getc(INPUT)) == '\n')
                     79:                        goto again;
                     80:                   else
                     81:                        break;
                     82:        case '\n': if (nesting > 0 && (operator || lastyy == '\n'))
                     83:                   {    Prompt2;
                     84:                        pline++;
                     85:                        goto again;
                     86:                   }
                     87:        default  : break;
                     88:        }
                     89: 
                     90:        nolf = (c != '\n');
                     91: 
                     92:        if (c == '\"')
                     93:        {       yylval.resu = (int) getstring();
                     94:                lastyy = '\0';
                     95:                return STRING;
                     96:        }
                     97:        if (isdigit(c))
                     98:        {       lexlast = 0;
                     99:                do
                    100:                {       lexlast = lexlast*10 + c - '0';
                    101:                        c = getc(INPUT);
                    102:                } while (isdigit(c));
                    103:                ungetc(c, INPUT);
                    104:                lastyy = '\0';
                    105: 
                    106:                yylval.resu = lexlast;
                    107:                return VAL;
                    108:        }
                    109: 
                    110:        if (isalpha(c) || c == '_')
                    111:        {       yylval.sym = getname(c);
                    112:                lastyy = '\0';
                    113:                return yylval.sym->type;
                    114:        }
                    115: 
                    116:        lastyy = '\0';
                    117:        switch (c) {
                    118:        case '{' : if (++nesting == 1) pline = 1; lastyy = '\n'; return OPEN;
                    119:        case '}' : sympurge();
                    120:                   if (nesting-- == 1) pline = 0;
                    121:                   else ungetc(';', INPUT);
                    122:                   return CLOSE;
                    123:        case '/' : return follow('=', DIVEQ, follow('*', SCOM, '/'));
                    124:        case '%' : return follow('=', MODEQ, '%');
                    125:        case '+' : return follow('+', INC, follow('=', ADDEQ, '+'));
                    126:        case '-' : return follow('-', DEC, follow('=', SUBEQ, '-'));
                    127:        case '*' : return follow('*', POW, follow('=',MULEQ, follow('/',ECOM,'*')));
                    128:        case '>' : return follow('=', GE,  follow('>', RSH, GT));
                    129:        case '<' : return follow('=', LE,  follow('<', LSH, LT));
                    130:        case '=' : return follow('=', EQ, ASSIGN);
                    131:        case '!' : return follow('=', NE, NOT);
                    132:        case '|' : return follow('|', OROR, OR);
                    133:        case '&' : return follow('&', ANDAND, AND);
                    134:        case '\n': if (nesting == 0)
                    135:                        linenumber++;   /* fall through */
                    136:                   else
                    137:                   {    Prompt2;
                    138:                        pline++;
                    139:                   }
                    140:        case ';' : lastyy = '\n';
                    141:                   return ';';
                    142:        default  : return c;
                    143:        }
                    144: }
                    145: 
                    146: follow(expect, ifyes, ifno)
                    147: {
                    148:        int c = getc(INPUT);
                    149: 
                    150:        if (c == expect)
                    151:                return ifyes;
                    152: 
                    153:        ungetc(c, INPUT);
                    154:        return ifno;
                    155: }
                    156: 
                    157: Symbol *
                    158: getname(cc)
                    159:        char cc;
                    160: {      char c=cc, sbuf[128], *p = sbuf;
                    161: 
                    162:        do
                    163:        {       if (p >= sbuf + sizeof(sbuf) - 1)
                    164:                {       *p = '\0';
                    165:                        yyerror("name too long: %s", sbuf);
                    166:                }
                    167:                *p++ = c;
                    168:        } while ((c=getc(INPUT)) != EOF && (isalnum(c) || c == '_'));
                    169:        ungetc(c, INPUT);
                    170:        *p = '\0';
                    171: 
                    172:        if (nesting == 0 && lastyy == '\n')
                    173:                return whichcmd(sbuf);
                    174:        else
                    175:                return lookup(sbuf);
                    176: }
                    177: 
                    178: char *
                    179: getstring()
                    180: {      char c, *sbuf, *p;
                    181:        sbuf = (char *) Emalloc(512);
                    182:        p = sbuf;
                    183: 
                    184:        while ((c=getc(INPUT)) != EOF && c != '\"')
                    185:        {       if (c == '\\')
                    186:                        c = follow('n', '\n', follow('t', '\t', '\\'));
                    187:                *p++ = c;
                    188:                if (p >= sbuf + 512 - 1)
                    189:                {       *p = '\0';
                    190:                        yyerror("string too long: %s", sbuf);
                    191:                }
                    192:        } ;
                    193:        *p = '\0';
                    194: 
                    195:        return sbuf;
                    196: }

unix.superglobalmegacorp.com

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