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 "long" { count(); return(LONG); }
121 "near" { count(); TKEYWORD(DATA);}
122 "pdata" { count(); TKEYWORD(PDATA); }
123 "reentrant" { count(); TKEYWORD(REENTRANT);}
124 "register" { count(); return(REGISTER); }
125 "return" { count(); return(RETURN); }
126 "sfr" { count(); TKEYWORD(SFR) ; }
127 "sbit" { count(); TKEYWORD(SBIT) ; }
128 "short" { count(); return(SHORT); }
129 "signed" { count(); return(SIGNED); }
130 "sizeof" { count(); return(SIZEOF); }
131 "sram" { count(); TKEYWORD(XDATA);}
132 "static" { count(); return(STATIC); }
133 "struct" { count(); return(STRUCT); }
134 "switch" { count(); return(SWITCH); }
135 "typedef" { count(); return(TYPEDEF); }
136 "union" { count(); return(UNION); }
137 "unsigned" { count(); return(UNSIGNED); }
138 "void" { count(); return(VOID); }
139 "volatile" { count(); return(VOLATILE); }
140 "using" { count(); TKEYWORD(USING); }
141 "while" { count(); return(WHILE); }
142 "xdata" { count(); TKEYWORD(XDATA); }
143 "_data" { count(); TKEYWORD(_NEAR); }
144 "_code" { count(); TKEYWORD(_CODE); }
145 "_eeprom" { count(); TKEYWORD(_EEPROM); }
146 "_flash" { count(); TKEYWORD(_CODE); }
147 "_generic" { count(); TKEYWORD(_GENERIC); }
148 "_near" { count(); TKEYWORD(_NEAR); }
149 "_sram" { count(); TKEYWORD(_XDATA);}
150 "_xdata" { count(); TKEYWORD(_XDATA);}
151 "_pdata" { count(); TKEYWORD(_PDATA); }
152 "_idata" { count(); TKEYWORD(_IDATA); }
153 "..." { count(); return(VAR_ARGS);}
154 {L}({L}|{D})* { count(); return(check_type()); }
155 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
156 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
157 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
158 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
159 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
160 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
161 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
162 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
163 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
164 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
165 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
166 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
167 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
168 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
169 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
170 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
171 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
172 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
173 ">>" { count(); return(RIGHT_OP); }
174 "<<" { count(); return(LEFT_OP); }
175 "++" { count(); return(INC_OP); }
176 "--" { count(); return(DEC_OP); }
177 "->" { count(); return(PTR_OP); }
178 "&&" { count(); return(AND_OP); }
179 "||" { count(); return(OR_OP); }
180 "<=" { count(); return(LE_OP); }
181 ">=" { count(); return(GE_OP); }
182 "==" { count(); return(EQ_OP); }
183 "!=" { count(); return(NE_OP); }
184 ";" { count(); return(';'); }
185 "{" { count(); NestLevel++ ; return('{'); }
186 "}" { count(); NestLevel--; return('}'); }
187 "," { count(); 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 ^#line.*"\n" { count(); checkCurrFile(yytext); }
209 ^#pragma.*"\n" { count(); process_pragma(yytext); }
211 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
212 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
215 [ \t\v\f] { count(); }
219 int checkCurrFile ( char *s)
225 /* first check if this is a #line */
226 if ( strncmp(s,"#line",5) )
229 /* get to the line number */
236 sscanf(lineNum,"%d",&lNum);
238 /* now see if we have a file name */
239 while (*s != '\"' && *s)
242 /* if we don't have a filename then */
243 /* set the current line number to */
244 /* line number if printFlag is on */
250 /* if we have a filename then check */
251 /* if it is "standard in" if yes then */
252 /* get the currentfile name info */
255 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
257 currFname = fullSrcFileName ;
260 /* mark the end of the filename */
261 while (*s != '"') s++;
263 ALLOC_ATOMIC(currFname,strlen(sb)+1);
264 strcpy(currFname,sb);
267 filename = currFname ;
276 while ((c = input()) != '*' && c != 0)
280 if ((c1 = input()) != '/' && c != 0) {
298 for (i = 0; yytext[i] != '\0'; i++) {
299 if (yytext[i] == '\n') {
301 lineno = ++yylineno ;
304 if (yytext[i] == '\t')
305 column += 8 - (column % 8);
315 /* check if it is in the typedef table */
316 if (findSym(TypedefTab,NULL,yytext)) {
317 strcpy(yylval.yychar,yytext);
321 strcpy (yylval.yychar,yytext);
326 char strLitBuff[2048] ;
328 char *stringLiteral ()
331 char *str = strLitBuff ;
334 /* put into the buffer till we hit the */
339 if (!ch) break ; /* end of input */
340 /* if it is a \ then everything allowed */
342 *str++ = ch ; /* backslash in place */
343 *str++ = input() ; /* following char in place */
344 continue ; /* carry on */
347 /* if new line we have a new line break */
348 if (ch == '\n') break ;
350 /* if this is a quote then we have work to do */
351 /* find the next non whitespace character */
352 /* if that is a double quote then carry on */
355 while ((ch = input()) && isspace(ch)) ;
371 void doPragma (int op, char *cp)
375 memcpy(&save_options,&options,sizeof(options));
376 memcpy(&save_optimize,&optimize,sizeof(optimize));
379 memcpy(&options,&save_options,sizeof(options));
380 memcpy(&optimize,&save_optimize,sizeof(optimize));
383 optimize.loopInduction = 0 ;
386 optimize.loopInvariant = 0 ;
389 optimize.loopInduction = 1 ;
392 options.stackAuto = 1;
395 optimize.noJTabBoundary = 1;
398 optimize.global_cse = 0;
401 options.noOverlay = 1;
406 /* append to the functions already listed
408 for (; options.calleeSaves[i] ;i++);
409 parseWithComma(&options.calleeSaves[i],strdup(cp));
413 parseWithComma(options.excludeRegs,strdup(cp));
416 optimize.noLoopReverse = 1;
421 int process_pragma(char *s)
424 /* find the pragma */
425 while (strncmp(s,"#pragma",7))
429 /* look for the directive */
430 while(isspace(*s)) s++;
433 /* look for the end of the directive */
434 while ((! isspace(*s)) &&
438 /* First give the port a chance */
439 if (port->process_pragma && !port->process_pragma(cp))
442 /* now compare and do what needs to be done */
443 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
444 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
448 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
449 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
453 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
454 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
458 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
459 doPragma (P_NOINVARIANT,NULL) ;
463 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
464 doPragma (P_INDUCTION,NULL) ;
468 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
469 doPragma (P_STACKAUTO,NULL);
473 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
474 doPragma (P_NOJTBOUND,NULL);
478 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
479 doPragma (P_NOGCSE,NULL);
483 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
484 doPragma (P_NOOVERLAY,NULL);
488 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
489 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
493 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
494 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
498 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
499 doPragma(P_EXCLUDE,NULL);
503 werror(W_UNKNOWN_PRAGMA,cp);
507 /* will return 1 if the string is a part
508 of a target specific keyword */
509 int isTargetKeyword(char *s)
513 if (port->keywords == NULL)
515 for ( i = 0 ; port->keywords[i] ; i++ ) {
516 if (strcmp(port->keywords[i],s) == 0)