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>(StackSize|STACKSIZE|stacksize)		{ BEGIN PARAM; RETURN(tSTACKSIZE);    }
164 
165 <START>(OverlayDefs|OVERLAYDEFS|overlaydefs)	{ BEGIN PARAM; RETURN(tOVERLAYDEFS);  }
166 <START>(OverlayTable|OVERLAYTABLE|overlaytable)	{ BEGIN PARAM; RETURN(tOVERLAYTABLE); }
167 <START>(Sur?ffix|SUR?FFIX|sur?ffix)		{ BEGIN PARAM; RETURN(tSUFFIX);       }
168 
169 <PARAM>(ITCM|itcm|Itcm)		{
170 	spec_yylval.string = strdup("ITCM");
171 	RETURN(tSTRING_ID);
172 }
173 
174 <PARAM>(DTCM|dtcm|Dtcm)		{
175 	spec_yylval.string = strdup("DTCM");
176 	RETURN(tSTRING_ID);
177 }
178 
179 <PARAM>(WRAM|wram|Wram)		{
180 	spec_yylval.string = strdup("WRAM");
181 	RETURN(tSTRING_ID);
182 }
183 
184 <START>\{		{ BEGIN PARAM; RETURN(tBEGIN);        }
185 <START>\}		{ BEGIN PARAM; RETURN(tEND);          }
186 
187 <PARAM>{ws}*\\{ws}*{nl}	{ BEGIN PARAM_CONTINUE; }     	/* Continue to next line */
188 
189 <PARAM>\({ws}*\.[a-z]*{ws}*\)	{
190 	spec_yylval.string = getSection();
191 	RETURN(tSECTIONNAME);
192 }
193 
194 <PARAM>\({ws}*\.[a-z]*\.[a-z]*{ws}*\)	{
195 	spec_yylval.string = getSection();
196 	RETURN(tSECTIONNAME);
197 }
198 
199 <PARAM>\*		{
200 	spec_yylval.string = strdup(spec_yytext);
201 	RETURN(tSTRING_STAR);
202 }
203 
204 <PARAM>GROUP\([^\)]*\)	{
205 	spec_yylval.string = strdup(spec_yytext);
206 	RETURN(tSTRING_GROUP);
207 }
208 
209 <PARAM>OBJECT\([^\)]*\)	{
210 	spec_yylval.string = strdup(spec_yytext);
211 	RETURN(tSTRING_FUNCTION);
212 }
213 
214 {decnum}		|
215 {octnum}		|
216 {hexnum}		{			/* Integer Value */
217 	spec_yylval.integer = strtol((char*)spec_yytext, (char**)NULL, 0);
218 	RETURN(tNUMBER);
219 }
220 
221 {identifier}		{		       	/* String for identifier */
222 	spec_yylval.string = strdup(spec_yytext);
223 	RETURN(tSTRING_ID);
224 }
225 
226 {qstring}		{		       	/* String quated by "" */
227 	spec_yytext[spec_yyleng-1] = '\0';
228 	spec_yylval.string = strdup(spec_yytext+1);
229 	RETURN(tSTRING_QUATED);
230 }
231 
232 {string_wo_ws}		{			/* String without white space */
233 	spec_yylval.string = strdup(spec_yytext);
234 	RETURN(tSTRING_NOSPACE);
235 }
236 
237 <PARAM><<EOF>>		{ BEGIN INITIAL; RETURN(tNL); }	/* End of File */
238 
239 {nl}			{ BEGIN INITIAL; RETURN(tNL); }	/* Newline     */
240 {ws}+			;	       			/* Whitespace */
241 .			{ RETURN(spec_yytext[0]);     }	/* Default     */
242 
243 %%
244 
245 /*============================================================================
246  *  Utilities
247  */
248 void  spec_yyerror( const char* str )
249 {
250     int  line = spec_yylineno;
251     if ( spec_yytext[0] == '\n' ) line --;
252     fprintf( stderr, "makelcf: line %d: %s\n", line, str );
253 }
254 
255 static char* getSection( void )
256 {
257     char*  p;
258     char*  head = NULL;
259 
260     for ( p = spec_yytext; *p; p ++ )
261     {
262 	switch ( *p )
263 	{
264 	case '(':
265 	    while ( *p == ' ' ) p ++;
266 	    head = p + 1;
267 	    break;
268 
269 	case ')':
270 	case ' ':
271 	    if ( head )
272             {
273 	        *p = '\0';
274 		return strdup( head );
275             }
276 	    break;
277 
278 	default:
279 	    break;
280 	}
281     }
282     return strdup( "*" );
283 }
284 
285 static void  YYText_ResolveDevVal( void )
286 {
287     int   i;
288     char* s = ResolveDefVal( spec_yytext );
289 
290     for ( i = strlen(s)-1; i >= 0; i -- )
291     {
292     	unput( s[i] );
293     }
294     free(s);
295     return;
296 }
297 
298 /*============================================================================
299  *  PARSE SPEC FILE
300  */
301 int  ParseSpecFile( const char* filename )
302 {
303     FILE *fp;
304     int   result;
305 
306     if ( NULL == ( fp = fopen( filename, "r" ) ) )
307     {
308 	fprintf( stderr, "makelcf: cannot open %s\n", filename );
309 	return 2;
310     }
311 
312     spec_yyin = fp;
313     result = spec_yyparse();
314     fclose( fp );
315     if ( result ) return 1;
316 
317     return CheckSpec() ? 0 : 1;
318 }
319