1 %{
2 /*---------------------------------------------------------------------------*
3   Project:  TwlSDK - 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   $Date:: 2008-09-18#$
15   $Rev: 8573 $
16   $Author: okubata_ryoma $
17  *---------------------------------------------------------------------------*/
18 #include	<stdio.h>
19 #include	<string.h>
20 #include	"makelcf.h"
21 #include	"defval.h"
22 #include	"spec.tab.h"
23 
24 #define	RETURN(x) { debug_printf( "%s [%s]\n", #x, spec_yytext ); return(x); }
25 
26 static void  YYText_ResolveDevVal( void );
27 static char* getSection( void );
28 
29 
30 %}
31 
32 ws			[ \t]
33 nl			\r?\n
34 identifier		[A-Za-z_][A-Za-z_0-9]*
35 decnum			-?[1-9][0-9]*
36 octnum			-?0[0-7]*
37 hexnum			-?0[xX][0-9A-Fa-f]+
38 qstring			\"[^\"\n\r]*\"
39 string_wo_ws		[^ \t\n\r]+
40 
41 %s START
42 %s PARAM
43 %s PARAM_CONTINUE
44 %option pointer
45 %option yylineno
46 %option noyywrap
47 %%
48 
49  //======================================================================
50  //    SPEC TOKENS
51  //======================================================================
52 
53 #.*			;					/* Comment */
54 \/\/.*			;					/* Comment */
55 
56 <INITIAL>.*	{
57 	YYText_ResolveDevVal();
58 	BEGIN START;
59 }
60 
61 <PARAM_CONTINUE>.*	{
62 	YYText_ResolveDevVal();
63 	BEGIN PARAM;
64 }
65 
66 <START>(Static|STATIC|static)	 		{ BEGIN PARAM; RETURN(tSTATIC);       }
67 <START>(Autoload|AUTOLOAD|autoload) 		{ BEGIN PARAM; RETURN(tAUTOLOAD);     }
68 <START>(Overlay|OVERLAY|overlay) 		{ BEGIN PARAM; RETURN(tOVERLAY);      }
69 <START>(Ltd|LTD|ltd)(Autoload|AUTOLOAD|autoload)	{ BEGIN PARAM; RETURN(tLTDAUTOLOAD); }
70 <START>(Ltd|LTD|ltd)(Overlay|OVERLAY|overlay)	{ BEGIN PARAM; RETURN(tLTDOVERLAY); }
71 <START>(Property|PROPERTY|property)		{ BEGIN PARAM; RETURN(tPROPERTY);     }
72 <START>(Properties|PROPERTIES|properties)	{ BEGIN PARAM; RETURN(tPROPERTY);     }
73 
74 <START>(Group|GROUP|group)			{ BEGIN PARAM; RETURN(tGROUP);        }
75 <START>(Address|ADDRESS|address)		{ BEGIN PARAM; RETURN(tADDRESS);      }
76 <START>(After|AFTER|after)			{ BEGIN PARAM; RETURN(tAFTER);        }
77 <START>(Object|OBJECT|object)[sS]?		{ BEGIN PARAM; RETURN(tOBJECT);       }
78 <START>(Librar|LIBRAR|librar)(y|Y|ies|IES)?	{ BEGIN PARAM; RETURN(tLIBRARY);      }
79 <START>(Search|SEARCH|search)_?(Symbol|SYMBOL|symbol)[sS]? { BEGIN PARAM; RETURN(tSEARCHSYMBOL); }
80 <START>(StackSize|STACKSIZE|stacksize)		{ BEGIN PARAM; RETURN(tSTACKSIZE);    }
81 
82 <START>(OverlayDefs|OVERLAYDEFS|overlaydefs)	{ BEGIN PARAM; RETURN(tOVERLAYDEFS);  }
83 <START>(OverlayTable|OVERLAYTABLE|overlaytable)	{ BEGIN PARAM; RETURN(tOVERLAYTABLE); }
84 <START>(Ltd|LTD|ltd)(OverlayDefs|OVERLAYDEFS|overlaydefs)	{ BEGIN PARAM; RETURN(tLTDOVERLAYDEFS); }
85 <START>(Ltd|LTD|ltd)(OverlayTable|OVERLAYTABLE|overlaytable)	{ BEGIN PARAM; RETURN(tLTDOVERLAYTABLE); }
86 <START>(Sur?ffix|SUR?FFIX|sur?ffix)		{ BEGIN PARAM; RETURN(tSUFFIX);       }
87 <START>(Flx|FLX|flx)(Sur?ffix|SUR?FFIX|sur?ffix)	{ BEGIN PARAM; RETURN(tFLXSUFFIX); }
88 <START>(Ltd|LTD|ltd)(Sur?ffix|SUR?FFIX|sur?ffix)	{ BEGIN PARAM; RETURN(tLTDSUFFIX); }
89 
90 <PARAM>(ITCM|itcm|Itcm)		{
91 	spec_yylval.string = strdup("ITCM");
92 	RETURN(tSTRING_ID);
93 }
94 
95 <PARAM>(DTCM|dtcm|Dtcm)		{
96 	spec_yylval.string = strdup("DTCM");
97 	RETURN(tSTRING_ID);
98 }
99 
100 <PARAM>(WRAM|wram|Wram)		{
101 	spec_yylval.string = strdup("WRAM");
102 	RETURN(tSTRING_ID);
103 }
104 
105 <START>\{		{ BEGIN PARAM; RETURN(tBEGIN);        }
106 <START>\}		{ BEGIN PARAM; RETURN(tEND);          }
107 
108 <PARAM>{ws}*\\{ws}*{nl}	{ BEGIN PARAM_CONTINUE; }     	/* Continue to next line */
109 
110 <PARAM>\({ws}*\.[a-z]*{ws}*\)	{
111 	spec_yylval.string = getSection();
112 	RETURN(tSECTIONNAME);
113 }
114 
115 <PARAM>\({ws}*\.[a-z]*\.[a-z]*{ws}*\)	{
116 	spec_yylval.string = getSection();
117 	RETURN(tSECTIONNAME);
118 }
119 
120 <PARAM>\*		{
121 	spec_yylval.string = strdup(spec_yytext);
122 	RETURN(tSTRING_STAR);
123 }
124 
125 <PARAM>GROUP\([^\)]*\)	{
126 	spec_yylval.string = strdup(spec_yytext);
127 	RETURN(tSTRING_GROUP);
128 }
129 
130 <PARAM>OBJECT\([^\)]*\)	{
131 	spec_yylval.string = strdup(spec_yytext);
132 	RETURN(tSTRING_FUNCTION);
133 }
134 
135 {decnum}		|
136 {octnum}		|
137 {hexnum}		{			/* Integer Value */
138 	spec_yylval.integer = strtol((char*)spec_yytext, (char**)NULL, 0);
139 	RETURN(tNUMBER);
140 }
141 
142 {identifier}		{		       	/* String for identifier */
143 	spec_yylval.string = strdup(spec_yytext);
144 	RETURN(tSTRING_ID);
145 }
146 
147 {qstring}		{		       	/* String quated by "" */
148 	spec_yytext[spec_yyleng-1] = '\0';
149 	spec_yylval.string = strdup(spec_yytext+1);
150 	RETURN(tSTRING_QUATED);
151 }
152 
153 {string_wo_ws}		{			/* String without white space */
154 	spec_yylval.string = strdup(spec_yytext);
155 	RETURN(tSTRING_NOSPACE);
156 }
157 
158 <PARAM><<EOF>>		{ BEGIN INITIAL; RETURN(tNL); }	/* End of File */
159 
160 {nl}			{ BEGIN INITIAL; RETURN(tNL); }	/* Newline     */
161 {ws}+			;	       			/* White space */
162 .			{ RETURN(spec_yytext[0]);     }	/* Default     */
163 
164 %%
165 
166 /*============================================================================
167  *  Utilities
168  */
169 void  spec_yyerror( const char* str )
170 {
171     int  line = spec_yylineno;
172     if ( spec_yytext[0] == '\n' ) line --;
173     fprintf( stderr, "makelcf: line %d: %s\n", line, str );
174 }
175 
176 static char* getSection( void )
177 {
178     char*  p;
179     char*  head = NULL;
180 
181     for ( p = spec_yytext; *p; p ++ )
182     {
183 	switch ( *p )
184 	{
185 	case '(':
186 	    while ( *p == ' ' ) p ++;
187 	    head = p + 1;
188 	    break;
189 
190 	case ')':
191 	case ' ':
192 	    if ( head )
193             {
194 	        *p = '\0';
195 		return strdup( head );
196             }
197 	    break;
198 
199 	default:
200 	    break;
201 	}
202     }
203     return strdup( "*" );
204 }
205 
206 static void  YYText_ResolveDevVal( void )
207 {
208     int   i;
209     char* s = ResolveDefVal( spec_yytext );
210 
211     for ( i = strlen(s)-1; i >= 0; i -- )
212     {
213     	unput( s[i] );
214     }
215     free(s);
216     return;
217 }
218 
219 /*============================================================================
220  *  PARSE SPEC FILE
221  */
222 int  ParseSpecFile( const char* filename )
223 {
224     FILE *fp;
225     int   result;
226 
227     if ( NULL == ( fp = fopen( filename, "r" ) ) )
228     {
229 	fprintf( stderr, "makelcf: cannot open %s\n", filename );
230 	return 2;
231     }
232 
233     spec_yyin = fp;
234     result = spec_yyparse();
235     fclose( fp );
236     if ( result ) return 1;
237 
238     return CheckSpec() ? 0 : 1;
239 }
240