Added alternate lexer
[fw/sdcc] / src / altlex.c
index da1862bdf97880e4579965a903d056f84a7c203e..572826b6edc2b1a4e07de233756cf5d700debb8d 100644 (file)
@@ -3,8 +3,11 @@
     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;
@@ -48,6 +51,27 @@ char linebuf[10000];
 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)
 {
@@ -81,7 +105,7 @@ static int INLINE yungetc(int c)
 #define ISALNUM(_a)    isalnum(_a)
 #define ISHEX(_a)      isalnum(_a)
 
-char *stringLiteral (void)
+static char *stringLiteral (void)
 {
     static char line[1000];
     int ch;
@@ -125,7 +149,7 @@ char *stringLiteral (void)
     return line;
 }
 
-void discard_comments(int type)
+static void discard_comments(int type)
 {
     int c;
     if (type == '*') {
@@ -141,217 +165,52 @@ void discard_comments(int 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];
@@ -429,8 +288,27 @@ int yylex(void)
            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();
@@ -449,9 +327,108 @@ int yylex(void)
        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;
@@ -467,19 +444,340 @@ int yylex(void)
                }
            }
            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;
+}