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 "banked" { count(); TKEYWORD(BANKED);}
122 "long" { count(); return(LONG); }
123 "near" { count(); TKEYWORD(DATA);}
124 "pdata" { count(); TKEYWORD(PDATA); }
125 "reentrant" { count(); TKEYWORD(REENTRANT);}
126 "register" { count(); return(REGISTER); }
127 "return" { count(); return(RETURN); }
128 "sfr" { count(); TKEYWORD(SFR) ; }
129 "sbit" { count(); TKEYWORD(SBIT) ; }
130 "short" { count(); return(SHORT); }
131 "signed" { count(); return(SIGNED); }
132 "sizeof" { count(); return(SIZEOF); }
133 "sram" { count(); TKEYWORD(XDATA);}
134 "static" { count(); return(STATIC); }
135 "struct" { count(); return(STRUCT); }
136 "switch" { count(); return(SWITCH); }
137 "typedef" { count(); return(TYPEDEF); }
138 "union" { count(); return(UNION); }
139 "unsigned" { count(); return(UNSIGNED); }
140 "void" { count(); return(VOID); }
141 "volatile" { count(); return(VOLATILE); }
142 "using" { count(); TKEYWORD(USING); }
143 "while" { count(); return(WHILE); }
144 "xdata" { count(); TKEYWORD(XDATA); }
145 "_data" { count(); TKEYWORD(_NEAR); }
146 "_code" { count(); TKEYWORD(_CODE); }
147 "_eeprom" { count(); TKEYWORD(_EEPROM); }
148 "_flash" { count(); TKEYWORD(_CODE); }
149 "_generic" { count(); TKEYWORD(_GENERIC); }
150 "_near" { count(); TKEYWORD(_NEAR); }
151 "_sram" { count(); TKEYWORD(_XDATA);}
152 "_xdata" { count(); TKEYWORD(_XDATA);}
153 "_pdata" { count(); TKEYWORD(_PDATA); }
154 "_idata" { count(); TKEYWORD(_IDATA); }
155 "..." { count(); return(VAR_ARGS);}
156 {L}({L}|{D})* { count(); return(check_type()); }
157 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
158 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
159 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
160 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
161 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
162 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
163 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
164 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
165 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
166 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
167 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
168 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
169 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
170 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
171 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
172 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
173 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
174 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
175 ">>" { count(); return(RIGHT_OP); }
176 "<<" { count(); return(LEFT_OP); }
177 "++" { count(); return(INC_OP); }
178 "--" { count(); return(DEC_OP); }
179 "->" { count(); return(PTR_OP); }
180 "&&" { count(); return(AND_OP); }
181 "||" { count(); return(OR_OP); }
182 "<=" { count(); return(LE_OP); }
183 ">=" { count(); return(GE_OP); }
184 "==" { count(); return(EQ_OP); }
185 "!=" { count(); return(NE_OP); }
186 ";" { count(); return(';'); }
187 "{" { count(); NestLevel++ ; return('{'); }
188 "}" { count(); NestLevel--; 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 "?" { count(); return('?'); }
210 ^#line.*"\n" { count(); checkCurrFile(yytext); }
211 ^#pragma.*"\n" { count(); process_pragma(yytext); }
213 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
214 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
217 [ \t\v\f] { count(); }
221 int checkCurrFile ( char *s)
227 /* first check if this is a #line */
228 if ( strncmp(s,"#line",5) )
231 /* get to the line number */
238 sscanf(lineNum,"%d",&lNum);
240 /* now see if we have a file name */
241 while (*s != '\"' && *s)
244 /* if we don't have a filename then */
245 /* set the current line number to */
246 /* line number if printFlag is on */
252 /* if we have a filename then check */
253 /* if it is "standard in" if yes then */
254 /* get the currentfile name info */
257 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
259 currFname = fullSrcFileName ;
262 /* mark the end of the filename */
263 while (*s != '"') s++;
265 ALLOC(currFname,strlen(sb)+1);
266 strcpy(currFname,sb);
269 filename = currFname ;
278 while ((c = input()) != '*' && c != 0)
282 if ((c1 = input()) != '/' && c != 0) {
300 for (i = 0; yytext[i] != '\0'; i++) {
301 if (yytext[i] == '\n') {
303 lineno = ++yylineno ;
306 if (yytext[i] == '\t')
307 column += 8 - (column % 8);
317 /* check if it is in the typedef table */
318 if (findSym(TypedefTab,NULL,yytext)) {
319 strcpy(yylval.yychar,yytext);
323 strcpy (yylval.yychar,yytext);
328 char strLitBuff[2048] ;
330 char *stringLiteral ()
333 char *str = strLitBuff ;
336 /* put into the buffer till we hit the */
341 if (!ch) break ; /* end of input */
342 /* if it is a \ then everything allowed */
344 *str++ = ch ; /* backslash in place */
345 *str++ = input() ; /* following char in place */
346 continue ; /* carry on */
349 /* if new line we have a new line break */
350 if (ch == '\n') break ;
352 /* if this is a quote then we have work to do */
353 /* find the next non whitespace character */
354 /* if that is a double quote then carry on */
357 while ((ch = input()) && isspace(ch)) ;
373 void doPragma (int op, char *cp)
377 memcpy(&save_options,&options,sizeof(options));
378 memcpy(&save_optimize,&optimize,sizeof(optimize));
381 memcpy(&options,&save_options,sizeof(options));
382 memcpy(&optimize,&save_optimize,sizeof(optimize));
385 optimize.loopInduction = 0 ;
388 optimize.loopInvariant = 0 ;
391 optimize.loopInduction = 1 ;
394 options.stackAuto = 1;
397 optimize.noJTabBoundary = 1;
400 optimize.global_cse = 0;
403 options.noOverlay = 1;
408 /* append to the functions already listed
410 for (; options.calleeSaves[i] ;i++);
411 parseWithComma(&options.calleeSaves[i],strdup(cp));
415 parseWithComma(options.excludeRegs,strdup(cp));
418 optimize.noLoopReverse = 1;
423 int process_pragma(char *s)
426 /* find the pragma */
427 while (strncmp(s,"#pragma",7))
431 /* look for the directive */
432 while(isspace(*s)) s++;
435 /* look for the end of the directive */
436 while ((! isspace(*s)) &&
440 /* First give the port a chance */
441 if (port->process_pragma && !port->process_pragma(cp))
444 /* now compare and do what needs to be done */
445 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
446 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
450 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
451 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
455 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
456 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
460 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
461 doPragma (P_NOINVARIANT,NULL) ;
465 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
466 doPragma (P_INDUCTION,NULL) ;
470 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
471 doPragma (P_STACKAUTO,NULL);
475 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
476 doPragma (P_NOJTBOUND,NULL);
480 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
481 doPragma (P_NOGCSE,NULL);
485 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
486 doPragma (P_NOOVERLAY,NULL);
490 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
491 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
495 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
496 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
500 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
501 doPragma(P_EXCLUDE,NULL);
505 werror(W_UNKNOWN_PRAGMA,cp);
509 /* will return 1 if the string is a part
510 of a target specific keyword */
511 int isTargetKeyword(char *s)
515 if (port->keywords == NULL)
517 for ( i = 0 ; port->keywords[i] ; i++ ) {
518 if (strcmp(port->keywords[i],s) == 0)
525 extern int fatalError;
531 if (yylineno && filename)
532 fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",