/*****************************************************************************/
/* */
-/* scanner.c */
+/* scanner.c */
/* */
-/* Source file line info structure */
+/* Source file line info structure */
/* */
/* */
/* */
-/* (C) 1998-2009, Ullrich von Bassewitz */
+/* (C) 1998-2010, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/*****************************************************************************/
-/* data */
+/* data */
/*****************************************************************************/
-Token CurTok; /* The current token */
-Token NextTok; /* The next token */
+Token CurTok; /* The current token */
+Token NextTok; /* The next token */
/* Token table */
static const struct Keyword {
- char* Key; /* Keyword name */
- unsigned char Tok; /* The token */
+ char* Key; /* Keyword name */
+ unsigned char Tok; /* The token */
unsigned char Std; /* Token supported in which standards? */
} Keywords [] = {
{ "_Pragma", TOK_PRAGMA, TT_C89 | TT_C99 | TT_CC65 }, /* !! */
- { "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
- { "__A__", TOK_A, TT_C89 | TT_C99 | TT_CC65 },
- { "__EAX__", TOK_EAX, TT_C89 | TT_C99 | TT_CC65 },
- { "__X__", TOK_X, TT_C89 | TT_C99 | TT_CC65 },
- { "__Y__", TOK_Y, TT_C89 | TT_C99 | TT_CC65 },
- { "__asm__", TOK_ASM, TT_C89 | TT_C99 | TT_CC65 },
- { "__attribute__", TOK_ATTRIBUTE, TT_C89 | TT_C99 | TT_CC65 },
- { "__far__", TOK_FAR, TT_C89 | TT_C99 | TT_CC65 },
- { "__fastcall__", TOK_FASTCALL, TT_C89 | TT_C99 | TT_CC65 },
- { "__inline__", TOK_INLINE, TT_C89 | TT_C99 | TT_CC65 },
- { "__near__", TOK_NEAR, TT_C89 | TT_C99 | TT_CC65 },
- { "asm", TOK_ASM, TT_CC65 },
- { "auto", TOK_AUTO, TT_C89 | TT_C99 | TT_CC65 },
- { "break", TOK_BREAK, TT_C89 | TT_C99 | TT_CC65 },
- { "case", TOK_CASE, TT_C89 | TT_C99 | TT_CC65 },
- { "char", TOK_CHAR, TT_C89 | TT_C99 | TT_CC65 },
- { "const", TOK_CONST, TT_C89 | TT_C99 | TT_CC65 },
- { "continue", TOK_CONTINUE, TT_C89 | TT_C99 | TT_CC65 },
- { "default", TOK_DEFAULT, TT_C89 | TT_C99 | TT_CC65 },
- { "do", TOK_DO, TT_C89 | TT_C99 | TT_CC65 },
- { "double", TOK_DOUBLE, TT_C89 | TT_C99 | TT_CC65 },
- { "else", TOK_ELSE, TT_C89 | TT_C99 | TT_CC65 },
- { "enum", TOK_ENUM, TT_C89 | TT_C99 | TT_CC65 },
- { "extern", TOK_EXTERN, TT_C89 | TT_C99 | TT_CC65 },
- { "far", TOK_FAR, TT_CC65 },
- { "fastcall", TOK_FASTCALL, TT_CC65 },
- { "float", TOK_FLOAT, TT_C89 | TT_C99 | TT_CC65 },
- { "for", TOK_FOR, TT_C89 | TT_C99 | TT_CC65 },
- { "goto", TOK_GOTO, TT_C89 | TT_C99 | TT_CC65 },
- { "if", TOK_IF, TT_C89 | TT_C99 | TT_CC65 },
+ { "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
+ { "__A__", TOK_A, TT_C89 | TT_C99 | TT_CC65 },
+ { "__EAX__", TOK_EAX, TT_C89 | TT_C99 | TT_CC65 },
+ { "__X__", TOK_X, TT_C89 | TT_C99 | TT_CC65 },
+ { "__Y__", TOK_Y, TT_C89 | TT_C99 | TT_CC65 },
+ { "__asm__", TOK_ASM, TT_C89 | TT_C99 | TT_CC65 },
+ { "__attribute__", TOK_ATTRIBUTE, TT_C89 | TT_C99 | TT_CC65 },
+ { "__cdecl__", TOK_CDECL, TT_C89 | TT_C99 | TT_CC65 },
+ { "__far__", TOK_FAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "__fastcall__", TOK_FASTCALL, TT_C89 | TT_C99 | TT_CC65 },
+ { "__inline__", TOK_INLINE, TT_C89 | TT_C99 | TT_CC65 },
+ { "__near__", TOK_NEAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "asm", TOK_ASM, TT_CC65 },
+ { "auto", TOK_AUTO, TT_C89 | TT_C99 | TT_CC65 },
+ { "break", TOK_BREAK, TT_C89 | TT_C99 | TT_CC65 },
+ { "case", TOK_CASE, TT_C89 | TT_C99 | TT_CC65 },
+ { "cdecl", TOK_CDECL, TT_CC65 },
+ { "char", TOK_CHAR, TT_C89 | TT_C99 | TT_CC65 },
+ { "const", TOK_CONST, TT_C89 | TT_C99 | TT_CC65 },
+ { "continue", TOK_CONTINUE, TT_C89 | TT_C99 | TT_CC65 },
+ { "default", TOK_DEFAULT, TT_C89 | TT_C99 | TT_CC65 },
+ { "do", TOK_DO, TT_C89 | TT_C99 | TT_CC65 },
+ { "double", TOK_DOUBLE, TT_C89 | TT_C99 | TT_CC65 },
+ { "else", TOK_ELSE, TT_C89 | TT_C99 | TT_CC65 },
+ { "enum", TOK_ENUM, TT_C89 | TT_C99 | TT_CC65 },
+ { "extern", TOK_EXTERN, TT_C89 | TT_C99 | TT_CC65 },
+ { "far", TOK_FAR, TT_CC65 },
+ { "fastcall", TOK_FASTCALL, TT_CC65 },
+ { "float", TOK_FLOAT, TT_C89 | TT_C99 | TT_CC65 },
+ { "for", TOK_FOR, TT_C89 | TT_C99 | TT_CC65 },
+ { "goto", TOK_GOTO, TT_C89 | TT_C99 | TT_CC65 },
+ { "if", TOK_IF, TT_C89 | TT_C99 | TT_CC65 },
{ "inline", TOK_INLINE, TT_C99 | TT_CC65 },
- { "int", TOK_INT, TT_C89 | TT_C99 | TT_CC65 },
- { "long", TOK_LONG, TT_C89 | TT_C99 | TT_CC65 },
- { "near", TOK_NEAR, TT_CC65 },
- { "register", TOK_REGISTER, TT_C89 | TT_C99 | TT_CC65 },
- { "restrict", TOK_RESTRICT, TT_C99 | TT_CC65 },
- { "return", TOK_RETURN, TT_C89 | TT_C99 | TT_CC65 },
- { "short", TOK_SHORT, TT_C89 | TT_C99 | TT_CC65 },
- { "signed", TOK_SIGNED, TT_C89 | TT_C99 | TT_CC65 },
- { "sizeof", TOK_SIZEOF, TT_C89 | TT_C99 | TT_CC65 },
- { "static", TOK_STATIC, TT_C89 | TT_C99 | TT_CC65 },
- { "struct", TOK_STRUCT, TT_C89 | TT_C99 | TT_CC65 },
- { "switch", TOK_SWITCH, TT_C89 | TT_C99 | TT_CC65 },
- { "typedef", TOK_TYPEDEF, TT_C89 | TT_C99 | TT_CC65 },
- { "union", TOK_UNION, TT_C89 | TT_C99 | TT_CC65 },
- { "unsigned", TOK_UNSIGNED, TT_C89 | TT_C99 | TT_CC65 },
- { "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 },
- { "volatile", TOK_VOLATILE, TT_C89 | TT_C99 | TT_CC65 },
- { "while", TOK_WHILE, TT_C89 | TT_C99 | TT_CC65 },
+ { "int", TOK_INT, TT_C89 | TT_C99 | TT_CC65 },
+ { "long", TOK_LONG, TT_C89 | TT_C99 | TT_CC65 },
+ { "near", TOK_NEAR, TT_CC65 },
+ { "register", TOK_REGISTER, TT_C89 | TT_C99 | TT_CC65 },
+ { "restrict", TOK_RESTRICT, TT_C99 | TT_CC65 },
+ { "return", TOK_RETURN, TT_C89 | TT_C99 | TT_CC65 },
+ { "short", TOK_SHORT, TT_C89 | TT_C99 | TT_CC65 },
+ { "signed", TOK_SIGNED, TT_C89 | TT_C99 | TT_CC65 },
+ { "sizeof", TOK_SIZEOF, TT_C89 | TT_C99 | TT_CC65 },
+ { "static", TOK_STATIC, TT_C89 | TT_C99 | TT_CC65 },
+ { "struct", TOK_STRUCT, TT_C89 | TT_C99 | TT_CC65 },
+ { "switch", TOK_SWITCH, TT_C89 | TT_C99 | TT_CC65 },
+ { "typedef", TOK_TYPEDEF, TT_C89 | TT_C99 | TT_CC65 },
+ { "union", TOK_UNION, TT_C89 | TT_C99 | TT_CC65 },
+ { "unsigned", TOK_UNSIGNED, TT_C89 | TT_C99 | TT_CC65 },
+ { "void", TOK_VOID, TT_C89 | TT_C99 | TT_CC65 },
+ { "volatile", TOK_VOLATILE, TT_C89 | TT_C99 | TT_CC65 },
+ { "while", TOK_WHILE, TT_C89 | TT_C99 | TT_CC65 },
};
-#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
+#define KEY_COUNT (sizeof (Keywords) / sizeof (Keywords [0]))
/* Stuff for determining the type of an integer constant */
-#define IT_INT 0x01
-#define IT_UINT 0x02
-#define IT_LONG 0x04
-#define IT_ULONG 0x08
+#define IT_INT 0x01
+#define IT_UINT 0x02
+#define IT_LONG 0x04
+#define IT_ULONG 0x08
/*****************************************************************************/
-/* code */
+/* code */
/*****************************************************************************/
static token_t FindKey (const char* Key)
/* Find a keyword and return the token. Return IDENT if the token is not a
- * keyword.
- */
+** keyword.
+*/
{
struct Keyword* K;
K = bsearch (Key, Keywords, KEY_COUNT, sizeof (Keywords [0]), CmpKey);
if (K && (K->Std & (0x01 << IS_Get (&Standard))) != 0) {
- return K->Tok;
+ return K->Tok;
} else {
- return TOK_IDENT;
+ return TOK_IDENT;
}
}
static int SkipWhite (void)
/* Skip white space in the input stream, reading and preprocessing new lines
- * if necessary. Return 0 if end of file is reached, return 1 otherwise.
- */
+** if necessary. Return 0 if end of file is reached, return 1 otherwise.
+*/
{
while (1) {
- while (CurC == '\0') {
- if (NextLine () == 0) {
- return 0;
- }
- Preprocess ();
- }
- if (IsSpace (CurC)) {
- NextChar ();
- } else {
- return 1;
- }
+ while (CurC == '\0') {
+ if (NextLine () == 0) {
+ return 0;
+ }
+ Preprocess ();
+ }
+ if (IsSpace (CurC)) {
+ NextChar ();
+ } else {
+ return 1;
+ }
}
}
int TokIsFuncSpec (const Token* T)
/* Return true if the token is a function specifier */
{
- return (T->Tok == TOK_INLINE) || (T->Tok == TOK_FASTCALL) ||
- (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR);
+ return (T->Tok == TOK_INLINE) ||
+ (T->Tok == TOK_FASTCALL) || (T->Tok == TOK_CDECL) ||
+ (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR);
}
void SymName (char* S)
/* Read a symbol from the input stream. The first character must have been
- * checked before calling this function. The buffer is expected to be at
- * least of size MAX_IDENTLEN+1.
- */
+** checked before calling this function. The buffer is expected to be at
+** least of size MAX_IDENTLEN+1.
+*/
{
unsigned Len = 0;
do {
- if (Len < MAX_IDENTLEN) {
- ++Len;
- *S++ = CurC;
- }
- NextChar ();
+ if (Len < MAX_IDENTLEN) {
+ ++Len;
+ *S++ = CurC;
+ }
+ NextChar ();
} while (IsIdent (CurC) || IsDigit (CurC));
*S = '\0';
}
/* If a symbol follows, read it and return 1, otherwise return 0 */
{
if (IsIdent (CurC)) {
- SymName (S);
- return 1;
+ SymName (S);
+ return 1;
} else {
- return 0;
+ return 0;
}
}
/* Error message for unknown character */
{
Error ("Invalid input character with code %02X", C & 0xFF);
- NextChar (); /* Skip */
+ NextChar (); /* Skip */
}
{
int C;
int HadError;
+ int Count;
/* Check for escape chars */
if (CurC == '\\') {
- NextChar ();
- switch (CurC) {
- case '?':
- C = '\?';
- break;
- case 'a':
- C = '\a';
- break;
- case 'b':
- C = '\b';
- break;
- case 'f':
- C = '\f';
- break;
- case 'r':
- C = '\r';
- break;
- case 'n':
- C = '\n';
- break;
- case 't':
- C = '\t';
- break;
+ NextChar ();
+ switch (CurC) {
+ case '?':
+ C = '\?';
+ break;
+ case 'a':
+ C = '\a';
+ break;
+ case 'b':
+ C = '\b';
+ break;
+ case 'f':
+ C = '\f';
+ break;
+ case 'r':
+ C = '\r';
+ break;
+ case 'n':
+ C = '\n';
+ break;
+ case 't':
+ C = '\t';
+ break;
case 'v':
C = '\v';
break;
- case '\"':
- C = '\"';
- break;
- case '\'':
- C = '\'';
- break;
- case '\\':
- C = '\\';
- break;
- case 'x':
- case 'X':
- /* Hex character constant */
+ case '\"':
+ C = '\"';
+ break;
+ case '\'':
+ C = '\'';
+ break;
+ case '\\':
+ C = '\\';
+ break;
+ case 'x':
+ case 'X':
+ /* Hex character constant */
if (!IsXDigit (NextC)) {
Error ("\\x used with no following hex digits");
C = ' ';
NextChar ();
}
}
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- /* Octal constant */
- HadError = 0;
- C = HexVal (CurC);
- while (IsODigit (NextC)) {
- if ((C << 3) >= 256) {
- if (!HadError) {
- Error ("Octal character constant out of range");
- HadError = 1;
- }
- } else {
- C = (C << 3) | HexVal (NextC);
- }
- NextChar ();
- }
- 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;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ /* Octal constant */
+ Count = 1;
+ C = HexVal (CurC);
+ while (IsODigit (NextC) && Count++ < 3) {
+ C = (C << 3) | HexVal (NextC);
+ NextChar ();
}
- break;
- }
+ if (C >= 256)
+ Error ("Octal character constant out of range");
+ break;
+ default:
+ C = CurC;
+ Error ("Illegal escaped character: 0x%02X", CurC);
+ break;
+ }
} else {
- C = CurC;
+ C = CurC;
}
/* Skip the character read */
/* Check for closing quote */
if (CurC != '\'') {
- Error ("`\'' expected");
+ Error ("'\'' expected");
} else {
- /* Skip the quote */
- NextChar ();
+ /* Skip the quote */
+ NextChar ();
}
/* Setup values and attributes */
NextTok.Tok = TOK_SCONST;
/* Concatenate strings. If at least one of the concenated strings is a wide
- * character literal, the whole string is a wide char literal, otherwise
- * it's a normal string literal.
- */
+ ** character literal, the whole string is a wide char literal, otherwise
+ ** it's a normal string literal.
+ */
while (1) {
/* Check if this is a normal or a wide char string */
NextChar ();
} else if (CurC == '\"') {
/* Skip the quote char */
- NextChar ();
+ NextChar ();
} else {
/* No string */
break;
}
/* Read until end of string */
- while (CurC != '\"') {
- if (CurC == '\0') {
- Error ("Unexpected newline");
- break;
- }
- SB_AppendChar (&S, ParseChar ());
- }
+ while (CurC != '\"') {
+ if (CurC == '\0') {
+ Error ("Unexpected newline");
+ break;
+ }
+ SB_AppendChar (&S, ParseChar ());
+ }
- /* Skip closing quote char if there was one */
- NextChar ();
+ /* Skip closing quote char if there was one */
+ NextChar ();
- /* Skip white space, read new input */
- SkipWhite ();
+ /* Skip white space, read new input */
+ SkipWhite ();
}
unsigned long IVal; /* Value */
/* Check for a leading hex or octal prefix and determine the possible
- * integer types.
- */
+ ** integer types.
+ */
if (CurC == '0') {
/* Gobble 0 and examine next char */
NextChar ();
if (toupper (CurC) == 'X') {
Base = Prefix = 16;
- NextChar (); /* gobble "x" */
+ NextChar (); /* gobble "x" */
} else {
Base = 10; /* Assume 10 for now - see below */
Prefix = 8; /* Actual prefix says octal */
}
/* Because floating point numbers don't have octal prefixes (a number
- * with a leading zero is decimal), we first have to read the number
- * before converting it, so we can determine if it's a float or an
- * integer.
- */
+ ** with a leading zero is decimal), we first have to read the number
+ ** before converting it, so we can determine if it's a float or an
+ ** integer.
+ */
while (IsXDigit (CurC) && HexVal (CurC) < Base) {
SB_AppendChar (&S, CurC);
NextChar ();
SB_Terminate (&S);
/* The following character tells us if we have an integer or floating
- * point constant. Note: Hexadecimal floating point constants aren't
- * supported in C89.
- */
+ ** point constant. Note: Hexadecimal floating point constants aren't
+ ** supported in C89.
+ */
IsFloat = (CurC == '.' ||
(Base == 10 && toupper (CurC) == 'E') ||
(Base == 16 && toupper (CurC) == 'P' && IS_Get (&Standard) >= STD_C99));
/* If we don't have a floating point type, an octal prefix results in an
- * octal base.
- */
+ ** octal base.
+ */
if (!IsFloat && Prefix == 8) {
Base = 8;
}
/* Since we do now know the correct base, convert the remembered input
- * into a number.
- */
+ ** into a number.
+ */
SB_Reset (&S);
IVal = 0;
while ((C = SB_Get (&S)) != '\0') {
/* Out of range for int */
Types &= ~IT_INT;
/* If the value is in the range 0x8000..0xFFFF, unsigned int is not
- * allowed, and we don't have a type specifying suffix, emit a
- * warning, because the constant is of type long.
- */
+ ** allowed, and we don't have a type specifying suffix, emit a
+ ** warning, because the constant is of type long.
+ */
if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) {
Warning ("Constant is long");
}
if ((Base == 16 && toupper (CurC) == 'F') ||
(Base == 10 && toupper (CurC) == 'E')) {
- int Sign;
unsigned Digits;
unsigned Exp;
NextChar ();
/* Read an optional sign */
- Sign = 1;
if (CurC == '-') {
- Sign = -1;
NextChar ();
} else if (CurC == '+') {
NextChar ();
}
/* Read exponent digits. Since we support only 32 bit floats
- * with a maximum exponent of +-/127, we read the exponent
- * part as integer with up to 3 digits and drop the remainder.
- * This avoids an overflow of Exp. The exponent is always
- * decimal, even for hex float consts.
- */
+ ** with a maximum exponent of +-/127, we read the exponent
+ ** part as integer with up to 3 digits and drop the remainder.
+ ** This avoids an overflow of Exp. The exponent is always
+ ** decimal, even for hex float consts.
+ */
Digits = 0;
Exp = 0;
while (IsDigit (CurC)) {
}
/* Check for errors: We must have exponent digits, and not more
- * than three.
- */
+ ** than three.
+ */
if (Digits == 0) {
Error ("Floating constant exponent has no digits");
} else if (Digits > 3) {
ident token;
/* We have to skip white space here before shifting tokens, since the
- * tokens and the current line info is invalid at startup and will get
- * initialized by reading the first time from the file. Remember if
- * we were at end of input and handle that later.
- */
+ ** tokens and the current line info is invalid at startup and will get
+ ** initialized by reading the first time from the file. Remember if
+ ** we were at end of input and handle that later.
+ */
int GotEOF = (SkipWhite() == 0);
/* Current token is the lookahead token */
if (CurTok.LI) {
- ReleaseLineInfo (CurTok.LI);
+ ReleaseLineInfo (CurTok.LI);
}
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.
- */
+ ** 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 ());
+ CurTok.LI = UseLineInfo (GetCurLineInfo ());
}
/* Remember the starting position of the next token */
/* Now handle end of input. */
if (GotEOF) {
- /* End of file reached */
- NextTok.Tok = TOK_CEOF;
- return;
+ /* End of file reached */
+ NextTok.Tok = TOK_CEOF;
+ return;
}
/* Determine the next token from the lookahead */
if (IsDigit (CurC) || (CurC == '.' && IsDigit (NextC))) {
- /* A number */
+ /* A number */
NumericConst ();
- return;
+ return;
}
/* Check for wide character literals */
/* Check for keywords and identifiers */
if (IsSym (token)) {
- /* Check for a keyword */
- if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) {
- /* Reserved word found */
- return;
- }
- /* No reserved word, check for special symbols */
- if (token[0] == '_' && token[1] == '_') {
- /* Special symbols */
+ /* Check for a keyword */
+ if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) {
+ /* Reserved word found */
+ return;
+ }
+ /* No reserved word, check for special symbols */
+ if (token[0] == '_' && token[1] == '_') {
+ /* Special symbols */
if (strcmp (token+2, "FILE__") == 0) {
- NextTok.SVal = AddLiteral (GetCurrentFile());
- NextTok.Tok = TOK_SCONST;
- return;
- } else if (strcmp (token+2, "LINE__") == 0) {
- NextTok.Tok = TOK_ICONST;
- NextTok.IVal = GetCurrentLine();
- NextTok.Type = type_int;
- return;
- } else if (strcmp (token+2, "func__") == 0) {
- /* __func__ is only defined in functions */
- if (CurrentFunc) {
- NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
- NextTok.Tok = TOK_SCONST;
- return;
- }
- }
- }
-
- /* No reserved word but identifier */
- strcpy (NextTok.Ident, token);
- NextTok.Tok = TOK_IDENT;
- return;
+ NextTok.SVal = AddLiteral (GetCurrentFile());
+ NextTok.Tok = TOK_SCONST;
+ return;
+ } else if (strcmp (token+2, "LINE__") == 0) {
+ NextTok.Tok = TOK_ICONST;
+ NextTok.IVal = GetCurrentLine();
+ NextTok.Type = type_int;
+ return;
+ } else if (strcmp (token+2, "func__") == 0) {
+ /* __func__ is only defined in functions */
+ if (CurrentFunc) {
+ NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
+ NextTok.Tok = TOK_SCONST;
+ return;
+ }
+ }
+ }
+
+ /* No reserved word but identifier */
+ strcpy (NextTok.Ident, token);
+ NextTok.Tok = TOK_IDENT;
+ return;
}
/* Monstrous switch statement ahead... */
switch (CurC) {
- case '!':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_NE);
- } else {
- NextTok.Tok = TOK_BOOL_NOT;
- }
- break;
-
- case '\"':
- StringConst ();
- break;
-
- case '%':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_MOD_ASSIGN);
- } else {
- NextTok.Tok = TOK_MOD;
- }
- break;
-
- case '&':
- NextChar ();
- switch (CurC) {
- case '&':
- SetTok (TOK_BOOL_AND);
- break;
- case '=':
- SetTok (TOK_AND_ASSIGN);
- break;
- default:
- NextTok.Tok = TOK_AND;
- }
- break;
-
- case '\'':
- CharConst ();
- break;
-
- case '(':
- SetTok (TOK_LPAREN);
- break;
-
- case ')':
- SetTok (TOK_RPAREN);
- break;
-
- case '*':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_MUL_ASSIGN);
- } else {
- NextTok.Tok = TOK_STAR;
- }
- break;
-
- case '+':
- NextChar ();
- switch (CurC) {
- case '+':
- SetTok (TOK_INC);
- break;
- case '=':
- SetTok (TOK_PLUS_ASSIGN);
- break;
- default:
- NextTok.Tok = TOK_PLUS;
- }
- break;
-
- case ',':
- SetTok (TOK_COMMA);
- break;
-
- case '-':
- NextChar ();
- switch (CurC) {
- case '-':
- SetTok (TOK_DEC);
- break;
- case '=':
- SetTok (TOK_MINUS_ASSIGN);
- break;
- case '>':
- SetTok (TOK_PTR_REF);
- break;
- default:
- NextTok.Tok = TOK_MINUS;
- }
- break;
-
- case '.':
+ case '!':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_NE);
+ } else {
+ NextTok.Tok = TOK_BOOL_NOT;
+ }
+ break;
+
+ case '\"':
+ StringConst ();
+ break;
+
+ case '%':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_MOD_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_MOD;
+ }
+ break;
+
+ case '&':
+ NextChar ();
+ switch (CurC) {
+ case '&':
+ SetTok (TOK_BOOL_AND);
+ break;
+ case '=':
+ SetTok (TOK_AND_ASSIGN);
+ break;
+ default:
+ NextTok.Tok = TOK_AND;
+ }
+ break;
+
+ case '\'':
+ CharConst ();
+ break;
+
+ case '(':
+ SetTok (TOK_LPAREN);
+ break;
+
+ case ')':
+ SetTok (TOK_RPAREN);
+ break;
+
+ case '*':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_MUL_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_STAR;
+ }
+ break;
+
+ case '+':
+ NextChar ();
+ switch (CurC) {
+ case '+':
+ SetTok (TOK_INC);
+ break;
+ case '=':
+ SetTok (TOK_PLUS_ASSIGN);
+ break;
+ default:
+ NextTok.Tok = TOK_PLUS;
+ }
+ break;
+
+ case ',':
+ SetTok (TOK_COMMA);
+ break;
+
+ case '-':
+ NextChar ();
+ switch (CurC) {
+ case '-':
+ SetTok (TOK_DEC);
+ break;
+ case '=':
+ SetTok (TOK_MINUS_ASSIGN);
+ break;
+ case '>':
+ SetTok (TOK_PTR_REF);
+ break;
+ default:
+ NextTok.Tok = TOK_MINUS;
+ }
+ break;
+
+ case '.':
NextChar ();
if (CurC == '.') {
NextChar ();
} else {
NextTok.Tok = TOK_DOT;
}
- break;
-
- case '/':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_DIV_ASSIGN);
- } else {
- NextTok.Tok = TOK_DIV;
- }
- break;
-
- case ':':
- SetTok (TOK_COLON);
- break;
-
- case ';':
- SetTok (TOK_SEMI);
- break;
-
- case '<':
- NextChar ();
- switch (CurC) {
- case '=':
- SetTok (TOK_LE);
- break;
- case '<':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_SHL_ASSIGN);
- } else {
- NextTok.Tok = TOK_SHL;
- }
- break;
- default:
- NextTok.Tok = TOK_LT;
- }
- break;
-
- case '=':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_EQ);
- } else {
- NextTok.Tok = TOK_ASSIGN;
- }
- break;
-
- case '>':
- NextChar ();
- switch (CurC) {
- case '=':
- SetTok (TOK_GE);
- break;
- case '>':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_SHR_ASSIGN);
- } else {
- NextTok.Tok = TOK_SHR;
- }
- break;
- default:
- NextTok.Tok = TOK_GT;
- }
- break;
-
- case '?':
- SetTok (TOK_QUEST);
- break;
-
- case '[':
- SetTok (TOK_LBRACK);
- break;
-
- case ']':
- SetTok (TOK_RBRACK);
- break;
-
- case '^':
- NextChar ();
- if (CurC == '=') {
- SetTok (TOK_XOR_ASSIGN);
- } else {
- NextTok.Tok = TOK_XOR;
- }
- break;
-
- case '{':
- SetTok (TOK_LCURLY);
- break;
+ break;
+
+ case '/':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_DIV_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_DIV;
+ }
+ break;
+
+ case ':':
+ SetTok (TOK_COLON);
+ break;
+
+ case ';':
+ SetTok (TOK_SEMI);
+ break;
+
+ case '<':
+ NextChar ();
+ switch (CurC) {
+ case '=':
+ SetTok (TOK_LE);
+ break;
+ case '<':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_SHL_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_SHL;
+ }
+ break;
+ default:
+ NextTok.Tok = TOK_LT;
+ }
+ break;
+
+ case '=':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_EQ);
+ } else {
+ NextTok.Tok = TOK_ASSIGN;
+ }
+ break;
+
+ case '>':
+ NextChar ();
+ switch (CurC) {
+ case '=':
+ SetTok (TOK_GE);
+ break;
+ case '>':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_SHR_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_SHR;
+ }
+ break;
+ default:
+ NextTok.Tok = TOK_GT;
+ }
+ break;
+
+ case '?':
+ SetTok (TOK_QUEST);
+ break;
+
+ case '[':
+ SetTok (TOK_LBRACK);
+ break;
+
+ case ']':
+ SetTok (TOK_RBRACK);
+ break;
+
+ case '^':
+ NextChar ();
+ if (CurC == '=') {
+ SetTok (TOK_XOR_ASSIGN);
+ } else {
+ NextTok.Tok = TOK_XOR;
+ }
+ break;
+
+ case '{':
+ SetTok (TOK_LCURLY);
+ break;
case '|':
- NextChar ();
- switch (CurC) {
- case '|':
- SetTok (TOK_BOOL_OR);
- break;
- case '=':
- SetTok (TOK_OR_ASSIGN);
- break;
- default:
- NextTok.Tok = TOK_OR;
- }
- break;
-
- case '}':
- SetTok (TOK_RCURLY);
- break;
-
- case '~':
- SetTok (TOK_COMP);
- break;
-
- default:
- UnknownChar (CurC);
+ NextChar ();
+ switch (CurC) {
+ case '|':
+ SetTok (TOK_BOOL_OR);
+ break;
+ case '=':
+ SetTok (TOK_OR_ASSIGN);
+ break;
+ default:
+ NextTok.Tok = TOK_OR;
+ }
+ break;
+
+ case '}':
+ SetTok (TOK_RCURLY);
+ break;
+
+ case '~':
+ SetTok (TOK_COMP);
+ break;
+
+ default:
+ UnknownChar (CurC);
}
void SkipTokens (const token_t* TokenList, unsigned TokenCount)
/* Skip tokens until we reach TOK_CEOF or a token in the given token list.
- * This routine is used for error recovery.
- */
+** This routine is used for error recovery.
+*/
{
while (CurTok.Tok != TOK_CEOF) {
- /* Check if the current token is in the token list */
- unsigned I;
- for (I = 0; I < TokenCount; ++I) {
- if (CurTok.Tok == TokenList[I]) {
- /* Found a token in the list */
- return;
- }
- }
+ /* Check if the current token is in the token list */
+ unsigned I;
+ for (I = 0; I < TokenCount; ++I) {
+ if (CurTok.Tok == TokenList[I]) {
+ /* Found a token in the list */
+ return;
+ }
+ }
- /* Not in the list: Skip it */
- NextToken ();
+ /* Not in the list: Skip it */
+ NextToken ();
}
}
int Consume (token_t Token, const char* ErrorMsg)
/* Eat token if it is the next in the input stream, otherwise print an error
- * message. Returns true if the token was found and false otherwise.
- */
+** message. Returns true if the token was found and false otherwise.
+*/
{
if (CurTok.Tok == Token) {
- NextToken ();
+ NextToken ();
return 1;
} else {
- Error ("%s", ErrorMsg);
+ Error ("%s", ErrorMsg);
return 0;
}
}
int ConsumeColon (void)
/* Check for a colon and skip it. */
{
- return Consume (TOK_COLON, "`:' expected");
+ return Consume (TOK_COLON, "':' expected");
}
{
/* Try do be smart about typos... */
if (CurTok.Tok == TOK_SEMI) {
- NextToken ();
+ NextToken ();
return 1;
} else {
- Error ("`;' expected");
- if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) {
- NextToken ();
- }
+ Error ("';' expected");
+ if (CurTok.Tok == TOK_COLON || CurTok.Tok == TOK_COMMA) {
+ NextToken ();
+ }
return 0;
}
}
{
/* Try do be smart about typos... */
if (CurTok.Tok == TOK_COMMA) {
- NextToken ();
+ NextToken ();
return 1;
} else {
- Error ("`,' expected");
- if (CurTok.Tok == TOK_SEMI) {
- NextToken ();
- }
+ Error ("',' expected");
+ if (CurTok.Tok == TOK_SEMI) {
+ NextToken ();
+ }
return 0;
}
}
int ConsumeLParen (void)
/* Check for a left parenthesis and skip it */
{
- return Consume (TOK_LPAREN, "`(' expected");
+ return Consume (TOK_LPAREN, "'(' expected");
}
int ConsumeRParen (void)
/* Check for a right parenthesis and skip it */
{
- return Consume (TOK_RPAREN, "`)' expected");
+ return Consume (TOK_RPAREN, "')' expected");
}
int ConsumeLBrack (void)
/* Check for a left bracket and skip it */
{
- return Consume (TOK_LBRACK, "`[' expected");
+ return Consume (TOK_LBRACK, "'[' expected");
}
int ConsumeRBrack (void)
/* Check for a right bracket and skip it */
{
- return Consume (TOK_RBRACK, "`]' expected");
+ return Consume (TOK_RBRACK, "']' expected");
}
int ConsumeLCurly (void)
/* Check for a left curly brace and skip it */
{
- return Consume (TOK_LCURLY, "`{' expected");
+ return Consume (TOK_LCURLY, "'{' expected");
}
int ConsumeRCurly (void)
/* Check for a right curly brace and skip it */
{
- return Consume (TOK_RCURLY, "`}' expected");
+ return Consume (TOK_RCURLY, "'}' expected");
}
-
-
-