In development - ie messy and just plain wrong.
*/
#include "common.h"
+#include "reswords.h"
#include <assert.h>
+#define DUMP_OUTPUT 0
+
FILE *yyin;
int yylineno;
int linepos, linelen;
#define INLINE inline
+#define ERRSINK stdout
+
+extern int fatalError ;
+extern int lineno ;
+extern char *filename;
+
+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)
{
#define ISALNUM(_a) isalnum(_a)
#define ISHEX(_a) isalnum(_a)
-char *stringLiteral (void)
+static char *stringLiteral (void)
{
static char line[1000];
int ch;
return line;
}
-void discard_comments(int type)
+static void discard_comments(int type)
{
int c;
if (type == '*') {
} while (1);
}
else if (type == '/') {
- while (c != '\n' && c != EOF) {
+ do {
c = GETC();
- }
+ } while (c != '\n' && c != EOF);
}
else {
assert(0);
}
}
-#define TKEYWORD(_a) return _a
-
-int check_token(const char *sz)
+/* will return 1 if the string is a part
+ of a target specific keyword */
+static int isTargetKeyword(const char *s)
{
- if (!strcmp(sz, "at")) {
- TKEYWORD(AT) ; }
+ int i;
- else if (!strcmp(sz, "auto")) {
- return(AUTO); }
-
- else if (!strcmp(sz, "bit")) {
- TKEYWORD(BIT) ; }
+ if (port->keywords == NULL)
+ return 0;
+ for ( i = 0 ; port->keywords[i] ; i++ ) {
+ if (strcmp(port->keywords[i],s) == 0)
+ return 1;
+ }
- else if (!strcmp(sz, "break")) {
- return(BREAK); }
-
- else if (!strcmp(sz, "case")) {
- return(CASE); }
-
- else if (!strcmp(sz, "char")) {
- return(CHAR); }
-
- else if (!strcmp(sz, "code")) {
- TKEYWORD(CODE); }
-
- else if (!strcmp(sz, "const")) {
- return(CONST); }
-
- else if (!strcmp(sz, "continue")) {
- return(CONTINUE); }
-
- else if (!strcmp(sz, "critical")) {
- TKEYWORD(CRITICAL); }
-
- else if (!strcmp(sz, "data")) {
- TKEYWORD(DATA); }
-
- else if (!strcmp(sz, "default")) {
- return(DEFAULT); }
-
- else if (!strcmp(sz, "do")) {
- return(DO); }
-
- else if (!strcmp(sz, "double")) {
- werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
-
- else if (!strcmp(sz, "else")) {
- return(ELSE); }
-
- else if (!strcmp(sz, "enum")) {
- return(ENUM); }
-
- else if (!strcmp(sz, "extern")) {
- return(EXTERN); }
-
- else if (!strcmp(sz, "far")) {
- TKEYWORD(XDATA); }
-
- else if (!strcmp(sz, "eeprom")) {
- TKEYWORD(EEPROM); }
-
- else if (!strcmp(sz, "float")) {
- return(FLOAT); }
-
- else if (!strcmp(sz, "flash")) {
- TKEYWORD(CODE);}
-
- else if (!strcmp(sz, "for")) {
- return(FOR); }
-
- else if (!strcmp(sz, "goto")) {
- return(GOTO); }
-
- else if (!strcmp(sz, "idata")) {
- TKEYWORD(IDATA);}
-
- else if (!strcmp(sz, "if")) {
- return(IF); }
-
- else if (!strcmp(sz, "int")) {
- return(INT); }
-
- else if (!strcmp(sz, "interrupt")) {
- return(INTERRUPT);}
-
- else if (!strcmp(sz, "nonbanked")) {
- TKEYWORD(NONBANKED);}
-
- else if (!strcmp(sz, "banked")) {
- TKEYWORD(BANKED);}
-
- else if (!strcmp(sz, "long")) {
- return(LONG); }
-
- else if (!strcmp(sz, "near")) {
- TKEYWORD(DATA);}
-
- else if (!strcmp(sz, "pdata")) {
- TKEYWORD(PDATA); }
-
- else if (!strcmp(sz, "reentrant")) {
- TKEYWORD(REENTRANT);}
-
- else if (!strcmp(sz, "register")) {
- return(REGISTER); }
-
- else if (!strcmp(sz, "return")) {
- return(RETURN); }
-
- else if (!strcmp(sz, "sfr")) {
- TKEYWORD(SFR) ; }
-
- else if (!strcmp(sz, "sbit")) {
- TKEYWORD(SBIT) ; }
-
- else if (!strcmp(sz, "short")) {
- return(SHORT); }
-
- else if (!strcmp(sz, "signed")) {
- return(SIGNED); }
-
- else if (!strcmp(sz, "sizeof")) {
- return(SIZEOF); }
-
- else if (!strcmp(sz, "sram")) {
- TKEYWORD(XDATA);}
-
- else if (!strcmp(sz, "static")) {
- return(STATIC); }
-
- else if (!strcmp(sz, "struct")) {
- return(STRUCT); }
-
- else if (!strcmp(sz, "switch")) {
- return(SWITCH); }
-
- else if (!strcmp(sz, "typedef")) {
- return(TYPEDEF); }
-
- else if (!strcmp(sz, "union")) {
- return(UNION); }
-
- else if (!strcmp(sz, "unsigned")) {
- return(UNSIGNED); }
-
- else if (!strcmp(sz, "void")) {
- return(VOID); }
-
- else if (!strcmp(sz, "volatile")) {
- return(VOLATILE); }
-
- else if (!strcmp(sz, "using")) {
- TKEYWORD(USING); }
-
- else if (!strcmp(sz, "while")) {
- return(WHILE); }
-
- else if (!strcmp(sz, "xdata")) {
- TKEYWORD(XDATA); }
-
- else if (!strcmp(sz, "_data")) {
- TKEYWORD(_NEAR); }
-
- else if (!strcmp(sz, "_code")) {
- TKEYWORD(_CODE); }
-
- else if (!strcmp(sz, "_eeprom")) {
- TKEYWORD(_EEPROM); }
-
- else if (!strcmp(sz, "_flash")) {
- TKEYWORD(_CODE); }
-
- else if (!strcmp(sz, "_generic")) {
- TKEYWORD(_GENERIC); }
-
- else if (!strcmp(sz, "_near")) {
- TKEYWORD(_NEAR); }
-
- else if (!strcmp(sz, "_sram")) {
- TKEYWORD(_XDATA);}
-
- else if (!strcmp(sz, "_xdata")) {
- TKEYWORD(_XDATA);}
-
- else if (!strcmp(sz, "_pdata")) {
- TKEYWORD(_PDATA); }
+ return 0;
+}
- else if (!strcmp(sz, "_idata")) {
- TKEYWORD(_IDATA); }
+static 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) ;
+ return TYPE_NAME;
}
else {
strcpy (yylval.yychar,sz);
- return(IDENTIFIER);
+ return IDENTIFIER;
}
}
-int yylex(void)
+static int _yylex(void)
{
int c;
char line[128];
yylval.val = strVal(p);
return(STRING_LITERAL);
case '\'':
- /* ie '\n' */
- break;
+ /* 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 '#':
/* Assume a pragma and toast the rest of the line. */
c = GETC();
case '<':
case '>':
case '^':
- case '|':
+ case '|': {
/* Cases which can be compounds */
- return c;
+ /* 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;
}
}
UNGETC(c);
- /* Fall through */
+ return '.';
+ case '[': case ']':
+ return c;
case ',':
case ':':
case '(': case ')':
- case '[': case ']':
case '~':
case '?':
+ case ';':
/* Special characters that cant be part of a composite */
return c;
default:
- printf("Unhandled char %c\n", c);
+ error("Unhandled char %c", c);
}
c = GETC();
}
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;
+}