scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit aea5de4f99d00f5ca4c7f7503be3208f9666e623
parent 80244a46e09e3ce670be5c94ecc836659bff404c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 12 Jun 2012 21:06:16 +0200

Add ahead function

This function is needed in order to can look ahead one token without lose
the actual one.

Diffstat:
Mlex.c | 47+++++++++++++++++++++++++++++++----------------
Mtokens.h | 3++-
2 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/lex.c b/lex.c @@ -12,6 +12,7 @@ static FILE *yyin; union yyval yyval; +static unsigned char aheadtok = NOTOK; unsigned char yytoken; unsigned char yyhash; char yytext[TOKSIZ_MAX + 1]; @@ -132,32 +133,46 @@ void next(void) { register unsigned char c; - if (!skip()) { - c = EOFTOK; + if (aheadtok != NOTOK) { + yytoken = aheadtok; + aheadtok = NOTOK; + } else if (!skip()) { + yytoken = EOFTOK; } else if (isalpha(c = getc(yyin)) || c == '_') { ungetc(c, yyin); - c = iden(); + yytoken = iden(); } else if (isdigit(c)) { ungetc(c, yyin); - c = number(); + yytoken = number(); } else { switch (c) { - case '=': c = follow('=', EQ, 0); break; - case '^': c = follow('^', XOR_EQ, 0); break; - case '*': c = follow('*', MUL_EQ, 0); break; - case '!': c = follow('!', NE, 0); break; - case '+': c = follow('+', ADD_EQ, INC); break; - case '&': c = follow('&', AND_EQ, AND); break; - case '|': c = follow('|', OR_EQ, OR); break; - case '<': c = rel_shift('<'); break; - case '>': c = rel_shift('>'); break; - case '-': c = minus(); break; + case '=': yytoken = follow('=', EQ, 0); break; + case '^': yytoken = follow('^', XOR_EQ, 0); break; + case '*': yytoken = follow('*', MUL_EQ, 0); break; + case '!': yytoken = follow('!', NE, 0); break; + case '+': yytoken = follow('+', ADD_EQ, INC); break; + case '&': yytoken = follow('&', AND_EQ, AND); break; + case '|': yytoken = follow('|', OR_EQ, OR); break; + case '<': yytoken = rel_shift('<'); break; + case '>': yytoken = rel_shift('>'); break; + case '-': yytoken = minus(); break; + default: yytoken = c; } } - return yytoken = c; } -char accept(unsigned char tok) +unsigned char ahead(void) +{ + static unsigned char oldtok; + + oldtok = yytoken; + next(); + aheadtok = yytoken; + yytoken = oldtok; + return aheadtok; +} + +char accept(register unsigned char tok) { if (yytoken == tok) { next(); diff --git a/tokens.h b/tokens.h @@ -29,7 +29,7 @@ enum { XOR_EQ, OR_EQ, LSHIFT_EQ, RSHIFT_EQ, TYPE_NAME, ELLIPSIS, CASE, DEFAULT, IF, ELSE, SWITCH, WHILE, DO, FOR, GOTO, - CONTINUE, BREAK, RETURN, EOFTOK + CONTINUE, BREAK, RETURN, EOFTOK, NOTOK }; @@ -52,4 +52,5 @@ extern void next(void); extern char accept(unsigned char tok); extern void expect(unsigned char tok); extern void init_keywords(void); +extern unsigned char ahead(void); #endif