X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.lex;h=8d2dc055ce846c7f682e7ab8c05c51b05f4dac92;hb=ff658d790c10b6f7f605f9789a51ea9c902b521f;hp=510981ad443219c2eb18a9f56ff926c4746134a6;hpb=b09af35f2f1cde7649d3ac4a6f5d2af6d97895a0;p=fw%2Fsdcc diff --git a/src/SDCC.lex b/src/SDCC.lex index 510981ad..8d2dc055 100644 --- a/src/SDCC.lex +++ b/src/SDCC.lex @@ -33,23 +33,17 @@ IS (u|U|l|L)* #include #include #include -#include "SDCCglobl.h" -#include "SDCCsymt.h" -#include "SDCCval.h" -#include "SDCCast.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCmem.h" +#include "common.h" +#include "newalloc.h" char *stringLiteral(); char *currFname; -extern int lineno ; +extern int lineno, column; extern char *filename ; extern char *fullSrcFileName ; int yylineno = 1 ; void count() ; -void comment(); int process_pragma(char *); #undef yywrap @@ -57,10 +51,13 @@ int yywrap YY_PROTO((void)) { return(1); } - -char asmbuff[MAX_INLINEASM] ; +#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\ + check_type(yytext)) +char *asmbuff=NULL; +int asmbuffSize=0; char *asmp ; -extern int check_type ( ); +extern int check_type (); + extern int isTargetKeyword (); extern int checkCurrFile (char *); extern int processPragma (char *); extern int printListing (int ); @@ -85,51 +82,82 @@ struct options save_options ; %} %x asm %% -"_asm" { count(); asmp = asmbuff ;BEGIN(asm) ;} -"_endasm" { count() ; - *asmp = '\0' ; - strcpy(yylval.yyinline,asmbuff) ; - BEGIN(INITIAL) ; - return (INLINEASM) ; } -. { *asmp++ = yytext[0] ; } -\n { count(); *asmp++ = '\n' ;} -"/*" { comment(); } -"at" { count(); return(AT) ; } -"auto" { count(); return(AUTO); } -"bit" { count(); return(BIT) ; } -"break" { count(); return(BREAK); } -"case" { count(); return(CASE); } +"_asm" { + count(); + asmp = asmbuff = Safe_realloc (asmbuff, INITIAL_INLINEASM); + asmbuffSize=INITIAL_INLINEASM; + BEGIN(asm) ; +} +"_endasm" { + count(); + *asmp = '\0'; + yylval.yyinline = Safe_calloc (1, strlen(asmbuff)+1); + strcpy(yylval.yyinline,asmbuff); + BEGIN(INITIAL); + return (INLINEASM); +} +. { + if (asmp-asmbuff >= asmbuffSize-2) { + // increase the buffersize with 50% + int size=asmp-asmbuff; + asmbuffSize=asmbuffSize*3/2; + asmbuff = Safe_realloc (asmbuff, asmbuffSize); + asmp=asmbuff+size; + } + *asmp++ = yytext[0]; +} +\n { + count(); + if (asmp-asmbuff >= asmbuffSize-3) { + // increase the buffersize with 50% + int size=asmp-asmbuff; + asmbuffSize=asmbuffSize*3/2; + asmbuff = Safe_realloc (asmbuff, asmbuffSize); + asmp=asmbuff+size; + } + *asmp++ = '\n' ; +} +"at" { count(); TKEYWORD(AT) ; } +"auto" { count(); return(AUTO); } +"bit" { count(); TKEYWORD(BIT) ; } +"break" { count(); return(BREAK); } +"case" { count(); return(CASE); } "char" { count(); return(CHAR); } -"code" { count(); return(CODE); } +"code" { count(); TKEYWORD(CODE); } "const" { count(); return(CONST); } "continue" { count(); return(CONTINUE); } -"critical" { count(); return(CRITICAL); } -"data" { count(); return(DATA); } +"critical" { count(); TKEYWORD(CRITICAL); } +"data" { count(); TKEYWORD(DATA); } "default" { count(); return(DEFAULT); } "do" { count(); return(DO); } "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); } "else" { count(); return(ELSE); } "enum" { count(); return(ENUM); } "extern" { count(); return(EXTERN); } -"far" { count(); return(XDATA); } +"far" { count(); TKEYWORD(XDATA); } +"eeprom" { count(); TKEYWORD(EEPROM); } "float" { count(); return(FLOAT); } +"flash" { count(); TKEYWORD(CODE);} "for" { count(); return(FOR); } "goto" { count(); return(GOTO); } -"idata" { count(); return(IDATA);} +"idata" { count(); TKEYWORD(IDATA);} "if" { count(); return(IF); } "int" { count(); return(INT); } "interrupt" { count(); return(INTERRUPT);} +"nonbanked" { count(); TKEYWORD(NONBANKED);} +"banked" { count(); TKEYWORD(BANKED);} "long" { count(); return(LONG); } -"near" { count(); return(DATA);} -"pdata" { count(); return(PDATA); } -"reentrant" { count(); return(REENTRANT);} +"near" { count(); TKEYWORD(DATA);} +"pdata" { count(); TKEYWORD(PDATA); } +"reentrant" { count(); TKEYWORD(REENTRANT);} "register" { count(); return(REGISTER); } "return" { count(); return(RETURN); } -"sfr" { count(); return(SFR) ; } -"sbit" { count(); return(SBIT) ; } +"sfr" { count(); TKEYWORD(SFR) ; } +"sbit" { count(); TKEYWORD(SBIT) ; } "short" { count(); return(SHORT); } "signed" { count(); return(SIGNED); } "sizeof" { count(); return(SIZEOF); } +"sram" { count(); TKEYWORD(XDATA);} "static" { count(); return(STATIC); } "struct" { count(); return(STRUCT); } "switch" { count(); return(SWITCH); } @@ -138,17 +166,11 @@ struct options save_options ; "unsigned" { count(); return(UNSIGNED); } "void" { count(); return(VOID); } "volatile" { count(); return(VOLATILE); } -"using" { count(); return(USING); } +"using" { count(); TKEYWORD(USING); } +"_naked" { count(); TKEYWORD(NAKED); } "while" { count(); return(WHILE); } -"xdata" { count(); return(XDATA); } -"_data" { count(); return(_NEAR); } -"_code" { count(); return(_CODE); } -"_generic" { count(); return(_GENERIC); } -"_near" { count(); return(_NEAR); } -"_xdata" { count(); return(_XDATA);} -"_pdata" { count () ; return(_PDATA); } -"_idata" { count () ; return(_IDATA); } -"..." { count(); return(VAR_ARGS);} +"xdata" { count(); TKEYWORD(XDATA); } +"..." { count(); return(VAR_ARGS);} {L}({L}|{D})* { count(); return(check_type()); } 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); } 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); } @@ -180,8 +202,8 @@ struct options save_options ; "==" { count(); return(EQ_OP); } "!=" { count(); return(NE_OP); } ";" { count(); return(';'); } -"{" { count() ; NestLevel++ ; return('{'); } -"}" { count(); NestLevel--; return('}'); } +"{" { count(); NestLevel++ ; return('{'); } +"}" { count(); NestLevel--; return('}'); } "," { count(); return(','); } ":" { count(); return(':'); } "=" { count(); return('='); } @@ -211,6 +233,14 @@ struct options save_options ; "\r\n" { count(); } "\n" { count(); } [ \t\v\f] { count(); } +\\ { + char ch=input(); + if (ch!='\n') { + // that could have been removed by the preprocessor anyway + werror (W_STRAY_BACKSLASH, column); + unput(ch); + } +} . { count() ; } %% @@ -241,8 +271,8 @@ int checkCurrFile ( char *s) /* set the current line number to */ /* line number if printFlag is on */ if (!*s) { - yylineno = lNum ; - return 0; + lineno = yylineno = lNum ; + return 0; } /* if we have a filename then check */ @@ -251,61 +281,39 @@ int checkCurrFile ( char *s) s++ ; if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) { - yylineno = lNum - 2; - currFname = fullSrcFileName ; + lineno = yylineno = lNum; + currFname = fullSrcFileName ; } else { char *sb = s; /* mark the end of the filename */ while (*s != '"') s++; *s = '\0'; - ALLOC_ATOMIC(currFname,strlen(sb)+1); + currFname = Safe_calloc(1,strlen(sb)+1); strcpy(currFname,sb); - yylineno = lNum - 2; + lineno = yylineno = lNum; } filename = currFname ; return 0; } -void comment() -{ - char c, c1; - -loop: - while ((c = input()) != '*' && c != 0) - if ( c == '\n') - yylineno++ ; - - if ((c1 = input()) != '/' && c != 0) { - if ( c1 == '\n' ) - yylineno++ ; - - unput(c1); - goto loop; - } - -} - - - int column = 0; int plineIdx=0; void count() { - int i; - for (i = 0; yytext[i] != '\0'; i++) { - if (yytext[i] == '\n') { - column = 0; - lineno = ++yylineno ; - } - else - if (yytext[i] == '\t') - column += 8 - (column % 8); - else - column++; - } - - /* ECHO; */ + int i; + for (i = 0; yytext[i] != '\0'; i++) { + if (yytext[i] == '\n') { + column = 0; + lineno = ++yylineno ; + } + else + if (yytext[i] == '\t') + column += 8 - (column % 8); + else + column++; + } + /* ECHO; */ } int check_type() @@ -321,49 +329,84 @@ int check_type() } } -char strLitBuff[2048] ; +char strLitBuff[2048]; // TODO: this is asking for the next bug :) -char *stringLiteral () -{ - int ch; - char *str = strLitBuff ; - - *str++ = '\"' ; - /* put into the buffer till we hit the */ - /* first \" */ - while (1) { - - ch = input() ; - if (!ch) break ; /* end of input */ - /* if it is a \ then everything allowed */ - if (ch == '\\') { - *str++ = ch ; /* backslash in place */ - *str++ = input() ; /* following char in place */ - continue ; /* carry on */ - } - - /* if new line we have a new line break */ - if (ch == '\n') break ; - - /* 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 */ - if (ch == '\"') { - - while ((ch = input()) && isspace(ch)) ; - if (!ch) break ; - if (ch != '\"') { - unput(ch) ; - break ; - } - - continue ; - } - *str++ = ch; - } - *str++ = '\"' ; - *str = '\0'; - return strLitBuff ; +/* + * Change by JTV 2001-05-19 to not concantenate strings + * to support ANSI hex and octal escape sequences in string liteals + */ + +char *stringLiteral () { + int ch; + char *str = strLitBuff; + + *str++ = '\"'; + /* put into the buffer till we hit the first \" */ + + while (1) { + ch = input(); + + if (!ch) + break; /* end of input */ + + /* if it is a \ then escape char's are allowed */ + if (ch == '\\') { + ch=input(); + if (ch=='\n') { + /* \ is a continuator */ + lineno=++yylineno; + column=0; + continue; + } + *str++ = '\\'; /* backslash in place */ + *str++ = ch; /* get the escape char, no further check */ + continue; /* carry on */ + } + + /* if new line we have a new line break, which is illegal */ + if (ch == '\n') { + werror (W_NEWLINE_IN_STRING); + *str++ = '\n'; + lineno=++yylineno; + column=0; + continue; + } + + /* 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 */ + if (ch == '\"') { + *str++ = ch ; /* Pass end of this string or substring to evaluator */ + while ((ch = input()) && (isspace(ch) || ch=='\\')) { + switch (ch) { + case '\\': + if ((ch=input())!='\n') { + werror (W_STRAY_BACKSLASH, column); + unput(ch); + } else { + lineno=++yylineno; + column=0; + } + break; + case '\n': + yylineno++; + break; + } + } + + if (!ch) + break; + + if (ch != '\"') { + unput(ch) ; + break ; + } + } + *str++ = ch; /* Put next substring introducer into output string */ + } + *str = '\0'; + + return strLitBuff; } void doPragma (int op, char *cp) @@ -433,6 +476,10 @@ int process_pragma(char *s) (*s != '\n')) s++ ; + /* First give the port a chance */ + if (port->process_pragma && !port->process_pragma(cp)) + return 0; + /* now compare and do what needs to be done */ if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) { doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE)); @@ -490,10 +537,40 @@ int process_pragma(char *s) } if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) { - doPragma(P_EXCLUDE,NULL); + doPragma(P_LOOPREV,NULL); return 0; } werror(W_UNKNOWN_PRAGMA,cp); return 0; } + +/* will return 1 if the string is a part + of a target specific keyword */ +int isTargetKeyword(char *s) +{ + int i; + + if (port->keywords == NULL) + return 0; + for ( i = 0 ; port->keywords[i] ; i++ ) { + if (strcmp(port->keywords[i],s) == 0) + return 1; + } + + return 0; +} + +extern int fatalError; + +int yyerror(char *s) +{ + fflush(stdout); + + if (yylineno && filename) + fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n", + filename,yylineno, + s,yytext,column); + fatalError++; + return 0; +}