gbdk-releases/sdcc/src/altlex.c
2015-01-10 16:25:09 +01:00

1218 lines
24 KiB
C

/** @file altlex.c
An alternate lexer to SDCC.lex.
In development - ie messy and just plain wrong.
Inspired by the gcc lexer, c-lex.c.
*/
#include "common.h"
#include "reswords.h"
#include <assert.h>
#define DUMP_OUTPUT 0
/* Right. What are the parts of the C stream? From SDCC.lex:
D = [0..9] digits
L = [a..z A..Z _] alphanumerics and _
H = [a..f A..F 0-9] Hex digits
E = [eE+-0-9] Digits in a float
FS = [fFlL] Specifiers for a float
IS = [uUlL] Specifiers for a int
L[LD]* A 'token' - cant think of a good name
Check tokens against the reserved words.
If match
return the token id.
else
If in the typedef table, do stuff...
Blah. See check_type()
0[xX]{H}+ Hex number - PENDING: specifiers
0{D}+ Octal number - PENDING: specifiers
{D}+ Decimal - PENDING: specifiers
Floats PENDING
Exceptions:
Comment start Strip until end of comment.
... Ellipses
So the inputs are:
Skip whitespace
switch class
L Try to read a token
D Try to read a number
Punct Try to read punct
*/
extern int fatalError;
extern int lineno;
extern char *filename;
FILE *yyin;
int yylineno;
char *currFname;
char *yytext;
static char linebuf[10000];
static int linepos, linelen;
static int end_of_file;
#ifdef __GNUC__
#define INLINE inline
#else
#define INLINE
#endif
#define ERRSINK stderr
static void
error (const char *sz,...)
{
va_list ap;
fatalError++;
if (filename && lineno)
{
fprintf (ERRSINK, "%s(%d):", filename, lineno);
}
fprintf (ERRSINK, "error *** ");
va_start (ap, sz);
vfprintf (ERRSINK, sz, ap);
va_end (ap);
fprintf (ERRSINK, "\n");
fflush (ERRSINK);
}
static int
underflow (void)
{
linelen = fread (linebuf, 1, sizeof (linebuf), yyin);
if (linelen <= 0)
return EOF;
linepos = 0;
return linebuf[linepos++];
}
static int INLINE
ygetc (void)
{
if (linepos < linelen)
return linebuf[linepos++];
else
return underflow ();
};
static int INLINE
yungetc (int c)
{
linebuf[--linepos] = c;
return 0;
}
#define GETC() ygetc()
#define UNGETC(_a) yungetc(_a)
//#define GETC() fgetc(yyin);
//#define UNGETC(_a) ungetc(_a, yyin)
#define ISL(_a) (isalnum(_a) || _a == '_')
#define ISALNUM(_a) isalnum(_a)
#define ISHEX(_a) isxdigit(_a)
static char *
stringLiteral (void)
{
static char line[1000];
int ch;
char *str = line;
*str++ = '\"';
/* put into the buffer till we hit the */
/* first \" */
while (1)
{
ch = GETC ();
if (!ch)
break; /* end of input */
/* if it is a \ then everything allowed */
if (ch == '\\')
{
*str++ = ch; /* backslash in place */
*str++ = GETC (); /* following char in place */
continue; /* carry on */
}
/* if new line we have a new line break */
if (ch == '\n')
break;
/* if this is a quote then we have work to do */
/* find the next non whitespace character */
/* if that is a double quote then carry on */
if (ch == '\"')
{
while ((ch = GETC ()) && isspace (ch));
if (!ch)
break;
if (ch != '\"')
{
UNGETC (ch);
break;
}
continue;
}
*str++ = ch;
}
*str++ = '\"';
*str = '\0';
return line;
}
static void
discard_comments (int type)
{
int c;
if (type == '*')
{
do
{
c = GETC ();
if (c == '*')
{
c = GETC ();
if (c == '/')
return;
}
else if (c == EOF)
return;
}
while (1);
}
else if (type == '/')
{
do
{
c = GETC ();
}
while (c != '\n' && c != EOF);
}
else
{
assert (0);
}
}
/* will return 1 if the string is a part
of a target specific keyword */
static INLINE int
isTargetKeyword (const char *s)
{
int i;
if (port->keywords == NULL)
return 0;
for (i = 0; port->keywords[i]; i++)
{
if (strcmp (port->keywords[i], s) == 0)
return 1;
}
return 0;
}
static INLINE int
check_token (const char *sz)
{
const struct reserved_words *p;
p = is_reserved_word (sz, strlen (sz));
if (p)
{
if (!p->is_special || isTargetKeyword (sz))
return p->token;
}
/* check if it is in the typedef table */
if (findSym (TypedefTab, NULL, sz))
{
strcpy (yylval.yychar, sz);
return TYPE_NAME;
}
else
{
strcpy (yylval.yychar, sz);
return IDENTIFIER;
}
}
static void
handle_pragma (void)
{
char line[128], *p;
int c;
c = GETC ();
while (c == '\t' || c == ' ')
c = GETC ();
p = line;
while (!isspace (c))
{
*p++ = c;
c = GETC ();
}
*p = '\0';
if (line[0] == '\0')
error ("Missing argument to pragma");
else
{
/* First give the port a chance */
if (port->process_pragma && !port->process_pragma (line))
return;
/* PENDING: all the SDCC shared pragmas */
/* Nothing handled it */
error ("Unrecognised #pragma %s", line);
}
}
static void
handle_line (void)
{
int c;
char line[128], *p;
c = GETC ();
while (c == '\t' || c == ' ')
c = GETC ();
p = line;
while (isdigit (c))
{
*p++ = c;
c = GETC ();
}
*p = '\0';
if (line[0] == '\0')
error ("Error in number in #line");
/* This is weird but cpp seems to add an extra three to the line no */
yylineno = atoi (line) - 3;
lineno = yylineno;
/* Fetch the filename if there is one */
while (c == '\t' || c == ' ')
c = GETC ();
if (c == '\"')
{
p = line;
c = GETC ();
while (c != '\"' && c != EOF && c != '\n')
{
*p++ = c;
c = GETC ();
}
if (c == '\"')
{
*p = '\0';
currFname = Safe_strdup (line);
}
filename = currFname;
}
}
static INLINE void
invalid_directive (void)
{
error ("Invalid directive");
}
static INLINE int
check_newline (void)
{
int c;
yylineno++;
lineno = yylineno;
/* Skip any leading white space */
c = GETC ();
while (c == '\t' || c == ' ')
c = GETC ();
/* Were only interested in #something */
if (c != '#')
return c;
c = GETC ();
while (c == '\t' || c == ' ')
c = GETC ();
/* The text in the stream is the type of directive */
switch (c)
{
case 'l':
/* Start of line? */
if (GETC () == 'i' && GETC () == 'n' && GETC () == 'e')
{
c = GETC ();
if (c == '\t' || c == ' ')
handle_line ();
else
invalid_directive ();
}
else
invalid_directive ();
break;
case 'p':
/* Start of pragma? */
if (GETC () == 'r' && GETC () == 'a' && GETC () == 'g' &&
GETC () == 'm' && GETC () == 'a')
{
c = GETC ();
if (c == '\t' || c == ' ')
handle_pragma ();
else
invalid_directive ();
}
else
invalid_directive ();
break;
default:
invalid_directive ();
}
/* Discard from here until the start of the next line */
while (c != '\n' && c != EOF)
c = GETC ();
return c;
}
static int
skip_whitespace (int c)
{
while (1)
{
switch (c)
{
case ' ':
case '\t':
case '\f':
case '\v':
case '\b':
case '\r':
c = GETC ();
break;
case '\n':
c = check_newline ();
default:
return c;
}
}
}
void
yyerror (const char *s)
{
if (end_of_file)
error ("%s at end of of input", s);
else if (yytext[0] == '\0')
error ("%s at null character", s);
else if (yytext[0] == '"')
error ("%s before string constant", s);
else if (yytext[0] == '\'')
error ("%s before character constant", s);
else
error ("%s before %s", s, yytext);
}
static int
_yylex (void)
{
int c;
static char line[128];
char *p;
yytext = line;
c = GETC ();
while (1)
{
switch (c)
{
case ' ':
case '\t':
case '\f':
case '\v':
case '\b':
/* Skip whitespace */
c = GETC ();
break;
case '\r':
case '\n':
c = skip_whitespace (c);
break;
case '#':
UNGETC (c);
c = check_newline ();
break;
default:
goto past_ws;
}
}
past_ws:
/* Handle comments first */
if (c == '/')
{
int c2 = GETC ();
if (c2 == '*' || c2 == '/')
{
discard_comments (c2);
c = GETC ();
}
else
UNGETC (c2);
}
switch (c)
{
case EOF:
end_of_file = TRUE;
line[0] = '\0';
return 0;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':
/* Start of a token. Parse. */
p = line;
*p++ = c;
c = GETC ();
while (ISL (c))
{
*p++ = c;
c = GETC ();
}
*p = '\0';
UNGETC (c);
return check_token (line);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
p = line;
*p++ = c;
c = GETC ();
if (c == 'x' || c == 'X')
{
*p++ = c;
c = GETC ();
}
while (ISHEX (c))
{
*p++ = c;
c = GETC ();
}
if (c == 'U' || c == 'u' || c == 'L' || c == 'l')
{
*p++ = c;
c = GETC ();
}
if (c == 'U' || c == 'u' || c == 'L' || c == 'l')
{
*p++ = c;
c = GETC ();
}
*p = '\0';
UNGETC (c);
yylval.val = constVal (line);
return CONSTANT;
case '\"':
/* A string */
p = stringLiteral ();
yylval.val = strVal (p);
return (STRING_LITERAL);
case '\'':
/* Possible formats:
['\n', '\\', '\'', '\"'...]
['a'...]
*/
p = line;
*p++ = c;
c = GETC ();
if (c == '\\')
{
*p++ = c;
c = GETC ();
/* Fall through */
}
*p++ = c;
c = GETC ();
*p++ = c;
*p = '\0';
if (c != '\'')
{
error ("Unrecognised character constant %s", line);
}
yylval.val = charVal (line);
return CONSTANT;
case '=':
case '&':
case '!':
case '-':
case '+':
case '*':
case '/':
case '%':
case '<':
case '>':
case '^':
case '|':
{
/* Cases which can be compounds */
/* The types and classes of composites are:
>>= <<=
+= -= *= /= %= &= ^= |=
>> << ++ --
&& ||
<= >= == !=
->
So a composite started by char 'x' can be:
1. Followed by itself then an equals
2. Followed by itself
3. Followed by an equals
4. Be a '->'
5. Be by itself
*/
int next = GETC ();
/* Class 1 and 2 */
if (next == c)
{
next = GETC ();
/* Class 1 */
if (next == '=')
{
switch (c)
{
case '>': // >>=
yylval.yyint = RIGHT_ASSIGN;
return RIGHT_ASSIGN;
case '<': // <<=
yylval.yyint = LEFT_ASSIGN;
return LEFT_ASSIGN;
default:
error ("Unrecognised token %c%c=", c, c);
}
}
else
{
/* Push the next char back on and find the class */
UNGETC (next);
/* Case 2 */
switch (c)
{
case '>': // >>
return RIGHT_OP;
case '<': // <<
return LEFT_OP;
case '+':
return INC_OP;
case '-':
return DEC_OP;
case '&':
return AND_OP;
case '|':
return OR_OP;
case '=':
return EQ_OP;
default:
error ("Unrecognised token %c%c", c, c);
}
}
}
/* Case 3 */
else if (next == '=')
{
int result = 0;
switch (c)
{
case '+':
result = ADD_ASSIGN;
break;
case '-':
result = SUB_ASSIGN;
break;
case '*':
result = MUL_ASSIGN;
break;
case '/':
result = DIV_ASSIGN;
break;
case '%':
result = MOD_ASSIGN;
break;
case '&':
result = AND_ASSIGN;
break;
case '^':
result = XOR_ASSIGN;
break;
case '|':
result = OR_ASSIGN;
break;
case '<':
result = LE_OP;
break;
case '>':
result = GE_OP;
break;
case '!':
result = NE_OP;
break;
default:
error ("Unrecognised token %c=", c);
}
if (result)
{
yylval.yyint = result;
return result;
}
}
/* Case 4 */
else if (c == '-' && next == '>')
{
return PTR_OP;
}
/* Case 5 */
else
{
UNGETC (next);
return c;
}
break;
}
case '{':
NestLevel++;
return c;
case '}':
NestLevel--;
return c;
case '.':
c = GETC ();
if (c == '.')
{
c = GETC ();
if (c == '.')
{
return VAR_ARGS;
}
}
UNGETC (c);
return '.';
case '[':
case ']':
return c;
case ',':
case ':':
case '(':
case ')':
case '~':
case '?':
case ';':
/* Special characters that cant be part of a composite */
return c;
default:
error ("Unhandled character %c", c);
}
return 0;
}
#define ENTRY(_a) case (_a): printf(#_a); break;
int
yylex (void)
{
int ret = _yylex ();
#if DUMP_OUTPUT
static int lastpos = 0;
char tmp;
printf ("Returning ");
switch (ret)
{
/* Wrapper */
ENTRY (IDENTIFIER);
ENTRY (TYPE_NAME);
ENTRY (CONSTANT);
ENTRY (STRING_LITERAL);
ENTRY (SIZEOF);
ENTRY (PTR_OP);
ENTRY (INC_OP);
ENTRY (DEC_OP);
ENTRY (LEFT_OP);
ENTRY (RIGHT_OP);
ENTRY (LE_OP);
ENTRY (GE_OP);
ENTRY (EQ_OP);
ENTRY (NE_OP);
ENTRY (AND_OP);
ENTRY (OR_OP);
ENTRY (MUL_ASSIGN);
ENTRY (DIV_ASSIGN);
ENTRY (MOD_ASSIGN);
ENTRY (ADD_ASSIGN);
ENTRY (SUB_ASSIGN);
ENTRY (LEFT_ASSIGN);
ENTRY (RIGHT_ASSIGN);
ENTRY (AND_ASSIGN);
ENTRY (XOR_ASSIGN);
ENTRY (OR_ASSIGN);
ENTRY (TYPEDEF);
ENTRY (EXTERN);
ENTRY (STATIC);
ENTRY (AUTO);
ENTRY (REGISTER);
ENTRY (CODE);
ENTRY (EEPROM);
ENTRY (INTERRUPT);
ENTRY (SFR);
ENTRY (AT);
ENTRY (SBIT);
ENTRY (REENTRANT);
ENTRY (USING);
ENTRY (XDATA);
ENTRY (DATA);
ENTRY (IDATA);
ENTRY (PDATA);
ENTRY (VAR_ARGS);
ENTRY (CRITICAL);
ENTRY (NONBANKED);
ENTRY (BANKED);
ENTRY (CHAR);
ENTRY (SHORT);
ENTRY (INT);
ENTRY (LONG);
ENTRY (SIGNED);
ENTRY (UNSIGNED);
ENTRY (FLOAT);
ENTRY (DOUBLE);
ENTRY (CONST);
ENTRY (VOLATILE);
ENTRY (VOID);
ENTRY (BIT);
ENTRY (STRUCT);
ENTRY (UNION);
ENTRY (ENUM);
ENTRY (ELIPSIS);
ENTRY (RANGE);
ENTRY (FAR);
ENTRY (_XDATA);
ENTRY (_CODE);
ENTRY (_GENERIC);
ENTRY (_NEAR);
ENTRY (_PDATA);
ENTRY (_IDATA);
ENTRY (_EEPROM);
ENTRY (CASE);
ENTRY (DEFAULT);
ENTRY (IF);
ENTRY (ELSE);
ENTRY (SWITCH);
ENTRY (WHILE);
ENTRY (DO);
ENTRY (FOR);
ENTRY (GOTO);
ENTRY (CONTINUE);
ENTRY (BREAK);
ENTRY (RETURN);
ENTRY (INLINEASM);
ENTRY (IFX);
ENTRY (ADDRESS_OF);
ENTRY (GET_VALUE_AT_ADDRESS);
ENTRY (SPIL);
ENTRY (UNSPIL);
ENTRY (GETHBIT);
ENTRY (BITWISEAND);
ENTRY (UNARYMINUS);
ENTRY (IPUSH);
ENTRY (IPOP);
ENTRY (PCALL);
ENTRY (ENDFUNCTION);
ENTRY (JUMPTABLE);
ENTRY (RRC);
ENTRY (RLC);
ENTRY (CAST);
ENTRY (CALL);
ENTRY (PARAM);
ENTRY (NULLOP);
ENTRY (BLOCK);
ENTRY (LABEL);
ENTRY (RECEIVE);
ENTRY (SEND);
default:
printf ("default: %c", ret);
}
tmp = linebuf[linepos];
linebuf[linepos] = '\0';
printf (" for %s (%u bytes)\n", linebuf + lastpos, linepos - lastpos);
linebuf[linepos] = tmp;
lastpos = linepos;
fflush (stdout);
#endif
return ret;
}
#define TEST(_a) (_a) ? (void)0 : printf("Test %s failed\n", #_a);
int
altlex_testparse (const char *input)
{
/* Fiddle with the read-ahead buffer to insert ourselves */
strcpy (linebuf, input);
linelen = strlen (linebuf) + 1;
linepos = 0;
return yylex ();
}
int
altlex_testchar (const char *input)
{
value *val;
if (altlex_testparse (input) != CONSTANT)
return -2;
val = yylval.val;
if (val->type->class != SPECIFIER)
return -3;
if (SPEC_NOUN (val->type) != V_CHAR)
return -4;
if (SPEC_SCLS (val->type) != S_LITERAL)
return -5;
return SPEC_CVAL (val->type).v_int;
}
int
altlex_testnum (const char *input)
{
value *val;
if (altlex_testparse (input) != CONSTANT)
return -2;
val = yylval.val;
if (val->type->class != SPECIFIER)
return -3;
if (SPEC_NOUN (val->type) != V_INT)
return -4;
if (SPEC_SCLS (val->type) != S_LITERAL)
return -5;
if (SPEC_USIGN (val->type))
return SPEC_CVAL (val->type).v_uint;
else
return SPEC_CVAL (val->type).v_int;
}
int
altlex_runtests (void)
{
/* These conditions are ripped directly from SDCC.lex */
/* First check the parsing of the basic tokens */
TEST (altlex_testparse (">>=") == RIGHT_ASSIGN);
TEST (altlex_testparse ("<<=") == LEFT_ASSIGN);
TEST (altlex_testparse ("+=") == ADD_ASSIGN);
TEST (altlex_testparse ("-=") == SUB_ASSIGN);
TEST (altlex_testparse ("*=") == MUL_ASSIGN);
TEST (altlex_testparse ("/=") == DIV_ASSIGN);
TEST (altlex_testparse ("%=") == MOD_ASSIGN);
TEST (altlex_testparse ("&=") == AND_ASSIGN);
TEST (altlex_testparse ("^=") == XOR_ASSIGN);
TEST (altlex_testparse ("|=") == OR_ASSIGN);
TEST (altlex_testparse (">>") == RIGHT_OP);
TEST (altlex_testparse ("<<") == LEFT_OP);
TEST (altlex_testparse ("++") == INC_OP);
TEST (altlex_testparse ("--") == DEC_OP);
TEST (altlex_testparse ("->") == PTR_OP);
TEST (altlex_testparse ("&&") == AND_OP);
TEST (altlex_testparse ("||") == OR_OP);
TEST (altlex_testparse ("<=") == LE_OP);
TEST (altlex_testparse (">=") == GE_OP);
TEST (altlex_testparse ("==") == EQ_OP);
TEST (altlex_testparse ("!=") == NE_OP);
TEST (altlex_testparse (";") == ';');
TEST (altlex_testparse ("{") == '{');
TEST (altlex_testparse ("}") == '}');
TEST (altlex_testparse (",") == ',');
TEST (altlex_testparse (":") == ':');
TEST (altlex_testparse ("=") == '=');
TEST (altlex_testparse ("(") == '(');
TEST (altlex_testparse (")") == ')');
TEST (altlex_testparse ("[") == '[');
TEST (altlex_testparse ("]") == ']');
TEST (altlex_testparse (".") == '.');
TEST (altlex_testparse ("&") == '&');
TEST (altlex_testparse ("!") == '!');
TEST (altlex_testparse ("~") == '~');
TEST (altlex_testparse ("-") == '-');
TEST (altlex_testparse ("+") == '+');
TEST (altlex_testparse ("*") == '*');
TEST (altlex_testparse ("/") == '/');
TEST (altlex_testparse ("%") == '%');
TEST (altlex_testparse ("<") == '<');
TEST (altlex_testparse (">") == '>');
TEST (altlex_testparse ("^") == '^');
TEST (altlex_testparse ("|") == '|');
TEST (altlex_testparse ("?") == '?');
/* Now some character constants */
TEST (altlex_testchar ("'1'") == '1');
TEST (altlex_testchar ("'a'") == 'a');
TEST (altlex_testchar ("'A'") == 'A');
TEST (altlex_testchar ("'z'") == 'z');
TEST (altlex_testchar ("'Z'") == 'Z');
TEST (altlex_testchar ("'\n'") == '\n');
TEST (altlex_testchar ("'\\\\'") == '\\');
TEST (altlex_testchar ("'\\''") == '\'');
/* And some numbers */
TEST (altlex_testnum ("0") == 0);
TEST (altlex_testnum ("1") == 1);
TEST (altlex_testnum ("075") == 075);
TEST (altlex_testnum ("0xfeed") == 0xfeed);
TEST (altlex_testnum ("0xFEED") == 0xFEED);
TEST (altlex_testnum ("0x00005678") == 0x5678);
/* Keywords */
TEST (altlex_testparse ("auto") == AUTO);
TEST (altlex_testparse ("break") == BREAK);
TEST (altlex_testparse ("case") == CASE);
TEST (altlex_testparse ("char") == CHAR);
TEST (altlex_testparse ("const") == CONST);
TEST (altlex_testparse ("continue") == CONTINUE);
TEST (altlex_testparse ("default") == DEFAULT);
TEST (altlex_testparse ("do") == DO);
/* Prints a warning */
// TEST(altlex_testparse("double") == FLOAT);
TEST (altlex_testparse ("else") == ELSE);
TEST (altlex_testparse ("enum") == ENUM);
TEST (altlex_testparse ("extern") == EXTERN);
TEST (altlex_testparse ("float") == FLOAT);
TEST (altlex_testparse ("for") == FOR);
TEST (altlex_testparse ("goto") == GOTO);
TEST (altlex_testparse ("if") == IF);
TEST (altlex_testparse ("int") == INT);
TEST (altlex_testparse ("interrupt") == INTERRUPT);
TEST (altlex_testparse ("long") == LONG);
TEST (altlex_testparse ("register") == REGISTER);
TEST (altlex_testparse ("return") == RETURN);
TEST (altlex_testparse ("short") == SHORT);
TEST (altlex_testparse ("signed") == SIGNED);
TEST (altlex_testparse ("sizeof") == SIZEOF);
TEST (altlex_testparse ("static") == STATIC);
TEST (altlex_testparse ("struct") == STRUCT);
TEST (altlex_testparse ("switch") == SWITCH);
TEST (altlex_testparse ("typedef") == TYPEDEF);
TEST (altlex_testparse ("union") == UNION);
TEST (altlex_testparse ("unsigned") == UNSIGNED);
TEST (altlex_testparse ("void") == VOID);
TEST (altlex_testparse ("volatile") == VOLATILE);
TEST (altlex_testparse ("while") == WHILE);
TEST (altlex_testparse ("...") == VAR_ARGS);
#if 0
/* Platform specific keywords */
TEST (altlex_testparse ("sram") ==)
{
count ();
TKEYWORD (XDATA);
}
TEST (altlex_testparse ("using") ==)
{
count ();
TKEYWORD (USING);
}
TEST (altlex_testparse ("near") ==)
{
count ();
TKEYWORD (DATA);
}
TEST (altlex_testparse ("at") ==)
{
count ();
TKEYWORD (AT);
}
TEST (altlex_testparse ("bit") ==)
{
count ();
TKEYWORD (BIT);
}
TEST (altlex_testparse ("code") ==)
{
count ();
TKEYWORD (CODE);
}
TEST (altlex_testparse ("critical") ==)
{
count ();
TKEYWORD (CRITICAL);
}
TEST (altlex_testparse ("data") ==)
{
count ();
TKEYWORD (DATA);
}
TEST (altlex_testparse ("far") ==)
{
count ();
TKEYWORD (XDATA);
}
TEST (altlex_testparse ("eeprom") ==)
{
count ();
TKEYWORD (EEPROM);
}
TEST (altlex_testparse ("flash") ==)
{
count ();
TKEYWORD (CODE);
}
TEST (altlex_testparse ("idata") ==)
{
count ();
TKEYWORD (IDATA);
}
TEST (altlex_testparse ("nonbanked") ==)
{
count ();
TKEYWORD (NONBANKED);
}
TEST (altlex_testparse ("banked") ==)
{
count ();
TKEYWORD (BANKED);
}
TEST (altlex_testparse ("pdata") ==)
{
count ();
TKEYWORD (PDATA);
}
TEST (altlex_testparse ("reentrant") ==)
{
count ();
TKEYWORD (REENTRANT);
}
TEST (altlex_testparse ("sfr") ==)
{
count ();
TKEYWORD (SFR);
}
TEST (altlex_testparse ("sbit") ==)
{
count ();
TKEYWORD (SBIT);
}
TEST (altlex_testparse ("xdata") ==)
{
count ();
TKEYWORD (XDATA);
}
TEST (altlex_testparse ("_data") ==)
{
count ();
TKEYWORD (_NEAR);
}
TEST (altlex_testparse ("_code") ==)
{
count ();
TKEYWORD (_CODE);
}
TEST (altlex_testparse ("_eeprom") ==)
{
count ();
TKEYWORD (_EEPROM);
}
TEST (altlex_testparse ("_flash") ==)
{
count ();
TKEYWORD (_CODE);
}
TEST (altlex_testparse ("_generic") ==)
{
count ();
TKEYWORD (_GENERIC);
}
TEST (altlex_testparse ("_near") ==)
{
count ();
TKEYWORD (_NEAR);
}
TEST (altlex_testparse ("_sram") ==)
{
count ();
TKEYWORD (_XDATA);
}
TEST (altlex_testparse ("_xdata") ==)
{
count ();
TKEYWORD (_XDATA);
}
TEST (altlex_testparse ("_pdata") ==)
{
count ();
TKEYWORD (_PDATA);
}
TEST (altlex_testparse ("_idata") ==)
{
count ();
TKEYWORD (_IDATA);
}
#endif
return 0;
}