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 -------------------------------------------------------------------------*/
38 char *stringLiteral();
42 extern char *filename ;
43 extern char *fullSrcFileName ;
47 int process_pragma(char *);
50 int yywrap YY_PROTO((void))
54 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
56 char asmbuff[MAX_INLINEASM] ;
58 extern int check_type ();
59 extern int isTargetKeyword ();
60 extern int checkCurrFile (char *);
61 extern int processPragma (char *);
62 extern int printListing (int );
63 struct optimize save_optimize ;
64 struct options save_options ;
84 "_asm" { count(); asmp = asmbuff ;BEGIN(asm) ;}
85 <asm>"_endasm" { count() ;
87 strcpy(yylval.yyinline,asmbuff) ;
89 return (INLINEASM) ; }
90 <asm>. { *asmp++ = yytext[0] ; }
91 <asm>\n { count(); *asmp++ = '\n' ;}
93 "at" { count(); TKEYWORD(AT) ; }
94 "auto" { count(); return(AUTO); }
95 "bit" { count(); TKEYWORD(BIT) ; }
96 "break" { count(); return(BREAK); }
97 "case" { count(); return(CASE); }
98 "char" { count(); return(CHAR); }
99 "code" { count(); TKEYWORD(CODE); }
100 "const" { count(); return(CONST); }
101 "continue" { count(); return(CONTINUE); }
102 "critical" { count(); TKEYWORD(CRITICAL); }
103 "data" { count(); TKEYWORD(DATA); }
104 "default" { count(); return(DEFAULT); }
105 "do" { count(); return(DO); }
106 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
107 "else" { count(); return(ELSE); }
108 "enum" { count(); return(ENUM); }
109 "extern" { count(); return(EXTERN); }
110 "far" { count(); TKEYWORD(XDATA); }
111 "eeprom" { count(); TKEYWORD(EEPROM); }
112 "float" { count(); return(FLOAT); }
113 "flash" { count(); TKEYWORD(CODE);}
114 "for" { count(); return(FOR); }
115 "goto" { count(); return(GOTO); }
116 "idata" { count(); TKEYWORD(IDATA);}
117 "if" { count(); return(IF); }
118 "int" { count(); return(INT); }
119 "interrupt" { count(); return(INTERRUPT);}
120 "nonbanked" { count(); TKEYWORD(NONBANKED);}
121 "long" { count(); return(LONG); }
122 "near" { count(); TKEYWORD(DATA);}
123 "pdata" { count(); TKEYWORD(PDATA); }
124 "reentrant" { count(); TKEYWORD(REENTRANT);}
125 "register" { count(); return(REGISTER); }
126 "return" { count(); return(RETURN); }
127 "sfr" { count(); TKEYWORD(SFR) ; }
128 "sbit" { count(); TKEYWORD(SBIT) ; }
129 "short" { count(); return(SHORT); }
130 "signed" { count(); return(SIGNED); }
131 "sizeof" { count(); return(SIZEOF); }
132 "sram" { count(); TKEYWORD(XDATA);}
133 "static" { count(); return(STATIC); }
134 "struct" { count(); return(STRUCT); }
135 "switch" { count(); return(SWITCH); }
136 "typedef" { count(); return(TYPEDEF); }
137 "union" { count(); return(UNION); }
138 "unsigned" { count(); return(UNSIGNED); }
139 "void" { count(); return(VOID); }
140 "volatile" { count(); return(VOLATILE); }
141 "using" { count(); TKEYWORD(USING); }
142 "while" { count(); return(WHILE); }
143 "xdata" { count(); TKEYWORD(XDATA); }
144 "_data" { count(); TKEYWORD(_NEAR); }
145 "_code" { count(); TKEYWORD(_CODE); }
146 "_eeprom" { count(); TKEYWORD(_EEPROM); }
147 "_flash" { count(); TKEYWORD(_CODE); }
148 "_generic" { count(); TKEYWORD(_GENERIC); }
149 "_near" { count(); TKEYWORD(_NEAR); }
150 "_sram" { count(); TKEYWORD(_XDATA);}
151 "_xdata" { count(); TKEYWORD(_XDATA);}
152 "_pdata" { count(); TKEYWORD(_PDATA); }
153 "_idata" { count(); TKEYWORD(_IDATA); }
154 "..." { count(); return(VAR_ARGS);}
155 {L}({L}|{D})* { count(); return(check_type()); }
156 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
157 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
158 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
159 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
160 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
161 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
162 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
163 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
164 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
165 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
166 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
167 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
168 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
169 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
170 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
171 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
172 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
173 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
174 ">>" { count(); return(RIGHT_OP); }
175 "<<" { count(); return(LEFT_OP); }
176 "++" { count(); return(INC_OP); }
177 "--" { count(); return(DEC_OP); }
178 "->" { count(); return(PTR_OP); }
179 "&&" { count(); return(AND_OP); }
180 "||" { count(); return(OR_OP); }
181 "<=" { count(); return(LE_OP); }
182 ">=" { count(); return(GE_OP); }
183 "==" { count(); return(EQ_OP); }
184 "!=" { count(); return(NE_OP); }
185 ";" { count(); return(';'); }
186 "{" { count(); NestLevel++ ; return('{'); }
187 "}" { count(); NestLevel--; return('}'); }
188 "," { count(); return(','); }
189 ":" { count(); return(':'); }
190 "=" { count(); return('='); }
191 "(" { count(); return('('); }
192 ")" { count(); return(')'); }
193 "[" { count(); return('['); }
194 "]" { count(); return(']'); }
195 "." { count(); return('.'); }
196 "&" { count(); return('&'); }
197 "!" { count(); return('!'); }
198 "~" { count(); return('~'); }
199 "-" { count(); return('-'); }
200 "+" { count(); return('+'); }
201 "*" { count(); return('*'); }
202 "/" { count(); return('/'); }
203 "%" { count(); return('%'); }
204 "<" { count(); return('<'); }
205 ">" { count(); return('>'); }
206 "^" { count(); return('^'); }
207 "|" { count(); return('|'); }
208 "?" { count(); return('?'); }
209 ^#line.*"\n" { count(); checkCurrFile(yytext); }
210 ^#pragma.*"\n" { count(); process_pragma(yytext); }
212 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
213 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
216 [ \t\v\f] { count(); }
220 int checkCurrFile ( char *s)
226 /* first check if this is a #line */
227 if ( strncmp(s,"#line",5) )
230 /* get to the line number */
237 sscanf(lineNum,"%d",&lNum);
239 /* now see if we have a file name */
240 while (*s != '\"' && *s)
243 /* if we don't have a filename then */
244 /* set the current line number to */
245 /* line number if printFlag is on */
251 /* if we have a filename then check */
252 /* if it is "standard in" if yes then */
253 /* get the currentfile name info */
256 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
258 currFname = fullSrcFileName ;
261 /* mark the end of the filename */
262 while (*s != '"') s++;
264 ALLOC_ATOMIC(currFname,strlen(sb)+1);
265 strcpy(currFname,sb);
268 filename = currFname ;
277 while ((c = input()) != '*' && c != 0)
281 if ((c1 = input()) != '/' && c != 0) {
299 for (i = 0; yytext[i] != '\0'; i++) {
300 if (yytext[i] == '\n') {
302 lineno = ++yylineno ;
305 if (yytext[i] == '\t')
306 column += 8 - (column % 8);
316 /* check if it is in the typedef table */
317 if (findSym(TypedefTab,NULL,yytext)) {
318 strcpy(yylval.yychar,yytext);
322 strcpy (yylval.yychar,yytext);
327 char strLitBuff[2048] ;
329 char *stringLiteral ()
332 char *str = strLitBuff ;
335 /* put into the buffer till we hit the */
340 if (!ch) break ; /* end of input */
341 /* if it is a \ then everything allowed */
343 *str++ = ch ; /* backslash in place */
344 *str++ = input() ; /* following char in place */
345 continue ; /* carry on */
348 /* if new line we have a new line break */
349 if (ch == '\n') break ;
351 /* if this is a quote then we have work to do */
352 /* find the next non whitespace character */
353 /* if that is a double quote then carry on */
356 while ((ch = input()) && isspace(ch)) ;
372 void doPragma (int op, char *cp)
376 memcpy(&save_options,&options,sizeof(options));
377 memcpy(&save_optimize,&optimize,sizeof(optimize));
380 memcpy(&options,&save_options,sizeof(options));
381 memcpy(&optimize,&save_optimize,sizeof(optimize));
384 optimize.loopInduction = 0 ;
387 optimize.loopInvariant = 0 ;
390 optimize.loopInduction = 1 ;
393 options.stackAuto = 1;
396 optimize.noJTabBoundary = 1;
399 optimize.global_cse = 0;
402 options.noOverlay = 1;
407 /* append to the functions already listed
409 for (; options.calleeSaves[i] ;i++);
410 parseWithComma(&options.calleeSaves[i],strdup(cp));
414 parseWithComma(options.excludeRegs,strdup(cp));
417 optimize.noLoopReverse = 1;
422 int process_pragma(char *s)
425 /* find the pragma */
426 while (strncmp(s,"#pragma",7))
430 /* look for the directive */
431 while(isspace(*s)) s++;
434 /* look for the end of the directive */
435 while ((! isspace(*s)) &&
439 /* First give the port a chance */
440 if (port->process_pragma && !port->process_pragma(cp))
443 /* now compare and do what needs to be done */
444 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
445 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
449 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
450 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
454 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
455 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
459 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
460 doPragma (P_NOINVARIANT,NULL) ;
464 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
465 doPragma (P_INDUCTION,NULL) ;
469 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
470 doPragma (P_STACKAUTO,NULL);
474 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
475 doPragma (P_NOJTBOUND,NULL);
479 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
480 doPragma (P_NOGCSE,NULL);
484 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
485 doPragma (P_NOOVERLAY,NULL);
489 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
490 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
494 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
495 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
499 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
500 doPragma(P_EXCLUDE,NULL);
504 werror(W_UNKNOWN_PRAGMA,cp);
508 /* will return 1 if the string is a part
509 of a target specific keyword */
510 int isTargetKeyword(char *s)
514 if (port->keywords == NULL)
516 for ( i = 0 ; port->keywords[i] ; i++ ) {
517 if (strcmp(port->keywords[i],s) == 0)