1 /*-----------------------------------------------------------------------
2 SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
3 8/16 bit microcontrollers)
4 Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
39 char *stringLiteral();
43 extern char *filename ;
44 extern char *fullSrcFileName ;
48 int process_pragma(char *);
51 int yywrap YY_PROTO((void))
55 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
60 extern int check_type ();
61 extern int isTargetKeyword ();
62 extern int checkCurrFile (char *);
63 extern int processPragma (char *);
64 extern int printListing (int );
65 struct optimize save_optimize ;
66 struct options save_options ;
88 asmp = asmbuff = Safe_realloc (asmbuff, INITIAL_INLINEASM);
89 asmbuffSize=INITIAL_INLINEASM;
95 yylval.yyinline = Safe_calloc (1, strlen(asmbuff)+1);
96 strcpy(yylval.yyinline,asmbuff);
101 if (asmp-asmbuff >= asmbuffSize-2) {
102 // increase the buffersize with 50%
103 int size=asmp-asmbuff;
104 asmbuffSize=asmbuffSize*3/2;
105 asmbuff = Safe_realloc (asmbuff, asmbuffSize);
112 if (asmp-asmbuff >= asmbuffSize-3) {
113 // increase the buffersize with 50%
114 int size=asmp-asmbuff;
115 asmbuffSize=asmbuffSize*3/2;
116 asmbuff = Safe_realloc (asmbuff, asmbuffSize);
122 "at" { count(); TKEYWORD(AT) ; }
123 "auto" { count(); return(AUTO); }
124 "bit" { count(); TKEYWORD(BIT) ; }
125 "break" { count(); return(BREAK); }
126 "case" { count(); return(CASE); }
127 "char" { count(); return(CHAR); }
128 "code" { count(); TKEYWORD(CODE); }
129 "const" { count(); return(CONST); }
130 "continue" { count(); return(CONTINUE); }
131 "critical" { count(); TKEYWORD(CRITICAL); }
132 "data" { count(); TKEYWORD(DATA); }
133 "default" { count(); return(DEFAULT); }
134 "do" { count(); return(DO); }
135 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
136 "else" { count(); return(ELSE); }
137 "enum" { count(); return(ENUM); }
138 "extern" { count(); return(EXTERN); }
139 "far" { count(); TKEYWORD(XDATA); }
140 "eeprom" { count(); TKEYWORD(EEPROM); }
141 "float" { count(); return(FLOAT); }
142 "flash" { count(); TKEYWORD(CODE);}
143 "for" { count(); return(FOR); }
144 "goto" { count(); return(GOTO); }
145 "idata" { count(); TKEYWORD(IDATA);}
146 "if" { count(); return(IF); }
147 "int" { count(); return(INT); }
148 "interrupt" { count(); return(INTERRUPT);}
149 "nonbanked" { count(); TKEYWORD(NONBANKED);}
150 "banked" { count(); TKEYWORD(BANKED);}
151 "long" { count(); return(LONG); }
152 "near" { count(); TKEYWORD(DATA);}
153 "pdata" { count(); TKEYWORD(PDATA); }
154 "reentrant" { count(); TKEYWORD(REENTRANT);}
155 "register" { count(); return(REGISTER); }
156 "return" { count(); return(RETURN); }
157 "sfr" { count(); TKEYWORD(SFR) ; }
158 "sbit" { count(); TKEYWORD(SBIT) ; }
159 "short" { count(); return(SHORT); }
160 "signed" { count(); return(SIGNED); }
161 "sizeof" { count(); return(SIZEOF); }
162 "sram" { count(); TKEYWORD(XDATA);}
163 "static" { count(); return(STATIC); }
164 "struct" { count(); return(STRUCT); }
165 "switch" { count(); return(SWITCH); }
166 "typedef" { count(); return(TYPEDEF); }
167 "union" { count(); return(UNION); }
168 "unsigned" { count(); return(UNSIGNED); }
169 "void" { count(); return(VOID); }
170 "volatile" { count(); return(VOLATILE); }
171 "using" { count(); TKEYWORD(USING); }
172 "while" { count(); return(WHILE); }
173 "xdata" { count(); TKEYWORD(XDATA); }
174 "_data" { count(); TKEYWORD(_NEAR); }
175 "_code" { count(); TKEYWORD(_CODE); }
176 "_eeprom" { count(); TKEYWORD(_EEPROM); }
177 "_flash" { count(); TKEYWORD(_CODE); }
178 "_generic" { count(); TKEYWORD(_GENERIC); }
179 "_near" { count(); TKEYWORD(_NEAR); }
180 "_sram" { count(); TKEYWORD(_XDATA);}
181 "_xdata" { count(); TKEYWORD(_XDATA);}
182 "_pdata" { count(); TKEYWORD(_PDATA); }
183 "_idata" { count(); TKEYWORD(_IDATA); }
184 "..." { count(); return(VAR_ARGS);}
185 {L}({L}|{D})* { count(); return(check_type()); }
186 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
187 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
188 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
189 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
190 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
191 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
192 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
193 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
194 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
195 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
196 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
197 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
198 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
199 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
200 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
201 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
202 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
203 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
204 ">>" { count(); return(RIGHT_OP); }
205 "<<" { count(); return(LEFT_OP); }
206 "++" { count(); return(INC_OP); }
207 "--" { count(); return(DEC_OP); }
208 "->" { count(); return(PTR_OP); }
209 "&&" { count(); return(AND_OP); }
210 "||" { count(); return(OR_OP); }
211 "<=" { count(); return(LE_OP); }
212 ">=" { count(); return(GE_OP); }
213 "==" { count(); return(EQ_OP); }
214 "!=" { count(); return(NE_OP); }
215 ";" { count(); return(';'); }
216 "{" { count(); NestLevel++ ; return('{'); }
217 "}" { count(); NestLevel--; return('}'); }
218 "," { count(); return(','); }
219 ":" { count(); return(':'); }
220 "=" { count(); return('='); }
221 "(" { count(); return('('); }
222 ")" { count(); return(')'); }
223 "[" { count(); return('['); }
224 "]" { count(); return(']'); }
225 "." { count(); return('.'); }
226 "&" { count(); return('&'); }
227 "!" { count(); return('!'); }
228 "~" { count(); return('~'); }
229 "-" { count(); return('-'); }
230 "+" { count(); return('+'); }
231 "*" { count(); return('*'); }
232 "/" { count(); return('/'); }
233 "%" { count(); return('%'); }
234 "<" { count(); return('<'); }
235 ">" { count(); return('>'); }
236 "^" { count(); return('^'); }
237 "|" { count(); return('|'); }
238 "?" { count(); return('?'); }
239 ^#line.*"\n" { count(); checkCurrFile(yytext); }
240 ^#pragma.*"\n" { count(); process_pragma(yytext); }
242 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
243 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
246 [ \t\v\f] { count(); }
250 int checkCurrFile ( char *s)
256 /* first check if this is a #line */
257 if ( strncmp(s,"#line",5) )
260 /* get to the line number */
267 sscanf(lineNum,"%d",&lNum);
269 /* now see if we have a file name */
270 while (*s != '\"' && *s)
273 /* if we don't have a filename then */
274 /* set the current line number to */
275 /* line number if printFlag is on */
281 /* if we have a filename then check */
282 /* if it is "standard in" if yes then */
283 /* get the currentfile name info */
286 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
288 currFname = fullSrcFileName ;
291 /* mark the end of the filename */
292 while (*s != '"') s++;
294 currFname = Safe_calloc(1,strlen(sb)+1);
295 strcpy(currFname,sb);
298 filename = currFname ;
307 while ((c = input()) != '*' && c != 0)
311 if ((c1 = input()) != '/' && c != 0) {
329 for (i = 0; yytext[i] != '\0'; i++) {
330 if (yytext[i] == '\n') {
332 lineno = ++yylineno ;
335 if (yytext[i] == '\t')
336 column += 8 - (column % 8);
346 /* check if it is in the typedef table */
347 if (findSym(TypedefTab,NULL,yytext)) {
348 strcpy(yylval.yychar,yytext);
352 strcpy (yylval.yychar,yytext);
357 char strLitBuff[2048] ;
360 * Change by JTV 2001-05-19 to not concantenate strings
361 * to support ANSI hex and octal escape sequences in string liteals
364 char *stringLiteral ()
368 char *str = strLitBuff ;
371 /* put into the buffer till we hit the */
379 break ; /* end of input */
381 /* if it is a \ then everything allowed */
385 *str++ = ch ; /* backslash in place */
386 *str++ = input() ; /* following char in place */
387 continue ; /* carry on */
390 /* if new line we have a new line break */
394 /* if this is a quote then we have work to do */
395 /* find the next non whitespace character */
396 /* if that is a double quote then carry on */
400 *str++ = ch ; /* Pass end of this string or substring to evaluator */
402 while ((ch = input()) && isspace(ch)) ;
414 *str++ = ch; /* Put next substring introducer into output string */
422 void doPragma (int op, char *cp)
426 memcpy(&save_options,&options,sizeof(options));
427 memcpy(&save_optimize,&optimize,sizeof(optimize));
430 memcpy(&options,&save_options,sizeof(options));
431 memcpy(&optimize,&save_optimize,sizeof(optimize));
434 optimize.loopInduction = 0 ;
437 optimize.loopInvariant = 0 ;
440 optimize.loopInduction = 1 ;
443 options.stackAuto = 1;
446 optimize.noJTabBoundary = 1;
449 optimize.global_cse = 0;
452 options.noOverlay = 1;
457 /* append to the functions already listed
459 for (; options.calleeSaves[i] ;i++);
460 parseWithComma(&options.calleeSaves[i],strdup(cp));
464 parseWithComma(options.excludeRegs,strdup(cp));
467 optimize.noLoopReverse = 1;
472 int process_pragma(char *s)
475 /* find the pragma */
476 while (strncmp(s,"#pragma",7))
480 /* look for the directive */
481 while(isspace(*s)) s++;
484 /* look for the end of the directive */
485 while ((! isspace(*s)) &&
489 /* First give the port a chance */
490 if (port->process_pragma && !port->process_pragma(cp))
493 /* now compare and do what needs to be done */
494 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
495 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
499 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
500 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
504 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
505 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
509 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
510 doPragma (P_NOINVARIANT,NULL) ;
514 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
515 doPragma (P_INDUCTION,NULL) ;
519 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
520 doPragma (P_STACKAUTO,NULL);
524 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
525 doPragma (P_NOJTBOUND,NULL);
529 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
530 doPragma (P_NOGCSE,NULL);
534 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
535 doPragma (P_NOOVERLAY,NULL);
539 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
540 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
544 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
545 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
549 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
550 doPragma(P_EXCLUDE,NULL);
554 werror(W_UNKNOWN_PRAGMA,cp);
558 /* will return 1 if the string is a part
559 of a target specific keyword */
560 int isTargetKeyword(char *s)
564 if (port->keywords == NULL)
566 for ( i = 0 ; port->keywords[i] ; i++ ) {
567 if (strcmp(port->keywords[i],s) == 0)
574 extern int fatalError;
580 if (yylineno && filename)
581 fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",