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 "_naked" { count(); TKEYWORD(NAKED); }
173 "while" { count(); return(WHILE); }
174 "xdata" { count(); TKEYWORD(XDATA); }
175 "_data" { count(); TKEYWORD(_NEAR); }
176 "_code" { count(); TKEYWORD(_CODE); }
177 "_eeprom" { count(); TKEYWORD(_EEPROM); }
178 "_flash" { count(); TKEYWORD(_CODE); }
179 "_generic" { count(); TKEYWORD(_GENERIC); }
180 "_near" { count(); TKEYWORD(_NEAR); }
181 "_sram" { count(); TKEYWORD(_XDATA);}
182 "_xdata" { count(); TKEYWORD(_XDATA);}
183 "_pdata" { count(); TKEYWORD(_PDATA); }
184 "_idata" { count(); TKEYWORD(_IDATA); }
185 "..." { count(); return(VAR_ARGS);}
186 {L}({L}|{D})* { count(); return(check_type()); }
187 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
188 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
189 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
190 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
191 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
192 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
193 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
194 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
195 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
196 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
197 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
198 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
199 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
200 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
201 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
202 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
203 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
204 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
205 ">>" { count(); return(RIGHT_OP); }
206 "<<" { count(); return(LEFT_OP); }
207 "++" { count(); return(INC_OP); }
208 "--" { count(); return(DEC_OP); }
209 "->" { count(); return(PTR_OP); }
210 "&&" { count(); return(AND_OP); }
211 "||" { count(); return(OR_OP); }
212 "<=" { count(); return(LE_OP); }
213 ">=" { count(); return(GE_OP); }
214 "==" { count(); return(EQ_OP); }
215 "!=" { count(); return(NE_OP); }
216 ";" { count(); return(';'); }
217 "{" { count(); NestLevel++ ; return('{'); }
218 "}" { count(); NestLevel--; 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 "?" { count(); return('?'); }
240 ^#line.*"\n" { count(); checkCurrFile(yytext); }
241 ^#pragma.*"\n" { count(); process_pragma(yytext); }
243 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
244 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
247 [ \t\v\f] { count(); }
251 int checkCurrFile ( char *s)
257 /* first check if this is a #line */
258 if ( strncmp(s,"#line",5) )
261 /* get to the line number */
268 sscanf(lineNum,"%d",&lNum);
270 /* now see if we have a file name */
271 while (*s != '\"' && *s)
274 /* if we don't have a filename then */
275 /* set the current line number to */
276 /* line number if printFlag is on */
282 /* if we have a filename then check */
283 /* if it is "standard in" if yes then */
284 /* get the currentfile name info */
287 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
289 currFname = fullSrcFileName ;
292 /* mark the end of the filename */
293 while (*s != '"') s++;
295 currFname = Safe_calloc(1,strlen(sb)+1);
296 strcpy(currFname,sb);
299 filename = currFname ;
308 while ((c = input()) != '*' && c != 0)
312 if ((c1 = input()) != '/' && c != 0) {
330 for (i = 0; yytext[i] != '\0'; i++) {
331 if (yytext[i] == '\n') {
333 lineno = ++yylineno ;
336 if (yytext[i] == '\t')
337 column += 8 - (column % 8);
347 /* check if it is in the typedef table */
348 if (findSym(TypedefTab,NULL,yytext)) {
349 strcpy(yylval.yychar,yytext);
353 strcpy (yylval.yychar,yytext);
358 char strLitBuff[2048] ;
361 * Change by JTV 2001-05-19 to not concantenate strings
362 * to support ANSI hex and octal escape sequences in string liteals
365 char *stringLiteral ()
369 char *str = strLitBuff ;
372 /* put into the buffer till we hit the */
380 break ; /* end of input */
382 /* if it is a \ then everything allowed */
386 *str++ = ch ; /* backslash in place */
387 *str++ = input() ; /* following char in place */
388 continue ; /* carry on */
391 /* if new line we have a new line break */
395 /* if this is a quote then we have work to do */
396 /* find the next non whitespace character */
397 /* if that is a double quote then carry on */
401 *str++ = ch ; /* Pass end of this string or substring to evaluator */
403 while ((ch = input()) && isspace(ch)) ;
415 *str++ = ch; /* Put next substring introducer into output string */
423 void doPragma (int op, char *cp)
427 memcpy(&save_options,&options,sizeof(options));
428 memcpy(&save_optimize,&optimize,sizeof(optimize));
431 memcpy(&options,&save_options,sizeof(options));
432 memcpy(&optimize,&save_optimize,sizeof(optimize));
435 optimize.loopInduction = 0 ;
438 optimize.loopInvariant = 0 ;
441 optimize.loopInduction = 1 ;
444 options.stackAuto = 1;
447 optimize.noJTabBoundary = 1;
450 optimize.global_cse = 0;
453 options.noOverlay = 1;
458 /* append to the functions already listed
460 for (; options.calleeSaves[i] ;i++);
461 parseWithComma(&options.calleeSaves[i],strdup(cp));
465 parseWithComma(options.excludeRegs,strdup(cp));
468 optimize.noLoopReverse = 1;
473 int process_pragma(char *s)
476 /* find the pragma */
477 while (strncmp(s,"#pragma",7))
481 /* look for the directive */
482 while(isspace(*s)) s++;
485 /* look for the end of the directive */
486 while ((! isspace(*s)) &&
490 /* First give the port a chance */
491 if (port->process_pragma && !port->process_pragma(cp))
494 /* now compare and do what needs to be done */
495 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
496 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
500 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
501 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
505 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
506 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
510 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
511 doPragma (P_NOINVARIANT,NULL) ;
515 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
516 doPragma (P_INDUCTION,NULL) ;
520 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
521 doPragma (P_STACKAUTO,NULL);
525 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
526 doPragma (P_NOJTBOUND,NULL);
530 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
531 doPragma (P_NOGCSE,NULL);
535 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
536 doPragma (P_NOOVERLAY,NULL);
540 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
541 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
545 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
546 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
550 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
551 doPragma(P_EXCLUDE,NULL);
555 werror(W_UNKNOWN_PRAGMA,cp);
559 /* will return 1 if the string is a part
560 of a target specific keyword */
561 int isTargetKeyword(char *s)
565 if (port->keywords == NULL)
567 for ( i = 0 ; port->keywords[i] ; i++ ) {
568 if (strcmp(port->keywords[i],s) == 0)
575 extern int fatalError;
581 if (yylineno && filename)
582 fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",