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 "for" { count(); return(FOR); }
114 "goto" { count(); return(GOTO); }
115 "idata" { count(); TKEYWORD(IDATA);}
116 "if" { count(); return(IF); }
117 "int" { count(); return(INT); }
118 "interrupt" { count(); return(INTERRUPT);}
119 "long" { count(); return(LONG); }
120 "near" { count(); TKEYWORD(DATA);}
121 "pdata" { count(); TKEYWORD(PDATA); }
122 "reentrant" { count(); TKEYWORD(REENTRANT);}
123 "register" { count(); return(REGISTER); }
124 "return" { count(); return(RETURN); }
125 "sfr" { count(); TKEYWORD(SFR) ; }
126 "sbit" { count(); TKEYWORD(SBIT) ; }
127 "short" { count(); return(SHORT); }
128 "signed" { count(); return(SIGNED); }
129 "sizeof" { count(); return(SIZEOF); }
130 "static" { count(); return(STATIC); }
131 "struct" { count(); return(STRUCT); }
132 "switch" { count(); return(SWITCH); }
133 "typedef" { count(); return(TYPEDEF); }
134 "union" { count(); return(UNION); }
135 "unsigned" { count(); return(UNSIGNED); }
136 "void" { count(); return(VOID); }
137 "volatile" { count(); return(VOLATILE); }
138 "using" { count(); TKEYWORD(USING); }
139 "while" { count(); return(WHILE); }
140 "xdata" { count(); TKEYWORD(XDATA); }
141 "_data" { count(); TKEYWORD(_NEAR); }
142 "_code" { count(); TKEYWORD(_CODE); }
143 "_eeprom" { count(); TKEYWORD(_EEPROM); }
144 "_generic" { count(); TKEYWORD(_GENERIC); }
145 "_near" { count(); TKEYWORD(_NEAR); }
146 "_xdata" { count(); TKEYWORD(_XDATA);}
147 "_pdata" { count(); TKEYWORD(_PDATA); }
148 "_idata" { count(); TKEYWORD(_IDATA); }
149 "..." { count(); return(VAR_ARGS);}
150 {L}({L}|{D})* { count(); return(check_type()); }
151 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
152 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
153 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
154 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
155 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
156 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
157 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
158 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
159 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
160 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
161 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
162 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
163 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
164 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
165 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
166 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
167 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
168 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
169 ">>" { count(); return(RIGHT_OP); }
170 "<<" { count(); return(LEFT_OP); }
171 "++" { count(); return(INC_OP); }
172 "--" { count(); return(DEC_OP); }
173 "->" { count(); return(PTR_OP); }
174 "&&" { count(); return(AND_OP); }
175 "||" { count(); return(OR_OP); }
176 "<=" { count(); return(LE_OP); }
177 ">=" { count(); return(GE_OP); }
178 "==" { count(); return(EQ_OP); }
179 "!=" { count(); return(NE_OP); }
180 ";" { count(); return(';'); }
181 "{" { count(); NestLevel++ ; return('{'); }
182 "}" { count(); NestLevel--; return('}'); }
183 "," { count(); return(','); }
184 ":" { count(); return(':'); }
185 "=" { count(); return('='); }
186 "(" { count(); 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 ^#line.*"\n" { count(); checkCurrFile(yytext); }
205 ^#pragma.*"\n" { count(); process_pragma(yytext); }
207 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
208 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
211 [ \t\v\f] { count(); }
215 int checkCurrFile ( char *s)
221 /* first check if this is a #line */
222 if ( strncmp(s,"#line",5) )
225 /* get to the line number */
232 sscanf(lineNum,"%d",&lNum);
234 /* now see if we have a file name */
235 while (*s != '\"' && *s)
238 /* if we don't have a filename then */
239 /* set the current line number to */
240 /* line number if printFlag is on */
246 /* if we have a filename then check */
247 /* if it is "standard in" if yes then */
248 /* get the currentfile name info */
251 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
253 currFname = fullSrcFileName ;
256 /* mark the end of the filename */
257 while (*s != '"') s++;
259 ALLOC_ATOMIC(currFname,strlen(sb)+1);
260 strcpy(currFname,sb);
263 filename = currFname ;
272 while ((c = input()) != '*' && c != 0)
276 if ((c1 = input()) != '/' && c != 0) {
294 for (i = 0; yytext[i] != '\0'; i++) {
295 if (yytext[i] == '\n') {
297 lineno = ++yylineno ;
300 if (yytext[i] == '\t')
301 column += 8 - (column % 8);
311 /* check if it is in the typedef table */
312 if (findSym(TypedefTab,NULL,yytext)) {
313 strcpy(yylval.yychar,yytext);
317 strcpy (yylval.yychar,yytext);
322 char strLitBuff[2048] ;
324 char *stringLiteral ()
327 char *str = strLitBuff ;
330 /* put into the buffer till we hit the */
335 if (!ch) break ; /* end of input */
336 /* if it is a \ then everything allowed */
338 *str++ = ch ; /* backslash in place */
339 *str++ = input() ; /* following char in place */
340 continue ; /* carry on */
343 /* if new line we have a new line break */
344 if (ch == '\n') break ;
346 /* if this is a quote then we have work to do */
347 /* find the next non whitespace character */
348 /* if that is a double quote then carry on */
351 while ((ch = input()) && isspace(ch)) ;
367 void doPragma (int op, char *cp)
371 memcpy(&save_options,&options,sizeof(options));
372 memcpy(&save_optimize,&optimize,sizeof(optimize));
375 memcpy(&options,&save_options,sizeof(options));
376 memcpy(&optimize,&save_optimize,sizeof(optimize));
379 optimize.loopInduction = 0 ;
382 optimize.loopInvariant = 0 ;
385 optimize.loopInduction = 1 ;
388 options.stackAuto = 1;
391 optimize.noJTabBoundary = 1;
394 optimize.global_cse = 0;
397 options.noOverlay = 1;
402 /* append to the functions already listed
404 for (; options.calleeSaves[i] ;i++);
405 parseWithComma(&options.calleeSaves[i],strdup(cp));
409 parseWithComma(options.excludeRegs,strdup(cp));
412 optimize.noLoopReverse = 1;
417 int process_pragma(char *s)
420 /* find the pragma */
421 while (strncmp(s,"#pragma",7))
425 /* look for the directive */
426 while(isspace(*s)) s++;
429 /* look for the end of the directive */
430 while ((! isspace(*s)) &&
434 /* now compare and do what needs to be done */
435 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
436 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
440 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
441 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
445 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
446 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
450 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
451 doPragma (P_NOINVARIANT,NULL) ;
455 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
456 doPragma (P_INDUCTION,NULL) ;
460 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
461 doPragma (P_STACKAUTO,NULL);
465 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
466 doPragma (P_NOJTBOUND,NULL);
470 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
471 doPragma (P_NOGCSE,NULL);
475 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
476 doPragma (P_NOOVERLAY,NULL);
480 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
481 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
485 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
486 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
490 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
491 doPragma(P_EXCLUDE,NULL);
495 werror(W_UNKNOWN_PRAGMA,cp);
499 /* will return 1 if the string is a part
500 of a target specific keyword */
501 int isTargetKeyword(char *s)
505 if (port->keywords == NULL)
507 for ( i = 0 ; port->keywords[i] ; i++ ) {
508 if (strcmp(port->keywords[i],s) == 0)