X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.lex;h=e0038cc65202abf5aa30a0557481a7cfa8a14573;hb=3e5db37d509d6ad71df792e58769955068a37266;hp=9288e1fee2bb02ba69b3aa9b55af13f2dbc81848;hpb=fa4545635551d3d5551448b43c116fa21babbe17;p=fw%2Fsdcc diff --git a/src/SDCC.lex b/src/SDCC.lex index 9288e1fe..e0038cc6 100644 --- a/src/SDCC.lex +++ b/src/SDCC.lex @@ -1,6 +1,6 @@ /*----------------------------------------------------------------------- - SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for - 8/16 bit microcontrollers) + SDCC.lex - lexical analyser for use with sdcc (free open source + compiler for 8/16 bit microcontrollers) Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997) This program is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ -------------------------------------------------------------------------*/ D [0-9] -L [a-zA-Z_] +L [a-zA-Z_$] H [a-fA-F0-9] E [Ee][+-]?{D}+ FS (f|F|l|L) @@ -45,19 +45,22 @@ IS (u|U|l|L)* #define TKEYWORD99(token) return (options.std_c99 ? token : check_type()) -extern int lineno, column; extern char *filename; +extern int lineno; +int column = 0; /* current column */ /* global definitions */ -char *currFname; -int mylineno = 1; +char *lexFilename; +int lexLineno = 1; /* local definitions */ -static struct dbuf_s asmbuff; +static struct dbuf_s asmbuff; /* reusable _asm buffer */ /* forward declarations */ -static char *stringLiteral(void); +int yyerror(char *s); +static const char *stringLiteral(void); static void count(void); +static void count_char(int); static int process_pragma(const char *); static int check_type(void); static int isTargetKeyword(const char *s); @@ -70,8 +73,11 @@ _?"_asm" { count(); if (!options.std_sdcc && yytext[1] != '_') return check_type(); - assert(asmbuff.alloc == 0 && asmbuff.len == 0 && asmbuff.buf == NULL); - dbuf_init(&asmbuff, INITIAL_INLINEASM); + if (asmbuff.buf == NULL) + dbuf_init(&asmbuff, INITIAL_INLINEASM); + else + dbuf_set_length(&asmbuff, 0); + BEGIN(asm); } _?"_endasm" { @@ -83,7 +89,6 @@ _?"_asm" { else { yylval.yyinline = dbuf_c_str(&asmbuff); - dbuf_detach(&asmbuff); BEGIN(INITIAL); return (INLINEASM); } @@ -123,7 +128,7 @@ _?"_asm" { "__eeprom" { count(); TKEYWORD(EEPROM); } "float" { count(); return(FLOAT); } "fixed16x16" { count(); TKEYWORDSDCC(FIXED16X16); } -"__fixed16x16" { count(); TKEYWORD(FIXED16X16); } +"__fixed16x16" { count(); TKEYWORD(FIXED16X16); } "flash" { count(); TKEYWORDSDCC(CODE); } "__flash" { count(); TKEYWORD(CODE); } "for" { count(); return(FOR); } @@ -186,7 +191,14 @@ _?"_asm" { "__overlay" { count(); TKEYWORD(OVERLAY); } "inline" { count(); TKEYWORD99(INLINE); } "restrict" { count(); TKEYWORD99(RESTRICT); } -{L}({L}|{D})* { count(); return(check_type()); } +{L}({L}|{D})* { + if (!options.dollars_in_ident && strchr(yytext, '$')) + { + yyerror("stray '$' in program"); + } + count(); + return(check_type()); +} 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); } 0[0-7]*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); } [1-9]{D}*{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); } @@ -195,16 +207,16 @@ _?"_asm" { {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); } {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); } \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL); } -">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); } -"<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); } -"+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); } -"-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); } -"*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); } -"/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); } -"%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); } -"&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); } -"^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); } -"|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); } +">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); } +"<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN); } +"+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN); } +"-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN); } +"*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN); } +"/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN); } +"%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN); } +"&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN); } +"^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN); } +"|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN); } ">>" { count(); return(RIGHT_OP); } "<<" { count(); return(LEFT_OP); } "++" { count(); return(INC_OP); } @@ -250,11 +262,15 @@ _?"_asm" { [ \t\v\f] { count(); } \\ { int ch = input(); - if (ch != '\n') { - /* that could have been removed by the preprocessor anyway */ - werror (W_STRAY_BACKSLASH, column); - unput(ch); - } + + if (ch == '\n') + count_char(ch); + else + { + /* that could have been removed by the preprocessor anyway */ + werror (W_STRAY_BACKSLASH, column); + unput(ch); + } } . { count(); } %% @@ -267,99 +283,110 @@ _?"_asm" { static int checkCurrFile (const char *s) { - int lNum; - char *tptr; + int lNum; + char *tptr; - /* skip '#' character */ - if (*s++ != '#') - return 0; + /* skip '#' character */ + if (*s++ != '#') + return 0; - /* check if this is a #line - this is not standard and can be removed in the future */ + /* check if this is a #line + this is not standard and can be removed in the future */ #define LINE_STR "line" #define LINE_LEN ((sizeof LINE_STR) - 1) - if (strncmp(s, LINE_STR, LINE_LEN) == 0) - s += LINE_LEN; + if (strncmp(s, LINE_STR, LINE_LEN) == 0) + s += LINE_LEN; - /* get the line number */ - lNum = strtol(s, &tptr, 10); - if (tptr == s || !isspace((unsigned char)*tptr)) - return 0; - s = tptr; + /* get the line number */ + lNum = strtol(s, &tptr, 10); + if (tptr == s || !isspace((unsigned char)*tptr)) + return 0; + s = tptr; - /* now see if we have a file name */ - while (*s != '"' && *s) - ++s; + /* adjust the line number */ + lineno = lexLineno = lNum; - /* if we don't have a filename then */ - /* set the current line number to */ - /* line number if printFlag is on */ - if (!*s) { - lineno = mylineno = lNum; + /* now see if we have a file name */ + while (*s != '"' && *s) + ++s; + + if (!*s) + { + /* no file name: return */ return 0; } - /* if we have a filename then check */ - /* if it is "standard in" if yes then */ - /* get the currentfile name info */ - ++s; + /* skip the double quote */ + ++s; - /* in c1mode fullSrcFileName is NULL */ - if (fullSrcFileName && - strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0) { - lineno = mylineno = lNum; - currFname = fullSrcFileName; + /* get the file name and see if it is different from current one. + in c1mode fullSrcFileName is NULL */ + if (fullSrcFileName && + strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"') + { + lexFilename = fullSrcFileName; } - else { + else + { const char *sb = s; + char *tmpFname; - /* find the end of the filename */ + /* find the end of the file name */ while (*s && *s != '"') ++s; - currFname = Safe_malloc(s - sb + 1); - memcpy(currFname, sb, s - sb); - currFname[s - sb] = '\0'; - lineno = mylineno = lNum; + + tmpFname = Safe_malloc(s - sb + 1); + memcpy(tmpFname, sb, s - sb); + tmpFname[s - sb] = '\0'; + + lexFilename = Safe_malloc(s - sb + 1); + copyStr(lexFilename, tmpFname); } - filename = currFname ; - return 0; -} + filename = lexFilename; -int column = 0; -int plineIdx =0; + return 0; +} -static void count(void) +static void count_char(int ch) { - int i; - for (i = 0; yytext[i] != '\0'; i++) { - if (yytext[i] == '\n') { + switch (ch) + { + case '\n': column = 0; - lineno = ++mylineno; + lineno = ++lexLineno; + break; + + case '\t': + column += 8 - (column % 8); + break; + + default: + ++column; + break; } - else - if (yytext[i] == '\t') - column += 8 - (column % 8); - else - column++; - } - /* ECHO; */ +} + +static void count(void) +{ + const char *p; + + for (p = yytext; *p; ++p) + count_char(*p); } static int check_type(void) { symbol *sym = findSym(SymbolTab, NULL, yytext); + strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX); + /* check if it is in the table as a typedef */ if (!ignoreTypedefType && sym && IS_SPEC (sym->etype) - && SPEC_TYPEDEF (sym->etype)) { - strncpyz(yylval.yychar, yytext, SDCC_NAME_MAX); + && SPEC_TYPEDEF (sym->etype)) return (TYPE_NAME); - } - else { - strncpyz (yylval.yychar, yytext, SDCC_NAME_MAX); + else return(IDENTIFIER); - } } /* @@ -367,11 +394,11 @@ static int check_type(void) * to support ANSI hex and octal escape sequences in string literals */ -static char *stringLiteral(void) +static const char *stringLiteral(void) { #define STR_BUF_CHUNCK_LEN 1024 int ch; - static struct dbuf_s dbuf; + static struct dbuf_s dbuf; /* reusable string literal buffer */ if (dbuf.alloc == 0) dbuf_init(&dbuf, STR_BUF_CHUNCK_LEN); @@ -379,135 +406,160 @@ static char *stringLiteral(void) dbuf_set_length(&dbuf, 0); dbuf_append_char(&dbuf, '"'); + /* put into the buffer till we hit the first \" */ - while ((ch = input()) != 0) { - switch (ch) { - case '\\': - /* if it is a \ then escape char's are allowed */ + for (; ; ) + { ch = input(); - if (ch == '\n') { - /* \ is a continuator */ - lineno = ++mylineno; - column = 0; - } - else { - char buf[2]; + count_char(ch); + if (ch == EOF) + break; - buf[0] = '\\'; - buf[1] = ch; - dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */ - } - break; /* carry on */ + switch (ch) + { + case '\\': + /* if it is a \ then escape char's are allowed */ + ch = input(); + count_char(ch); + if (ch == '\n') + { + /* \ is a continuator */ + } + else + { + char buf[2]; - case '\n': - /* if new line we have a new line break, which is illegal */ - werror(W_NEWLINE_IN_STRING); - dbuf_append_char(&dbuf, '\n'); - lineno = ++mylineno; - column = 0; - break; + if (ch == EOF) + goto out; - case '"': - /* 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 */ - dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */ - while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#')) { - switch (ch) { - case '\\': - if ((ch = input()) != '\n') { - werror(W_STRAY_BACKSLASH, column); - unput(ch); - } - else { - lineno = ++mylineno; - column = 0; - } - break; + buf[0] = '\\'; + buf[1] = ch; + dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */ + } + break; /* carry on */ case '\n': - lineno = ++mylineno; - column = 0; + /* if new line we have a new line break, which is illegal */ + werror(W_NEWLINE_IN_STRING); + dbuf_append_char(&dbuf, '\n'); break; - case '#': - if (0 == column) { - /* # at the beginning of the line: collect the entire line */ - struct dbuf_s linebuf; - const char *line; - - dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN); - dbuf_append_char(&linebuf, '#'); - - while ((ch = input()) && ch != '\n') { - dbuf_append_char(&linebuf, (char)ch); + case '"': + /* 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 */ + dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */ + while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#')) + { + switch (ch) + { + case '\\': + count_char(ch); + if ((ch = input()) != '\n') + { + werror(W_STRAY_BACKSLASH, column); + if (ch != EOF) + unput(ch); + else + count_char(ch); + } + else + count_char(ch); + break; + + case '\n': + count_char(ch); + break; + + case '#': + if (column == 0) + { + /* # at the beginning of the line: collect the entire line */ + struct dbuf_s linebuf; + const char *line; + + count_char(ch); + + dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN); + dbuf_append_char(&linebuf, '#'); + + while ((ch = input()) != EOF && ch != '\n') + dbuf_append_char(&linebuf, (char)ch); + + if (ch == '\n') + count_char(ch); + + line = dbuf_c_str(&linebuf); + + /* process the line */ + if (startsWith(line, "#pragma")) + process_pragma(line); + else + checkCurrFile(line); + + dbuf_destroy(&linebuf); + } + else + { + unput(ch); + goto out; + } + + default: + count_char(ch); + break; + } } - if (ch == '\n') { - lineno = ++mylineno; - column = 0; - } - - line = dbuf_c_str(&linebuf); + if (ch == EOF) + goto out; - /* process the line */ - if (startsWith(line, "#pragma")) - process_pragma(line); - else - checkCurrFile(line); + if (ch != '"') + { + unput(ch); + goto out; + } + count_char(ch); + break; - dbuf_destroy(&linebuf); - } + default: + dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */ } - } - - if (!ch) - goto out; - - if (ch != '"') { - unput(ch); - goto out; - } - break; - - default: - dbuf_append_char(&dbuf, (char)ch); /* Put next substring introducer into output string */ } - } out: - return (char *)dbuf_c_str(&dbuf); + return dbuf_c_str(&dbuf); } enum { - P_SAVE = 1, - P_RESTORE, - P_NOINDUCTION, - P_NOINVARIANT, - P_INDUCTION, - P_STACKAUTO, - P_NOJTBOUND, - P_NOOVERLAY, - P_LESSPEDANTIC, - P_NOGCSE, - P_CALLEE_SAVES, - P_EXCLUDE, - P_NOIV, - P_LOOPREV, - P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */ - /* cross-compiling for MINGW32 with gcc 3.2 */ - P_DISABLEWARN, - P_OPTCODESPEED, - P_OPTCODESIZE, - P_OPTCODEBALANCED, - P_STD_C89, - P_STD_C99, - P_STD_SDCC89, - P_STD_SDCC99, - P_CODESEG, - P_CONSTSEG + P_SAVE = 1, + P_RESTORE, + P_NOINDUCTION, + P_NOINVARIANT, + P_INDUCTION, + P_STACKAUTO, + P_NOJTBOUND, + P_NOOVERLAY, + P_LESSPEDANTIC, + P_NOGCSE, + P_CALLEE_SAVES, + P_EXCLUDE, + P_NOIV, + P_LOOPREV, + P_OVERLAY_, /* I had a strange conflict with P_OVERLAY while */ + /* cross-compiling for MINGW32 with gcc 3.2 */ + P_DISABLEWARN, + P_OPTCODESPEED, + P_OPTCODESIZE, + P_OPTCODEBALANCED, + P_STD_C89, + P_STD_C99, + P_STD_SDCC89, + P_STD_SDCC99, + P_CODESEG, + P_CONSTSEG }; @@ -1079,10 +1131,10 @@ int yyerror(char *s) if(options.vc_err_style) fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n", - filename, mylineno, s, yytext, column); + lexFilename, lexLineno, s, yytext, column); else fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n", - filename, mylineno, s ,yytext, column); + lexFilename, lexLineno, s ,yytext, column); fatalError++; return 0;