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 /* now compare and do what needs to be done */
439 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
440 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
444 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
445 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
449 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
450 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
454 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
455 doPragma (P_NOINVARIANT,NULL) ;
459 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
460 doPragma (P_INDUCTION,NULL) ;
464 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
465 doPragma (P_STACKAUTO,NULL);
469 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
470 doPragma (P_NOJTBOUND,NULL);
474 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
475 doPragma (P_NOGCSE,NULL);
479 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
480 doPragma (P_NOOVERLAY,NULL);
484 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
485 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
489 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
490 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
494 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
495 doPragma(P_EXCLUDE,NULL);
499 werror(W_UNKNOWN_PRAGMA,cp);
503 /* will return 1 if the string is a part
504 of a target specific keyword */
505 int isTargetKeyword(char *s)
509 if (port->keywords == NULL)
511 for ( i = 0 ; port->keywords[i] ; i++ ) {
512 if (strcmp(port->keywords[i],s) == 0)