void eatstring(void) { String *s; int esc, c, cnt; esc = 0; for(cnt = 0;;) { c = Bgetc(bin); switch(c) { case Eof: fatal("%d: <eof> in string constant", line); case '\n': line++; diag("newline in string constant"); goto done; case '\\': if(esc) { if(cnt >= bufmax) resizebuf(); strbuf[cnt++] = c; esc = 0; break; } esc = 1; break; case '"': if(esc == 0) goto done; /* Fall through */ default: if(esc) { c = escchar(c); esc = 0; } if(cnt >= bufmax) resizebuf(); strbuf[cnt++] = c; break; } } done: if(cnt >= bufmax) resizebuf(); strbuf[cnt] = '\0'; s = malloc(sizeof(String)); s->len = cnt+1; s->string = malloc(s->len); memmove(s->string, strbuf, s->len); yylval.string = s; }
int nextc(char quote) { register char c, d; if ((d = readc()) == ESCAPE) { if ((c = readc()) == NL) { chkpr(NL); d = nextc(quote); } else if (quote && c != quote && !escchar(c)) peekc = c | MARK; else d = c | QUOTE; } return d; }
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 void copyto(unsigned char endch, int trimflag) /* trimflag - flag to check if argument will be trimmed */ { unsigned int c; unsigned int d; unsigned char *pc; while ((c = getch(endch, trimflag)) != endch && c) if (quote) { if(c == '\\') { /* don't interpret next character */ if (staktop >= brkend) growstak(staktop); pushstak(c); d = readwc(); if(!escchar(d)) { /* both \ and following character are quoted if next character is not $, `, ", or \*/ if (staktop >= brkend) growstak(staktop); pushstak('\\'); if (staktop >= brkend) growstak(staktop); pushstak('\\'); pc = readw(d); /* push entire multibyte char */ while(*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { pc = readw(d); /* d might be NULL */ /* Evenif d is NULL, we have to save it */ if (*pc) { while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { if (staktop >= brkend) growstak(staktop); pushstak(*pc); } } } else { /* push escapes onto stack to quote characters */ pc = readw(c); if (staktop >= brkend) growstak(staktop); pushstak('\\'); while(*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } } else if(c == '\\') { c = readwc(); /* get character to be escaped */ if (staktop >= brkend) growstak(staktop); pushstak('\\'); pc = readw(c); /* c might be NULL */ /* Evenif c is NULL, we have to save it */ if (*pc) { while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { if (staktop >= brkend) growstak(staktop); pushstak(*pc); } } else { pc = readw(c); while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } if (staktop >= brkend) growstak(staktop); zerostak(); if (c != endch) error(badsub); }
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); } }
int yylex(void) { int c; loop: c = Bgetc(bin); switch(c) { case Eof: return Eof; case '"': eatstring(); return TSTRING; case ' ': case '\t': case '\r': goto loop; case '\n': line++; goto loop; case '.': c = Bgetc(bin); Bungetc(bin); if(isdigit(c)) return numsym('.'); return '.'; case '#': eatnl(); goto loop; case '(': case ')': case ';': case ',': case '~': case '$': case '+': case '/': case '%': case '^': case '*': case '&': case '=': case '|': case '<': case '>': case '-': case ':': return c; case '\'': c = Bgetrune(bin); if(c == '\\') yylval.ival = escchar(Bgetc(bin)); else yylval.ival = c; c = Bgetc(bin); if(c != '\'') { diag("missing '"); Bungetc(bin); } return TCONST; default: return numsym(c); } }