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:
M | lex.c | | | 47 | +++++++++++++++++++++++++++++++---------------- |
M | tokens.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