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 "float" { count(); return(FLOAT); }
112 "for" { count(); return(FOR); }
113 "goto" { count(); return(GOTO); }
114 "idata" { count(); TKEYWORD(IDATA);}
115 "if" { count(); return(IF); }
116 "int" { count(); return(INT); }
117 "interrupt" { count(); return(INTERRUPT);}
118 "long" { count(); return(LONG); }
119 "near" { count(); TKEYWORD(DATA);}
120 "pdata" { count(); return(PDATA); }
121 "reentrant" { count(); TKEYWORD(REENTRANT);}
122 "register" { count(); return(REGISTER); }
123 "return" { count(); return(RETURN); }
124 "sfr" { count(); TKEYWORD(SFR) ; }
125 "sbit" { count(); TKEYWORD(SBIT) ; }
126 "short" { count(); return(SHORT); }
127 "signed" { count(); return(SIGNED); }
128 "sizeof" { count(); return(SIZEOF); }
129 "static" { count(); return(STATIC); }
130 "struct" { count(); return(STRUCT); }
131 "switch" { count(); return(SWITCH); }
132 "typedef" { count(); return(TYPEDEF); }
133 "union" { count(); return(UNION); }
134 "unsigned" { count(); return(UNSIGNED); }
135 "void" { count(); return(VOID); }
136 "volatile" { count(); return(VOLATILE); }
137 "using" { count(); TKEYWORD(USING); }
138 "while" { count(); return(WHILE); }
139 "xdata" { count(); TKEYWORD(XDATA); }
140 "_data" { count(); TKEYWORD(_NEAR); }
141 "_code" { count(); TKEYWORD(_CODE); }
142 "_generic" { count(); TKEYWORD(_GENERIC); }
143 "_near" { count(); TKEYWORD(_NEAR); }
144 "_xdata" { count(); TKEYWORD(_XDATA);}
145 "_pdata" { count(); TKEYWORD(_PDATA); }
146 "_idata" { count(); TKEYWORD(_IDATA); }
147 "..." { count(); return(VAR_ARGS);}
148 {L}({L}|{D})* { count(); return(check_type()); }
149 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
150 0{D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
151 {D}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
152 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
153 {D}+{E}{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
154 {D}*"."{D}+({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
155 {D}+"."{D}*({E})?{FS}? { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
156 \" { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
157 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
158 "<<=" { count(); yylval.yyint = LEFT_ASSIGN ; return(LEFT_ASSIGN) ; }
159 "+=" { count(); yylval.yyint = ADD_ASSIGN ; return(ADD_ASSIGN) ; }
160 "-=" { count(); yylval.yyint = SUB_ASSIGN ; return(SUB_ASSIGN) ; }
161 "*=" { count(); yylval.yyint = MUL_ASSIGN ; return(MUL_ASSIGN) ; }
162 "/=" { count(); yylval.yyint = DIV_ASSIGN ; return(DIV_ASSIGN) ; }
163 "%=" { count(); yylval.yyint = MOD_ASSIGN ; return(MOD_ASSIGN) ; }
164 "&=" { count(); yylval.yyint = AND_ASSIGN ; return(AND_ASSIGN) ; }
165 "^=" { count(); yylval.yyint = XOR_ASSIGN ; return(XOR_ASSIGN) ; }
166 "|=" { count(); yylval.yyint = OR_ASSIGN ; return(OR_ASSIGN) ; }
167 ">>" { count(); return(RIGHT_OP); }
168 "<<" { count(); return(LEFT_OP); }
169 "++" { count(); return(INC_OP); }
170 "--" { count(); return(DEC_OP); }
171 "->" { count(); return(PTR_OP); }
172 "&&" { count(); return(AND_OP); }
173 "||" { count(); return(OR_OP); }
174 "<=" { count(); return(LE_OP); }
175 ">=" { count(); return(GE_OP); }
176 "==" { count(); return(EQ_OP); }
177 "!=" { count(); return(NE_OP); }
178 ";" { count(); return(';'); }
179 "{" { count(); NestLevel++ ; return('{'); }
180 "}" { count(); NestLevel--; return('}'); }
181 "," { count(); return(','); }
182 ":" { count(); 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 ^#line.*"\n" { count(); checkCurrFile(yytext); }
203 ^#pragma.*"\n" { count(); process_pragma(yytext); }
205 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
206 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
209 [ \t\v\f] { count(); }
213 int checkCurrFile ( char *s)
219 /* first check if this is a #line */
220 if ( strncmp(s,"#line",5) )
223 /* get to the line number */
230 sscanf(lineNum,"%d",&lNum);
232 /* now see if we have a file name */
233 while (*s != '\"' && *s)
236 /* if we don't have a filename then */
237 /* set the current line number to */
238 /* line number if printFlag is on */
244 /* if we have a filename then check */
245 /* if it is "standard in" if yes then */
246 /* get the currentfile name info */
249 if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
251 currFname = fullSrcFileName ;
254 /* mark the end of the filename */
255 while (*s != '"') s++;
257 ALLOC_ATOMIC(currFname,strlen(sb)+1);
258 strcpy(currFname,sb);
261 filename = currFname ;
270 while ((c = input()) != '*' && c != 0)
274 if ((c1 = input()) != '/' && c != 0) {
292 for (i = 0; yytext[i] != '\0'; i++) {
293 if (yytext[i] == '\n') {
295 lineno = ++yylineno ;
298 if (yytext[i] == '\t')
299 column += 8 - (column % 8);
309 /* check if it is in the typedef table */
310 if (findSym(TypedefTab,NULL,yytext)) {
311 strcpy(yylval.yychar,yytext);
315 strcpy (yylval.yychar,yytext);
320 char strLitBuff[2048] ;
322 char *stringLiteral ()
325 char *str = strLitBuff ;
328 /* put into the buffer till we hit the */
333 if (!ch) break ; /* end of input */
334 /* if it is a \ then everything allowed */
336 *str++ = ch ; /* backslash in place */
337 *str++ = input() ; /* following char in place */
338 continue ; /* carry on */
341 /* if new line we have a new line break */
342 if (ch == '\n') break ;
344 /* if this is a quote then we have work to do */
345 /* find the next non whitespace character */
346 /* if that is a double quote then carry on */
349 while ((ch = input()) && isspace(ch)) ;
365 void doPragma (int op, char *cp)
369 memcpy(&save_options,&options,sizeof(options));
370 memcpy(&save_optimize,&optimize,sizeof(optimize));
373 memcpy(&options,&save_options,sizeof(options));
374 memcpy(&optimize,&save_optimize,sizeof(optimize));
377 optimize.loopInduction = 0 ;
380 optimize.loopInvariant = 0 ;
383 optimize.loopInduction = 1 ;
386 options.stackAuto = 1;
389 optimize.noJTabBoundary = 1;
392 optimize.global_cse = 0;
395 options.noOverlay = 1;
400 /* append to the functions already listed
402 for (; options.calleeSaves[i] ;i++);
403 parseWithComma(&options.calleeSaves[i],strdup(cp));
407 parseWithComma(options.excludeRegs,strdup(cp));
410 optimize.noLoopReverse = 1;
415 int process_pragma(char *s)
418 /* find the pragma */
419 while (strncmp(s,"#pragma",7))
423 /* look for the directive */
424 while(isspace(*s)) s++;
427 /* look for the end of the directive */
428 while ((! isspace(*s)) &&
432 /* now compare and do what needs to be done */
433 if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
434 doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
438 if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
439 doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
443 if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
444 doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION)) ;
448 if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
449 doPragma (P_NOINVARIANT,NULL) ;
453 if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
454 doPragma (P_INDUCTION,NULL) ;
458 if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
459 doPragma (P_STACKAUTO,NULL);
463 if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
464 doPragma (P_NOJTBOUND,NULL);
468 if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
469 doPragma (P_NOGCSE,NULL);
473 if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
474 doPragma (P_NOOVERLAY,NULL);
478 if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
479 doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
483 if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
484 doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
488 if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
489 doPragma(P_EXCLUDE,NULL);
493 werror(W_UNKNOWN_PRAGMA,cp);
497 /* will return 1 if the string is a part
498 of a target specific keyword */
499 int isTargetKeyword(char *s)
503 if (port->keywords == NULL)
505 for ( i = 0 ; port->keywords[i] ; i++ ) {
506 if (strcmp(port->keywords[i],s) == 0)