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 -------------------------------------------------------------------------*/
39 char *stringLiteral();
43 extern char *filename ;
44 extern char *fullSrcFileName ;
48 int process_pragma(char *);
51 int yywrap YY_PROTO((void))
55 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
57 char asmbuff[MAX_INLINEASM] ;
59 extern int check_type ();
60 extern int isTargetKeyword ();
61 extern int checkCurrFile (char *);
62 extern int processPragma (char *);
63 extern int printListing (int );
64 struct optimize save_optimize ;
65 struct options save_options ;
85 "_asm" { count(); asmp = asmbuff ;BEGIN(asm) ;}
86 <asm>"_endasm" { count() ;
88 strcpy(yylval.yyinline,asmbuff) ;
90 return (INLINEASM) ; }
91 <asm>. { *asmp++ = yytext[0] ; }
92 <asm>\n { count(); *asmp++ = '\n' ;}
94 "at" { count(); TKEYWORD(AT) ; }
95 "auto" { count(); return(AUTO); }
96 "bit" { count(); TKEYWORD(BIT) ; }
97 "break" { count(); return(BREAK); }
98 "case" { count(); return(CASE); }
99 "char" { count(); return(CHAR); }
100 "code" { count(); TKEYWORD(CODE); }
101 "const" { count(); return(CONST); }
102 "continue" { count(); return(CONTINUE); }
103 "critical" { count(); TKEYWORD(CRITICAL); }
104 "data" { count(); TKEYWORD(DATA); }
105 "default" { count(); return(DEFAULT); }
106 "do" { count(); return(DO); }
107 "double" { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
108 "else" { count(); return(ELSE); }
109 "enum" { count(); return(ENUM); }
110 "extern" { count(); return(EXTERN); }
111 "far" { count(); TKEYWORD(XDATA); }
112 "eeprom" { count(); TKEYWORD(EEPROM); }
113 "float" { count(); return(FLOAT); }
114 "flash" { count(); TKEYWORD(CODE);}
115 "for" { count(); return(FOR); }
116 "goto" { count(); return(GOTO); }
117 "idata" { count(); TKEYWORD(IDATA);}
118 "if" { count(); return(IF); }
119 "int" { count(); return(INT); }
120 "interrupt" { count(); return(INTERRUPT);}
121 "nonbanked" { count(); TKEYWORD(NONBANKED);}
122 "banked" { count(); TKEYWORD(BANKED);}
123 "long" { count(); return(LONG); }
124 "near" { count(); TKEYWORD(DATA);}
125 "pdata" { count(); TKEYWORD(PDATA); }
126 "reentrant" { count(); TKEYWORD(REENTRANT);}
127 "register" { count(); return(REGISTER); }
128 "return" { count(); return(RETURN); }
129 "sfr" { count(); TKEYWORD(SFR) ; }
130 "sbit" { count(); TKEYWORD(SBIT) ; }
131 "short" { count(); return(SHORT); }
132 "signed" { count(); return(SIGNED); }
133 "sizeof" { count(); return(SIZEOF); }
134 "sram" { count(); TKEYWORD(XDATA);}
135 "static" { count(); return(STATIC); }
136 "struct" { count(); return(STRUCT); }
137 "switch" { count(); return(SWITCH); }
138 "typedef" { count(); return(TYPEDEF); }
139 "union" { count(); return(UNION); }
140 "unsigned" { count(); return(UNSIGNED); }
141 "void" { count(); return(VOID); }
142 "volatile" { count(); return(VOLATILE); }
143 "using" { count(); TKEYWORD(USING); }
144 "while" { count(); return(WHILE); }
145 "xdata" { count(); TKEYWORD(XDATA); }
146 "_data" { count(); TKEYWORD(_NEAR); }
147 "_code" { count(); TKEYWORD(_CODE); }
148 "_eeprom" { count(); TKEYWORD(_EEPROM); }
149 "_flash" { count(); TKEYWORD(_CODE); }
150 "_generic" { count(); TKEYWORD(_GENERIC); }
151 "_near" { count(); TKEYWORD(_NEAR); }
152 "_sram" { count(); TKEYWORD(_XDATA);}
153 "_xdata" { count(); TKEYWORD(_XDATA);}
154 "_pdata" { count(); TKEYWORD(_PDATA); }
155 "_idata" { count(); TKEYWORD(_IDATA); }
156 "..." { count(); return(VAR_ARGS);}
157 {L}({L}|{D})* { count(); return(check_type()); }
158 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
159 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
160 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
161 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
162 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
163 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
164 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
165 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
166 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
167 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
168 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
169 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
170 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
171 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
172 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
173 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
174 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
175 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
176 ">>" { count(); return(RIGHT_OP); }
177 "<<" { count(); return(LEFT_OP); }
178 "++" { count(); return(INC_OP); }
179 "--" { count(); return(DEC_OP); }
180 "->" { count(); return(PTR_OP); }
181 "&&" { count(); return(AND_OP); }
182 "||" { count(); return(OR_OP); }
183 "<=" { count(); return(LE_OP); }
184 ">=" { count(); return(GE_OP); }
185 "==" { count(); return(EQ_OP); }
186 "!=" { count(); return(NE_OP); }
187 ";" { count(); return(';'); }
188 "{" { count(); NestLevel++ ; return('{'); }
189 "}" { count(); NestLevel--; 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 "?" { count(); return('?'); }
211 ^#line.*"\n" { count(); checkCurrFile(yytext); }
212 ^#pragma.*"\n" { count(); process_pragma(yytext); }
214 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
215 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
218 [ \t\v\f] { count(); }
222 int checkCurrFile ( char *s)
228 /* first check if this is a #line */
229 if ( strncmp(s,"#line",5) )
232 /* get to the line number */
239 sscanf(lineNum,"%d",&lNum);
241 /* now see if we have a file name */
242 while (*s != '\"' && *s)
245 /* if we don't have a filename then */
246 /* set the current line number to */
247 /* line number if printFlag is on */
253 /* if we have a filename then check */
254 /* if it is "standard in" if yes then */
255 /* get the currentfile name info */
258 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
260 currFname = fullSrcFileName ;
263 /* mark the end of the filename */
264 while (*s != '"') s++;
266 currFname = Safe_calloc(1,strlen(sb)+1);
267 strcpy(currFname,sb);
270 filename = currFname ;
279 while ((c = input()) != '*' && c != 0)
283 if ((c1 = input()) != '/' && c != 0) {
301 for (i = 0; yytext[i] != '\0'; i++) {
302 if (yytext[i] == '\n') {
304 lineno = ++yylineno ;
307 if (yytext[i] == '\t')
308 column += 8 - (column % 8);
318 /* check if it is in the typedef table */
319 if (findSym(TypedefTab,NULL,yytext)) {
320 strcpy(yylval.yychar,yytext);
324 strcpy (yylval.yychar,yytext);
329 char strLitBuff[2048] ;
331 char *stringLiteral ()
334 char *str = strLitBuff ;
337 /* put into the buffer till we hit the */
342 if (!ch) break ; /* end of input */
343 /* if it is a \ then everything allowed */
345 *str++ = ch ; /* backslash in place */
346 *str++ = input() ; /* following char in place */
347 continue ; /* carry on */
350 /* if new line we have a new line break */
351 if (ch == '\n') break ;
353 /* if this is a quote then we have work to do */
354 /* find the next non whitespace character */
355 /* if that is a double quote then carry on */
358 while ((ch = input()) && isspace(ch)) ;
374 void doPragma (int op, char *cp)
378 memcpy(&save_options,&options,sizeof(options));
379 memcpy(&save_optimize,&optimize,sizeof(optimize));
382 memcpy(&options,&save_options,sizeof(options));
383 memcpy(&optimize,&save_optimize,sizeof(optimize));
386 optimize.loopInduction = 0 ;
389 optimize.loopInvariant = 0 ;
392 optimize.loopInduction = 1 ;
395 options.stackAuto = 1;
398 optimize.noJTabBoundary = 1;
401 optimize.global_cse = 0;
404 options.noOverlay = 1;
409 /* append to the functions already listed
411 for (; options.calleeSaves[i] ;i++);
412 parseWithComma(&options.calleeSaves[i],strdup(cp));
416 parseWithComma(options.excludeRegs,strdup(cp));
419 optimize.noLoopReverse = 1;
424 int process_pragma(char *s)
427 /* find the pragma */
428 while (strncmp(s,"#pragma",7))
432 /* look for the directive */
433 while(isspace(*s)) s++;
436 /* look for the end of the directive */
437 while ((! isspace(*s)) &&
441 /* First give the port a chance */
442 if (port->process_pragma && !port->process_pragma(cp))
445 /* now compare and do what needs to be done */
446 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
447 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
451 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
452 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
456 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
457 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
461 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
462 doPragma (P_NOINVARIANT,NULL) ;
466 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
467 doPragma (P_INDUCTION,NULL) ;
471 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
472 doPragma (P_STACKAUTO,NULL);
476 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
477 doPragma (P_NOJTBOUND,NULL);
481 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
482 doPragma (P_NOGCSE,NULL);
486 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
487 doPragma (P_NOOVERLAY,NULL);
491 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
492 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
496 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
497 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
501 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
502 doPragma(P_EXCLUDE,NULL);
506 werror(W_UNKNOWN_PRAGMA,cp);
510 /* will return 1 if the string is a part
511 of a target specific keyword */
512 int isTargetKeyword(char *s)
516 if (port->keywords == NULL)
518 for ( i = 0 ; port->keywords[i] ; i++ ) {
519 if (strcmp(port->keywords[i],s) == 0)
526 extern int fatalError;
532 if (yylineno && filename)
533 fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",