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] ;
332 * Change by JTV 2001-05-19 to not concantenate strings
333 * to support ANSI hex and octal escape sequences in string liteals
336 char *stringLiteral ()
340 char *str = strLitBuff ;
343 /* put into the buffer till we hit the */
351 break ; /* end of input */
353 /* if it is a \ then everything allowed */
357 *str++ = ch ; /* backslash in place */
358 *str++ = input() ; /* following char in place */
359 continue ; /* carry on */
362 /* if new line we have a new line break */
366 /* if this is a quote then we have work to do */
367 /* find the next non whitespace character */
368 /* if that is a double quote then carry on */
372 *str++ = ch ; /* Pass end of this string or substring to evaluator */
374 while ((ch = input()) && isspace(ch)) ;
386 *str++ = ch; /* Put next substring introducer into output string */
394 void doPragma (int op, char *cp)
398 memcpy(&save_options,&options,sizeof(options));
399 memcpy(&save_optimize,&optimize,sizeof(optimize));
402 memcpy(&options,&save_options,sizeof(options));
403 memcpy(&optimize,&save_optimize,sizeof(optimize));
406 optimize.loopInduction = 0 ;
409 optimize.loopInvariant = 0 ;
412 optimize.loopInduction = 1 ;
415 options.stackAuto = 1;
418 optimize.noJTabBoundary = 1;
421 optimize.global_cse = 0;
424 options.noOverlay = 1;
429 /* append to the functions already listed
431 for (; options.calleeSaves[i] ;i++);
432 parseWithComma(&options.calleeSaves[i],strdup(cp));
436 parseWithComma(options.excludeRegs,strdup(cp));
439 optimize.noLoopReverse = 1;
444 int process_pragma(char *s)
447 /* find the pragma */
448 while (strncmp(s,"#pragma",7))
452 /* look for the directive */
453 while(isspace(*s)) s++;
456 /* look for the end of the directive */
457 while ((! isspace(*s)) &&
461 /* First give the port a chance */
462 if (port->process_pragma && !port->process_pragma(cp))
465 /* now compare and do what needs to be done */
466 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
467 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
471 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
472 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
476 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
477 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
481 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
482 doPragma (P_NOINVARIANT,NULL) ;
486 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
487 doPragma (P_INDUCTION,NULL) ;
491 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
492 doPragma (P_STACKAUTO,NULL);
496 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
497 doPragma (P_NOJTBOUND,NULL);
501 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
502 doPragma (P_NOGCSE,NULL);
506 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
507 doPragma (P_NOOVERLAY,NULL);
511 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
512 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
516 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
517 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
521 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
522 doPragma(P_EXCLUDE,NULL);
526 werror(W_UNKNOWN_PRAGMA,cp);
530 /* will return 1 if the string is a part
531 of a target specific keyword */
532 int isTargetKeyword(char *s)
536 if (port->keywords == NULL)
538 for ( i = 0 ; port->keywords[i] ; i++ ) {
539 if (strcmp(port->keywords[i],s) == 0)
546 extern int fatalError;
552 if (yylineno && filename)
553 fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",