1 %{
2 /*---------------------------------------------------------------------------*
3   Project:  NitroSDK - tools - makelcf
4   File:     spec.l
5 
6   Copyright 2003-2008 Nintendo. All rights reserved.
7 
8   These coded instructions, statements, and computer programs contain
9   proprietary information of Nintendo of America Inc. and/or Nintendo
10   Company Ltd., and are protected by Federal copyright law. They may
11   not be disclosed to third parties or copied or duplicated in any form,
12   in whole or in part, without the prior written consent of Nintendo.
13 
14   $Log: spec.l,v $
15   Revision 1.28  2006/05/10 02:06:00  yasu
16   Added support for CodeWarrior 2.x
17 
18   Revision 1.27  2006/04/09 23:46:03  kitase_hirotake
19   Revised copyright
20 
21   Revision 1.26  2006/04/06 09:22:38  kitase_hirotake
22   Removed unnecessary parts
23 
24   Revision 1.25  2006/04/06 09:05:31  kitase_hirotake
25   Support for .itcm.bss .dtcm.bss .wram.bss
26 
27   Revision 1.24  2005/09/01 04:30:52  yasu
28   Support for Overlay Group
29 
30   Revision 1.23  2005/07/26 08:49:27  yasu
31   To provide compatibility with previous versions, supported keyword 'surffix'
32 
33   Revision 1.22  2005/06/22 00:50:06  yasu
34   Updated copyright year
35 
36   Revision 1.21  2005/06/20 12:21:48  yasu
37   Changed Surffix to Suffix
38 
39   Revision 1.20  2004/07/10 04:06:17  yasu
40   Added support for command 'Library'
41   Support for modifier ':x' in template
42   Fixed line continue '\' issue
43 
44   Revision 1.19  2004/07/08 02:58:53  yasu
45   Support section name for multi-objects as 'Objects' parameters
46 
47   Revision 1.18  2004/07/02 07:34:53  yasu
48   Added support for OBJECT( )
49 
50   Revision 1.17  2004/07/01 09:39:58  yasu
51   handle ITCM/DTCM/WRAM as keyword
52 
53   Revision 1.16  2004/06/29 04:20:31  yasu
54   Change error message
55 
56   Revision 1.15  2004/06/24 07:18:54  yasu
57   Support for keyword "Autoload"
58 
59   Revision 1.14  2004/06/14 11:28:45  yasu
60   Support for section filter "FOREACH.STATIC.OBJECTS=.sectionName"
61 
62   Revision 1.13  2004/06/07 01:46:59  yasu
63   Support 'properties' as keyword.
64 
65   Revision 1.12  2004/05/27 09:59:25  yasu
66   support negative value for stack size
67 
68   Revision 1.11  2004/04/02 04:02:36  yasu
69   merged with 1.00 branch
70 
71   Revision 1.10  2004/04/02 03:03:17  yasu
72   support big/little letter keywords
73 
74   Revision 1.9  2004/03/26 05:07:11  yasu
75   Support for variables like as -DNAME=VALUE
76 
77   Revision 1.8  2004/02/05 07:09:03  yasu
78   Changed SDK prefix iris -> nitro
79 
80   Revision 1.7  2004/01/15 10:47:56  yasu
81   Implementation of a static StackSize
82 
83   Revision 1.6  2004/01/14 13:05:44  yasu
84   Handle '\r?\n' as newline
85 
86   Revision 1.5  2004/01/14 12:58:47  yasu
87   Handle '\r' as newline
88 
89   Revision 1.4  2004/01/14 12:40:34  yasu
90   Change newline handling
91 
92   Revision 1.3  2004/01/14 12:38:08  yasu
93   Changed OverlayName to OverlayDefs
94 
95   Revision 1.2  2004/01/07 13:10:17  yasu
96   Fixed all warnings at compile -Wall
97 
98   Revision 1.1  2004/01/05 02:32:59  yasu
99   Initial version
100 
101   $NoKeywords: $
102  *---------------------------------------------------------------------------*/
103 #include	<stdio.h>
104 #include	<string.h>
105 #include	"makelcf.h"
106 #include	"defval.h"
107 #include	"spec.tab.h"
108 
109 #define	RETURN(x) { debug_printf( "%s [%s]\n", #x, spec_yytext ); return(x); }
110 
111 static void  YYText_ResolveDevVal( void );
112 static char* getSection( void );
113 
114 
115 %}
116 
117 ws			[ \t]
118 nl			\r?\n
119 identifier		[A-Za-z_][A-Za-z_0-9]*
120 decnum			-?[1-9][0-9]*
121 octnum			-?0[0-7]*
122 hexnum			-?0[xX][0-9A-Fa-f]+
123 qstring			\"[^\"\n\r]*\"
124 string_wo_ws		[^ \t\n\r]+
125 
126 %s START
127 %s PARAM
128 %s PARAM_CONTINUE
129 %option pointer
130 %option yylineno
131 %option noyywrap
132 %%
133 
134  //======================================================================
135  //    SPEC TOKENS
136  //======================================================================
137 
138 #.*			;					/* Comment */
139 \/\/.*			;					/* Comment */
140 
141 <INITIAL>.*	{
142 	YYText_ResolveDevVal();
143 	BEGIN START;
144 }
145 
146 <PARAM_CONTINUE>.*	{
147 	YYText_ResolveDevVal();
148 	BEGIN PARAM;
149 }
150 
151 <START>(Static|STATIC|static)	 		{ BEGIN PARAM; RETURN(tSTATIC);       }
152 <START>(Autoload|AUTOLOAD|autoload) 		{ BEGIN PARAM; RETURN(tAUTOLOAD);     }
153 <START>(Overlay|OVERLAY|overlay) 		{ BEGIN PARAM; RETURN(tOVERLAY);      }
154 <START>(Property|PROPERTY|property)		{ BEGIN PARAM; RETURN(tPROPERTY);     }
155 <START>(Properties|PROPERTIES|properties)	{ BEGIN PARAM; RETURN(tPROPERTY);     }
156 
157 <START>(Group|GROUP|group)			{ BEGIN PARAM; RETURN(tGROUP);        }
158 <START>(Address|ADDRESS|address)		{ BEGIN PARAM; RETURN(tADDRESS);      }
159 <START>(After|AFTER|after)			{ BEGIN PARAM; RETURN(tAFTER);        }
160 <START>(Object|OBJECT|object)[sS]?		{ BEGIN PARAM; RETURN(tOBJECT);       }
161 <START>(Librar|LIBRAR|librar)(y|Y|ies|IES)?	{ BEGIN PARAM; RETURN(tLIBRARY);      }
162 <START>(Search|SEARCH|search)_?(Symbol|SYMBOL|symbol)[sS]? { BEGIN PARAM; RETURN(tSEARCHSYMBOL); }
163 <START>(Force|FORCE|force)			{ BEGIN PARAM; RETURN(tFORCE); }
164 <START>(StackSize|STACKSIZE|stacksize)		{ BEGIN PARAM; RETURN(tSTACKSIZE);    }
165 <START>(Compress|COMPRESS|compress)		{ BEGIN PARAM; RETURN(tCOMPRESS);    }
166 
167 <START>(OverlayDefs|OVERLAYDEFS|overlaydefs)	{ BEGIN PARAM; RETURN(tOVERLAYDEFS);  }
168 <START>(OverlayTable|OVERLAYTABLE|overlaytable)	{ BEGIN PARAM; RETURN(tOVERLAYTABLE); }
169 <START>(Sur?ffix|SUR?FFIX|sur?ffix)		{ BEGIN PARAM; RETURN(tSUFFIX);       }
170 
171 <PARAM>(ITCM|itcm|Itcm)		{
172 	spec_yylval.string = strdup("ITCM");
173 	RETURN(tSTRING_ID);
174 }
175 
176 <PARAM>(DTCM|dtcm|Dtcm)		{
177 	spec_yylval.string = strdup("DTCM");
178 	RETURN(tSTRING_ID);
179 }
180 
181 <PARAM>(WRAM|wram|Wram)		{
182 	spec_yylval.string = strdup("WRAM");
183 	RETURN(tSTRING_ID);
184 }
185 
186 <PARAM>(SMART|smart|Smart)		{
187 	spec_yylval.string = strdup("SMART");
188 	RETURN(tSTRING_ID);
189 }
190 
191 <PARAM>(EXCLUSION|exclusion|Exclusion)		{
192 	spec_yylval.string = strdup("EXCLUSION");
193 	RETURN(tSTRING_ID);
194 }
195 
196 <START>\{		{ BEGIN PARAM; RETURN(tBEGIN);        }
197 <START>\}		{ BEGIN PARAM; RETURN(tEND);          }
198 
199 <PARAM>{ws}*\\{ws}*{nl}	{ BEGIN PARAM_CONTINUE; }     	/* Continue to next line */
200 
201 <PARAM>\({identifier}*\,{ws}{identifier}.[oa]\)	{
202 	spec_yylval.string = strdup(spec_yytext);
203 	RETURN(tSTRING_FORCE);
204 }
205 
206 <PARAM>\({ws}*\.[a-z]*{ws}*\)	{
207 	spec_yylval.string = getSection();
208 	RETURN(tSECTIONNAME);
209 }
210 
211 <PARAM>\({ws}*\.[a-z]*\.[a-z]*{ws}*\)	{
212 	spec_yylval.string = getSection();
213 	RETURN(tSECTIONNAME);
214 }
215 
216 <PARAM>\*		{
217 	spec_yylval.string = strdup(spec_yytext);
218 	RETURN(tSTRING_STAR);
219 }
220 
221 <PARAM>GROUP\([^\)]*\)	{
222 	spec_yylval.string = strdup(spec_yytext);
223 	RETURN(tSTRING_GROUP);
224 }
225 
226 <PARAM>OBJECT\([^\)]*\)	{
227 	spec_yylval.string = strdup(spec_yytext);
228 	RETURN(tSTRING_FUNCTION);
229 }
230 
231 {decnum}		|
232 {octnum}		|
233 {hexnum}		{			/* Integer Value */
234 	spec_yylval.integer = strtol((char*)spec_yytext, (char**)NULL, 0);
235 	RETURN(tNUMBER);
236 }
237 
238 {identifier}		{		       	/* String for identifier */
239 	spec_yylval.string = strdup(spec_yytext);
240 	RETURN(tSTRING_ID);
241 }
242 
243 {qstring}		{		       	/* String quated by "" */
244 	spec_yytext[spec_yyleng-1] = '\0';
245 	spec_yylval.string = strdup(spec_yytext+1);
246 	RETURN(tSTRING_QUATED);
247 }
248 
249 {string_wo_ws}		{			/* String without white space */
250 	spec_yylval.string = strdup(spec_yytext);
251 	RETURN(tSTRING_NOSPACE);
252 }
253 
254 <PARAM><<EOF>>		{ BEGIN INITIAL; RETURN(tNL); }	/* End of File */
255 
256 {nl}			{ BEGIN INITIAL; RETURN(tNL); }	/* Newline     */
257 {ws}+			;	       			/* Whitespace */
258 .			{ RETURN(spec_yytext[0]);     }	/* Default     */
259 
260 %%
261 
262 /*============================================================================
263  *  Utilities
264  */
265 void  spec_yyerror( const char* str )
266 {
267     int  line = spec_yylineno;
268     if ( spec_yytext[0] == '\n' ) line --;
269     fprintf( stderr, "makelcf: line %d: %s\n", line, str );
270 }
271 
272 static char* getSection( void )
273 {
274     char*  p;
275     char*  head = NULL;
276 
277     for ( p = spec_yytext; *p; p ++ )
278     {
279 	switch ( *p )
280 	{
281 	case '(':
282 	    while ( *p == ' ' ) p ++;
283 	    head = p + 1;
284 	    break;
285 
286 	case ')':
287 	case ' ':
288 	    if ( head )
289             {
290 	        *p = '\0';
291 		return strdup( head );
292             }
293 	    break;
294 
295 	default:
296 	    break;
297 	}
298     }
299     return strdup( "*" );
300 }
301 
302 static void  YYText_ResolveDevVal( void )
303 {
304     int   i;
305     char* s = ResolveDefVal( spec_yytext );
306 
307     for ( i = strlen(s)-1; i >= 0; i -- )
308     {
309     	unput( s[i] );
310     }
311     free(s);
312     return;
313 }
314 
315 /*============================================================================
316  *  PARSE SPEC FILE
317  */
318 int  ParseSpecFile( const char* filename )
319 {
320     FILE *fp;
321     int   result;
322 
323     if ( NULL == ( fp = fopen( filename, "r" ) ) )
324     {
325 	fprintf( stderr, "makelcf: cannot open %s\n", filename );
326 	return 2;
327     }
328 
329     spec_yyin = fp;
330     result = spec_yyparse();
331     fclose( fp );
332     if ( result ) return 1;
333 
334     return CheckSpec() ? 0 : 1;
335 }
336