scc

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

commit cffac6768dcdad6bf8fadf8686b89c389a60dc22
parent 943fc19936e423b3c349ceea154e4eb6465cc556
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  5 Jun 2012 23:03:08 +0200

Fixed tokens of multi character operators

The processing of this tokens was incorrect and diferent operators were
mapped to the same token, so the parser was unable of doing a correct work.

Diffstat:
Mdecl.c | 2+-
Mexpr.c | 2+-
Mlex.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mtokens.h | 5+++--
4 files changed, 73 insertions(+), 26 deletions(-)

diff --git a/decl.c b/decl.c @@ -43,7 +43,7 @@ static void dirdcl(void) /* TODO: specify size of array */; continue; } else { - printf("leaving dirdcl %c\n", yytoken); + puts("leaving dirdcl"); return; } } diff --git a/expr.c b/expr.c @@ -125,7 +125,7 @@ static void shift(void) puts("shift"); do add(); - while (accept(LEFT_OP) || accept(RIGHT_OP)); + while (accept(LSHIFT_OP) || accept(RSHIFT_OP)); puts("leaving shift"); } diff --git a/lex.c b/lex.c @@ -104,8 +104,8 @@ static char *toknames[] = { [PTR_OP] = "PTR_OP", [INC_OP] = "INC_OP", [DEC_OP] = "DEC_OP", - [LEFT_OP] = "LEFT_OP", - [RIGHT_OP] = "RIGHT_OP", + [LSHIFT_OP] = "LEFT_OP", + [RSHIFT_OP] = "RIGHT_OP", [LE_OP] = "LE_OP", [GE_OP] = "GE_OP", [EQ_OP] = "EQ_OP", @@ -227,30 +227,76 @@ unsigned char next(void) ungetc(ch, yyin); ch = number(); } else { + register unsigned char aux;; + aux = getc(yyin); + yytext[0] = ch; + yytext[1] = aux; + yytext[2] = '\0'; + switch (ch) { - case '&': case '|': - if ((c = getc(yyin)) == ch) { - yytext[1] = yytext[0] = ch; - yytext[2] = '\0'; - ch |= 0x80; /* TODO */ - break; - } else { - ungetc(c, yyin); + case '&': + switch (aux) { + case '&': ch = AND_OP; break; + case '=': ch = AND_ASSIGN; break; + default: goto no_doble_character; + } + break; + case '|': + switch (aux) { + case '|': ch = OR_OP; break; + case '=': ch = OR_ASSIGN; break; + default: goto no_doble_character; + } + break; + case '<': + switch (aux) { + case '<': ch = LSHIFT_OP; break; + case '=': ch = LSHIFT_ASSIGN; break; + default: goto no_doble_character; + } + break; + case '>': + switch (aux) { + case '<': ch = RSHIFT_OP; break; + case '=': ch = RSHIFT_ASSIGN; break; + default: goto no_doble_character; } - case '^': case '=': case '<': case '>': - case '*': case '+': case '-': case '/': - if ((c = getc(yyin)) == '=') { - yytext[0] = ch; - yytext[1] = c; - yytext[2] = '\0'; - ch |= 0x80; /* TODO */ + break; + case '-': + switch (aux) { + case '-': ch = DEC_OP; break; + case '>': ch = PTR_OP; break; + case '=': ch = ADD_ASSIGN; break; + default: goto no_doble_character; + } + break; + case '=': + if (aux == '=') ch = EQ_OP; + else goto no_doble_character; + break; + case '^': + if (aux == '=') ch = XOR_ASSIGN; + else goto no_doble_character; + break; + case '*': + if (aux == '=') ch = LSHIFT_ASSIGN; + else goto no_doble_character; + break; + case '+': + if (aux == '+') ch = INC_OP; + else if (aux == '=') ch = ADD_ASSIGN; + else goto no_doble_character; + break; + case '!': + if (aux == '=') { + ch = EQ_OP; break; - } else { - ungetc(c, yyin); } - case ';': case '{': case '}': case '(': case ')': case '~': - case '!': case ',': case '?': case '[': case ']': case ':': - yytext[0] = ch; + no_doble_character: + case '/': case ';': case '{': case '}': + case '(': case ')': case '~': case ',': + case '?': case '[': case ']': case ':': + ungetc(aux, yyin); yytext[1] = '\0'; break; default: diff --git a/tokens.h b/tokens.h @@ -22,8 +22,9 @@ enum { enum { - IDENTIFIER = 128, CONSTANT, STRING_LITERAL, SIZEOF, - PTR_OP, INC_OP, DEC_OP, LEFT_OP, RIGHT_OP, LE_OP, GE_OP, EQ_OP, NE_OP, + IDENTIFIER = 128, CONSTANT, STRING_LITERAL, SIZEOF, + PTR_OP, INC_OP, DEC_OP, LSHIFT_OP, RSHIFT_OP, + LE_OP, GE_OP, EQ_OP, NE_OP, AND_OP, OR_OP, MUL_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, ADD_ASSIGN, SUB_ASSIGN, LSHIFT_ASSIGN, RSHIFT_ASSIGN, AND_ASSIGN, XOR_ASSIGN, OR_ASSIGN, TYPE_NAME,