From 57b5edb25dcb2872d2c3e9789173bc9423959bec Mon Sep 17 00:00:00 2001 From: michaelh Date: Sat, 19 Aug 2000 21:58:54 +0000 Subject: [PATCH] Added alternate lexer git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@326 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/Makefile.in | 19 +- src/SDCCast.c | 2 +- src/SDCCerr.c | 31 +- src/SDCCglue.c | 2 +- src/SDCCmain.c | 10 +- src/SDCCmem.c | 2 +- src/SDCCsymt.c | 3 +- src/altlex.c | 696 ++++++++++++++++++++++++++++++++------------- src/reswords.gperf | 67 +++++ 9 files changed, 611 insertions(+), 221 deletions(-) create mode 100644 src/reswords.gperf diff --git a/src/Makefile.in b/src/Makefile.in index 5fd7f0f6..85e870b1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -6,6 +6,8 @@ PRJDIR = .. include $(PRJDIR)/Makefile.common +USE_ALT_LEX = 0 + PORTS = mcs51 z80 avr ds390 PORT_LIBS = $(PORTS:%=%/port.a) @@ -20,13 +22,21 @@ ifdef SDCC_SUB_VERSION CFLAGS += -DSDCC_SUB_VERSION_STR=\"$(SDCC_SUB_VERSION)\" endif -OBJECTS = SDCCy.o SDCClex.o SDCCerr.o SDCChasht.o SDCCmain.o \ +OBJECTS = SDCCy.o SDCCerr.o SDCChasht.o SDCCmain.o \ SDCCsymt.o SDCCopt.o SDCCast.o SDCCmem.o SDCCval.o \ SDCCicode.o SDCCbitv.o SDCCset.o SDCClabel.o \ SDCCBBlock.o SDCCloop.o SDCCcse.o SDCCcflow.o SDCCdflow.o \ SDCClrange.o SDCCptropt.o SDCCpeeph.o SDCCglue.o spawn.o \ asm.o +SPECIAL = SDCCy.h +ifeq ($(USE_ALT_LEX), 1) +OBJECTS += altlex.o +SPECIAL += reswords.h +else +OBJECTS += SDCClex.o +endif + SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) TARGET = $(PRJDIR)/bin/sdcc @@ -73,7 +83,7 @@ installdirs: # --------------------- dep: Makefile.dep -Makefile.dep: $(SOURCES) *.h $(PRJDIR)/*.h +Makefile.dep: $(SOURCES) $(SPECIAL) *.h $(PRJDIR)/*.h $(CPP) $(CPPFLAGS) $(M_OR_MM) $(SOURCES) >Makefile.dep include Makefile.dep @@ -88,6 +98,11 @@ $(TARGET): $(OBJECTS) $(PORT_LIBS) .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ +reswords.h: reswords.gperf Makefile + gperf -o -k1,2,4 -t -C -N is_reserved_word $< > $@ + +altlex.o: altlex.c SDCCy.h reswords.h + SDCCy.h: SDCCy.c SDCCy.c: SDCC.y diff --git a/src/SDCCast.c b/src/SDCCast.c index bf8f2f60..cfa68e04 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -3639,7 +3639,7 @@ ast *createFunction (symbol *name, ast *body ) addSet(&operKeyReset,name); applyToSet(operKeyReset,resetParmKey); - if (options.debug) + if (options.debug && !options.nodebug) cdbStructBlock(1,cdbFile); cleanUpLevel(LabelTab,0); diff --git a/src/SDCCerr.c b/src/SDCCerr.c index 0ad85971..d2e77054 100644 --- a/src/SDCCerr.c +++ b/src/SDCCerr.c @@ -2,7 +2,7 @@ #include "common.h" -#define USE_STDOUT_FOR_ERRORS 0 +#define USE_STDOUT_FOR_ERRORS 1 #if USE_STDOUT_FOR_ERRORS #define ERRSINK stdout @@ -156,25 +156,28 @@ struct { { WARNING,"warning *** Indirect call to a banked function not implemented.\n"}, { WARNING,"warning *** Model '%s' not supported for %s, ignored.\n"}, { WARNING,"warning *** Both banked and nonbanked attributes used. nonbanked wins.\n"}, -{ WARNING,"warning *** Both banked and static used. static wins.\n"}, +{ WARNING,"warning *** Both banked and static used. static wins.\n"} }; +void vwerror (int errNum, va_list marker) +{ + if ( ErrTab[errNum].errType== ERROR ) + fatalError++ ; + + if ( filename && lineno ) { + fprintf(ERRSINK, "%s(%d):",filename,lineno); + } + vfprintf(ERRSINK, ErrTab[errNum].errText,marker); +} + /****************************************************************************/ /* werror - writes an error to the listing file & to standarderr */ /****************************************************************************/ void werror (int errNum, ... ) { - va_list marker; - - - if ( ErrTab[errNum].errType== ERROR ) - fatalError++ ; - - if ( filename && lineno ) { - fprintf(ERRSINK, "%s(%d):",filename,lineno); - } - va_start(marker,errNum); - vfprintf(ERRSINK, ErrTab[errNum].errText,marker); - va_end( marker ); + va_list marker; + va_start(marker,errNum); + vwerror(errNum, marker); + va_end( marker ); } diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 448034e8..3b329f91 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -1032,7 +1032,7 @@ void glue () addSetHead(&tmpfileSet,ovrFile); /* print the global struct definitions */ - if (options.debug) + if (options.debug && !options.nodebug) cdbStructBlock (0,cdbFile); vFile = tempfile(); diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 66b52605..9f42bb5d 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -118,6 +118,7 @@ char *preOutName; #define OPTION_NOPEEP "-no-peep" #define OPTION_ASMPEEP "-peep-asm" #define OPTION_DEBUG "-debug" +#define OPTION_NODEBUG "-nodebug" #define OPTION_VERSION "-version" #define OPTION_STKAFTRDATA "-stack-after-data" #define OPTION_PREPROC_ONLY "-preprocessonly" @@ -654,6 +655,11 @@ int parseCmdLine ( int argc, char **argv ) continue; } + if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) { + options.nodebug = 1; + continue; + } + if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) { options.noregparms = 1; continue; @@ -1028,7 +1034,7 @@ int parseCmdLine ( int argc, char **argv ) options.xstack_loc = options.xdata_loc ; /* if debug option is set the open the cdbFile */ - if (/* options.debug && */ srcFileName) { + if (!options.nodebug && srcFileName) { sprintf(cdbfnbuf,"%s.cdb",srcFileName); if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL) werror(E_FILE_OPEN_ERR,cdbfnbuf); @@ -1338,7 +1344,7 @@ int main ( int argc, char **argv , char **envp) { /* turn all optimizations off by default */ memset(&optimize,0,sizeof(struct optimize)); - + /*printVersionInfo ();*/ _findPort(argc, argv); diff --git a/src/SDCCmem.c b/src/SDCCmem.c index ca4eff72..b3c8381f 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -865,7 +865,7 @@ void redoStackOffsets () /* if the debug option is set then output the symbols to the map file */ - if (options.debug) { + if (options.debug && !options.nodebug) { for (sym = setFirstItem(istack->syms); sym; sym = setNextItem(istack->syms)) cdbSymbol(sym,cdbFile,FALSE,FALSE); diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 393e3c97..7ef86605 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1846,7 +1846,8 @@ void cdbStructBlock (int block , FILE *of) int i ; bucket **table = StructTab; bucket *chain; - + wassert(of); + /* go thru the entire table */ for ( i = 0 ; i < 256; i++ ) { for ( chain = table[i]; chain ; chain = chain->next ) { diff --git a/src/altlex.c b/src/altlex.c index da1862bd..572826b6 100644 --- a/src/altlex.c +++ b/src/altlex.c @@ -3,8 +3,11 @@ In development - ie messy and just plain wrong. */ #include "common.h" +#include "reswords.h" #include +#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; +} diff --git a/src/reswords.gperf b/src/reswords.gperf new file mode 100644 index 00000000..651d581d --- /dev/null +++ b/src/reswords.gperf @@ -0,0 +1,67 @@ +%{ +/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +%} +struct reserved_words { const char *name; int token; bool is_special; }; +%% +auto, AUTO, 0 +break, BREAK, 0 +case, CASE, 0 +char, CHAR, 0 +const, CONST, 0 +continue, CONTINUE, 0 +default, DEFAULT, 0 +do, DO, 0 +double, FLOAT, 0 +else, ELSE, 0 +enum, ENUM, 0 +extern, EXTERN, 0 +float, FLOAT, 0 +for, FOR, 0 +goto, GOTO, 0 +if, IF, 0 +int, INT, 0 +interrupt, INTERRUPT, 0 +long, LONG, 0 +register, REGISTER, 0 +return, RETURN, 0 +short, SHORT, 0 +signed, SIGNED, 0 +sizeof, SIZEOF, 0 +static, STATIC, 0 +struct, STRUCT, 0 +switch, SWITCH, 0 +typedef, TYPEDEF, 0 +union, UNION, 0 +unsigned, UNSIGNED, 0 +void, VOID, 0 +volatile, VOLATILE, 0 +while, WHILE, 0 +_code, _CODE, 1 +_eeprom, _EEPROM, 1 +_flash, _CODE, 1 +_generic, _GENERIC, 1 +_near, _NEAR, 1 +_sram, _XDATA, 1 +_xdata, _XDATA, 1 +_pdata, _PDATA, 1 +_idata, _IDATA, 1 +at, AT, 1 +bit, BIT, 1 +critical, CRITICAL, 1 +data, DATA, 1 +far, XDATA, 1 +eeprom, EEPROM, 1 +flash, CODE, 1 +idata, IDATA, 1 +nonbanked, NONBANKED, 1 +banked, BANKED, 1 +near, DATA, 1 +pdata, PDATA, 1 +reentrant, REENTRANT, 1 +sfr, SFR, 1 +sbit, SBIT, 1 +sram, XDATA, 1 +using, USING, 1 +code, CODE, 1 +xdata, XDATA, 1 +_data, _NEAR, 1 -- 2.30.2