+
+#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;
+}