unsigned char Type; /* Token type */
} Keywords [] = {
{ "_Pragma", TOK_PRAGMA, TT_C },
+ { "__AX__", TOK_AX, TT_C },
{ "__A__", TOK_A, TT_C },
- { "__AX__", TOK_AX, TT_C },
- { "__EAX__", TOK_EAX, TT_C },
- { "__X__", TOK_X, TT_C },
- { "__Y__", TOK_Y, TT_C },
- { "__asm__", TOK_ASM, TT_C },
- { "__attribute__", TOK_ATTRIBUTE, TT_C },
- { "__far__", TOK_FAR, TT_C },
- { "__fastcall__", TOK_FASTCALL, TT_C },
+ { "__EAX__", TOK_EAX, TT_C },
+ { "__X__", TOK_X, TT_C },
+ { "__Y__", TOK_Y, TT_C },
+ { "__asm__", TOK_ASM, TT_C },
+ { "__attribute__", TOK_ATTRIBUTE, TT_C },
+ { "__far__", TOK_FAR, TT_C },
+ { "__fastcall__", TOK_FASTCALL, TT_C },
+ { "__near__", TOK_NEAR, TT_C },
{ "asm", TOK_ASM, TT_EXT },
{ "auto", TOK_AUTO, TT_C },
{ "break", TOK_BREAK, TT_C },
{ "if", TOK_IF, TT_C },
{ "int", TOK_INT, TT_C },
{ "long", TOK_LONG, TT_C },
+ { "near", TOK_NEAR, TT_EXT },
{ "register", TOK_REGISTER, TT_C },
{ "restrict", TOK_RESTRICT, TT_C },
{ "return", TOK_RETURN, TT_C },
static int ParseChar (void)
/* Parse a character. Converts \n into EOL, etc. */
{
- int i;
- unsigned val;
+ int I;
+ unsigned Val;
int C;
/* Check for escape chars */
if (CurC == '\\') {
NextChar ();
switch (CurC) {
+ case '?':
+ C = '\?';
+ break;
+ case 'a':
+ C = '\a';
+ break;
case 'b':
C = '\b';
- break;
+ break;
case 'f':
- C = '\f';
- break;
+ C = '\f';
+ break;
case 'r':
- C = '\r';
- break;
+ C = '\r';
+ break;
case 'n':
- C = '\n';
- break;
+ C = '\n';
+ break;
case 't':
- C = '\t';
- break;
+ C = '\t';
+ break;
+ case 'v':
+ C = '\v';
+ break;
case '\"':
- C = '\"';
- break;
+ C = '\"';
+ break;
case '\'':
- C = '\'';
- break;
+ C = '\'';
+ break;
case '\\':
- C = '\\';
- break;
+ C = '\\';
+ break;
case 'x':
case 'X':
- /* Hex character constant */
- NextChar ();
- val = HexVal (CurC) << 4;
- NextChar ();
- C = val | HexVal (CurC); /* Do not translate */
- break;
+ /* Hex character constant */
+ NextChar ();
+ Val = HexVal (CurC) << 4;
+ NextChar ();
+ C = Val | HexVal (CurC); /* Do not translate */
+ break;
case '0':
case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
/* Octal constant */
- i = 0;
- C = CurC - '0';
- while (NextC >= '0' && NextC <= '7' && i++ < 4) {
+ I = 0;
+ Val = CurC - '0';
+ while (NextC >= '0' && NextC <= '7' && ++I <= 3) {
NextChar ();
- C = (C << 3) | (CurC - '0');
+ Val = (Val << 3) | (CurC - '0');
}
+ C = (int) Val;
+ if (Val >= 256) {
+ Error ("Character constant out of range");
+ C = ' ';
+ }
break;
default:
Error ("Illegal character constant");
C = ' ';
+ /* Try to do error recovery, otherwise the compiler will spit
+ * out thousands of errors in this place and abort.
+ */
+ if (CurC != '\'' && CurC != '\0') {
+ while (NextC != '\'' && NextC != '\"' && NextC != '\0') {
+ NextChar ();
+ }
+ }
break;
}
} else {
}
CurTok = NextTok;
+ /* When reading the first time from the file, the line info in NextTok,
+ * which was copied to CurTok is invalid. Since the information from
+ * the token is used for error messages, we must make it valid.
+ */
+ if (CurTok.LI == 0) {
+ CurTok.LI = UseLineInfo (GetCurLineInfo ());
+ }
+
/* Remember the starting position of the next token */
NextTok.LI = UseLineInfo (GetCurLineInfo ());