int escchar(char c) { int n; char buf[Strsize]; if(c >= '0' && c <= '9') { n = 1; buf[0] = c; for(;;) { c = lexc(); if(c == Eof) error("%d: <eof> in escape sequence", line); if(strchr("0123456789xX", c) == 0) { unlexc(c); break; } buf[n++] = c; } buf[n] = '\0'; return strtol(buf, 0, 0); } n = cmap[c]; if(n == 0) return c; return n-1; }
void eatnl(void) { int c; line++; for(;;) { c = lexc(); if(c == Eof) error("eof in comment"); if(c == '\n') return; } }
void eatstring(void) { int esc, c, cnt; char buf[Strsize]; esc = 0; for(cnt = 0;;) { c = lexc(); switch(c) { case Eof: error("%d: <eof> in string constant", line); case '\r': case '\n': error("newline in string constant"); goto done; case '\\': if(esc) goto Default; esc = 1; break; case '"': if(esc == 0) goto done; /* Fall through */ default: Default: if(esc) { c = escchar(c); esc = 0; } buf[cnt++] = c; break; } if(cnt >= Strsize) error("string token too long"); } done: buf[cnt] = '\0'; yylval.string = strnode(buf); }
static int lexAlias(FILE *file, char **lexToken) { int c; char *t; enum state { Begin, Normal, Quoted, Comment } state; int count; static char *tokenBuf = (char *) NULL; static int tokenSize = 0; t = tokenBuf; count = 0; state = Begin; for (;;) { if (count == tokenSize) { int nsize; char *nbuf; nsize = tokenSize ? (tokenSize << 1) : 64; nbuf = (char *) xrealloc(tokenBuf, nsize); if (!nbuf) return EALLOC; tokenBuf = nbuf; tokenSize = nsize; t = tokenBuf + count; } c = lexc(file); switch (charClass) { case QUOTE: switch (state) { case Begin: case Normal: state = Quoted; break; case Quoted: state = Normal; break; case Comment: break; } break; case WHITE: switch (state) { case Begin: case Comment: continue; case Normal: *t = '\0'; *lexToken = tokenBuf; return NAME; case Quoted: break; } /* fall through */ case NORMAL: switch (state) { case Begin: state = Normal; break; case Comment: continue; default: break; } *t++ = c; ++count; break; case END: case NL: switch (state) { case Begin: case Comment: *lexToken = (char *) NULL; return charClass == END ? DONE : NEWLINE; default: *t = '\0'; *lexToken = tokenBuf; ungetc(c, file); return NAME; } break; case BANG: switch (state) { case Begin: state = Comment; break; case Comment: break; default: *t++ = c; ++count; } break; } } }
int numsym(char first) { int c, isbin, isfloat, ishex; char *sel, *p; Lsym *s; symbol[0] = first; p = symbol; ishex = 0; isbin = 0; isfloat = 0; if(first == '.') isfloat = 1; if(isdigit(*p++) || isfloat) { for(;;) { c = lexc(); if(c < 0) error("%d: <eof> eating symbols", line); if(c == '\r') continue; if(c == '\n') line++; sel = "01234567890.xb"; if(ishex) sel = "01234567890abcdefABCDEF"; else if(isbin) sel = "01"; else if(isfloat) sel = "01234567890eE-+"; if(strchr(sel, c) == 0) { unlexc(c); break; } if(c == '.') isfloat = 1; if(!isbin && c == 'x') ishex = 1; if(!ishex && c == 'b') isbin = 1; *p++ = c; } *p = '\0'; if(isfloat) { yylval.fval = atof(symbol); return Tfconst; } if(isbin) yylval.ival = strtoul(symbol+2, 0, 2); else yylval.ival = strtoul(symbol, 0, 0); return Tconst; } for(;;) { c = lexc(); if(c < 0) error("%d <eof> eating symbols", line); if(c == '\n') line++; if(c != '_' && c != '$' && c <= '~' && !isalnum(c)) { /* checking against ~ lets UTF names through */ unlexc(c); break; } *p++ = c; } *p = '\0'; s = look(symbol); if(s == 0) s = enter(symbol, Tid); yylval.sym = s; return s->lexval; }
int yylex(void) { int c; extern char vfmt[]; loop: Bflush(bout); c = lexc(); switch(c) { case Eof: if(gotint) { gotint = 0; stacked = 0; Bprint(bout, "\nacid: "); goto loop; } return Eof; case '"': eatstring(); return Tstring; case ' ': case '\r': case '\t': goto loop; case '\n': line++; if(interactive == 0) goto loop; if(stacked) { print("\t"); goto loop; } return ';'; case '.': c = lexc(); unlexc(c); if(isdigit(c)) return numsym('.'); return '.'; case '(': case ')': case '[': case ']': case ';': case ':': case ',': case '~': case '?': case '*': case '@': case '^': case '%': return c; case '{': stacked++; return c; case '}': stacked--; return c; case '\\': c = lexc(); if(strchr(vfmt, c) == 0) { unlexc(c); return '\\'; } yylval.ival = c; return Tfmt; case '!': c = lexc(); if(c == '=') return Tneq; unlexc(c); return '!'; case '+': c = lexc(); if(c == '+') return Tinc; unlexc(c); return '+'; case '/': c = lexc(); if(c == '/') { eatnl(); goto loop; } unlexc(c); return '/'; case '\'': c = lexc(); if(c == '\\') yylval.ival = escchar(lexc()); else yylval.ival = c; c = lexc(); if(c != '\'') { error("missing '"); unlexc(c); } return Tconst; case '&': c = lexc(); if(c == '&') return Tandand; unlexc(c); return '&'; case '=': c = lexc(); if(c == '=') return Teq; unlexc(c); return '='; case '|': c = lexc(); if(c == '|') return Toror; unlexc(c); return '|'; case '<': c = lexc(); if(c == '=') return Tleq; if(c == '<') return Tlsh; unlexc(c); return '<'; case '>': c = lexc(); if(c == '=') return Tgeq; if(c == '>') return Trsh; unlexc(c); return '>'; case '-': c = lexc(); if(c == '>') return Tindir; if(c == '-') return Tdec; unlexc(c); return '-'; default: return numsym(c); } }