X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.lex;h=0fc43d00445ed1bd3f5881bb047b091f04423282;hb=870a9fb183ba31e7c17b253cd859cf1c6c886c2a;hp=dd63429d7544e33de27569836909804ad00309fe;hpb=e456a4dd52fdd0d4ab33f935beb10ecad22d9e44;p=fw%2Fsdcc diff --git a/src/SDCC.lex b/src/SDCC.lex index dd63429d..0fc43d00 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 @@ -22,8 +22,9 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ +B [0-1] 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 +46,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; /* reusable _asm buffer */ /* forward declarations */ +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); @@ -188,7 +192,23 @@ _?"_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[bB]{B}+{IS}? { + if (!options.std_sdcc) + { + yyerror("binary (0b) constants are not allowed in ISO C"); + } + count(); + yylval.val = constVal(yytext); + return(CONSTANT); +} 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); } @@ -253,13 +273,14 @@ _?"_asm" { \\ { int ch = input(); - ++column; - if (ch != '\n') { - /* that could have been removed by the preprocessor anyway */ - werror (W_STRAY_BACKSLASH, column); - unput(ch); - --column; - } + if (ch == '\n') + count_char(ch); + else + { + /* that could have been removed by the preprocessor anyway */ + werror (W_STRAY_BACKSLASH, column); + unput(ch); + } } . { count(); } %% @@ -272,15 +293,15 @@ _?"_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) @@ -293,66 +314,75 @@ static int checkCurrFile (const char *s) return 0; s = tptr; + /* adjust the line number */ + lineno = lexLineno = lNum; + /* now see if we have a file name */ while (*s != '"' && *s) ++s; - /* 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; - return 0; - } + 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 */ + /* skip the double quote */ ++s; - /* in c1mode fullSrcFileName is NULL */ + /* 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) + strncmp(s, fullSrcFileName, strlen(fullSrcFileName)) == 0 && fullSrcFileName[strlen(fullSrcFileName) - 1] == '"') { - lineno = mylineno = lNum; - currFname = fullSrcFileName; + lexFilename = fullSrcFileName; } 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; + filename = lexFilename; + return 0; } -int column = 0; -int plineIdx =0; - -static void count(void) +static void count_char(int ch) { - int i; - for (i = 0; yytext[i] != '\0'; i++) + switch (ch) { - if (yytext[i] == '\n') - { - column = 0; - lineno = ++mylineno; - } - else - if (yytext[i] == '\t') - column += 8 - (column % 8); - else - column++; + case '\n': + column = 0; + lineno = ++lexLineno; + break; + + case '\t': + column += 8 - (column % 8); + break; + + default: + ++column; + break; } - /* ECHO; */ +} + +static void count(void) +{ + const char *p; + + for (p = yytext; *p; ++p) + count_char(*p); } static int check_type(void) @@ -363,7 +393,7 @@ static int check_type(void) /* check if it is in the table as a typedef */ if (!ignoreTypedefType && sym && IS_SPEC (sym->etype) - && SPEC_TYPEDEF (sym->etype)) + && SPEC_TYPEDEF (sym->etype) && findSym(TypedefTab, NULL, yytext)) return (TYPE_NAME); else return(IDENTIFIER); @@ -392,7 +422,7 @@ static const char *stringLiteral(void) for (; ; ) { ch = input(); - ++column; + count_char(ch); if (ch == EOF) break; @@ -400,11 +430,11 @@ static const char *stringLiteral(void) { case '\\': /* if it is a \ then escape char's are allowed */ - if ((ch = input()) == '\n') + ch = input(); + count_char(ch); + if (ch == '\n') { /* \ is a continuator */ - lineno = ++mylineno; - column = 0; } else { @@ -413,7 +443,6 @@ static const char *stringLiteral(void) if (ch == EOF) goto out; - ++column; buf[0] = '\\'; buf[1] = ch; dbuf_append(&dbuf, buf, 2); /* get the escape char, no further check */ @@ -424,8 +453,6 @@ static const char *stringLiteral(void) /* 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; case '"': @@ -435,31 +462,24 @@ static const char *stringLiteral(void) dbuf_append_char(&dbuf, '"'); /* Pass end of this string or substring to evaluator */ while ((ch = input()) && (isspace(ch) || ch == '\\' || ch == '#')) { - ++column; - switch (ch) { case '\\': + count_char(ch); if ((ch = input()) != '\n') { - ++column; werror(W_STRAY_BACKSLASH, column); if (ch != EOF) - { - unput(ch); - --column; - } + unput(ch); + else + count_char(ch); } - else - { - lineno = ++mylineno; - column = 0; - } - break; + else + count_char(ch); + break; case '\n': - lineno = ++mylineno; - column = 0; + count_char(ch); break; case '#': @@ -469,6 +489,8 @@ static const char *stringLiteral(void) struct dbuf_s linebuf; const char *line; + count_char(ch); + dbuf_init(&linebuf, STR_BUF_CHUNCK_LEN); dbuf_append_char(&linebuf, '#'); @@ -476,10 +498,7 @@ static const char *stringLiteral(void) dbuf_append_char(&linebuf, (char)ch); if (ch == '\n') - { - lineno = ++mylineno; - column = 0; - } + count_char(ch); line = dbuf_c_str(&linebuf); @@ -491,6 +510,15 @@ static const char *stringLiteral(void) dbuf_destroy(&linebuf); } + else + { + unput(ch); + goto out; + } + + default: + count_char(ch); + break; } } @@ -500,9 +528,9 @@ static const char *stringLiteral(void) if (ch != '"') { unput(ch); - --column; goto out; } + count_char(ch); break; default: @@ -1113,10 +1141,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;