1 %{
2 /*---------------------------------------------------------------------------*
3 Project: TwlSDK - tools - makelcf
4 File: tlcf.y
5
6 Copyright 2003-2009 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:: 2009-06-04#$
15 $Rev: 10698 $
16 $Author: okubata_ryoma $
17 *---------------------------------------------------------------------------*/
18 #include <stdio.h>
19 #include <string.h>
20 #include "makelcf.h"
21 #include "defval.h"
22
23 // IF-ELSE-ENDIF
24 static tCondStack cond_stack[COND_STACK_MAX];
25 static int cond_stack_level = 0;
26 static BOOL cond_valid = TRUE;
27 static tCondBlock cond_block = COND_BLOCK_NOCOND;
28
GetCompResult(const char * id,const char * comp,const char * value,BOOL * pvalid)29 static BOOL GetCompResult(const char* id, const char* comp, const char* value, BOOL* pvalid)
30 {
31 int result;
32 BOOL valid;
33 const char* defval;
34
35 defval = SearchDefValCleaned(id);
36 result = strcmp(defval, value);
37 if ( strcmp( comp, ".EQ." ) == 0 || strcmp( comp, "==" ) == 0 ) valid = ( result == 0 );
38 else if ( strcmp( comp, ".NE." ) == 0 || strcmp( comp, "!=" ) == 0 ) valid = ( result != 0 );
39 else if ( strcmp( comp, ".GT." ) == 0 ) valid = ( result > 0 );
40 else if ( strcmp( comp, ".GE." ) == 0 ) valid = ( result >= 0 );
41 else if ( strcmp( comp, ".LT." ) == 0 ) valid = ( result < 0 );
42 else if ( strcmp( comp, ".LE." ) == 0 ) valid = ( result <= 0 );
43 else
44 {
45 tlcf_yyerror( "Illegal IF-condition" );
46 return FALSE;
47 }
48 debug_printf("id(%s)=[%s] comp=[%s] value=[%s] valid=%d\n", id, defval, comp, value, valid);
49
50 *pvalid = valid;
51 return TRUE;
52 }
53
CondIf(const char * id,const char * comp,const char * value)54 static BOOL CondIf(const char* id, const char* comp, const char* value)
55 {
56 if (cond_stack_level >= COND_STACK_MAX)
57 {
58 tlcf_yyerror( "Too deep if-else-endif block" );
59 return FALSE;
60 }
61 cond_stack[cond_stack_level].block = cond_block;
62 cond_stack[cond_stack_level].valid = cond_valid;
63 cond_stack_level ++;
64 cond_block = COND_BLOCK_IF;
65
66 // Update validation only if previous level validation is TRUE
67 if (cond_stack[cond_stack_level-1].valid)
68 {
69 if (!GetCompResult(id, comp, value, &cond_valid))
70 {
71 tlcf_yyerror( "Unresolved IF condition" );
72 return FALSE;
73 }
74 }
75 return TRUE;
76 }
77
CondElse(void)78 static BOOL CondElse(void)
79 {
80 if (cond_block != COND_BLOCK_IF || cond_stack_level <= 0)
81 {
82 tlcf_yyerror( "IF-ELSE-ENDIF unmatched" );
83 return FALSE;
84 }
85 cond_block = COND_BLOCK_ELSE;
86
87 // Update validation only if previous level validation is TRUE
88 if (cond_stack[cond_stack_level-1].valid)
89 {
90 cond_valid = cond_valid ? FALSE : TRUE; // Flip validation
91 }
92 return TRUE;
93 }
94
CondEndIf(void)95 static BOOL CondEndIf(void)
96 {
97 if ((cond_block != COND_BLOCK_IF && cond_block != COND_BLOCK_ELSE) || cond_stack_level <= 0)
98 {
99 tlcf_yyerror( "IF-ELSE-ENDIF unmatched" );
100 return FALSE;
101 }
102 cond_stack_level --;
103 cond_block = cond_stack[cond_stack_level].block;
104 cond_valid = cond_stack[cond_stack_level].valid;
105 return TRUE;
106 }
107
108
109 // TOKEN HANDLEING
110 tTokenBuffer tokenBuffer[TOKEN_LEN];
111 int tokenBufferEnd = 0;
112 static tLoopStack loop_stack[LOOP_STACK_MAX];
113 static int loop_stack_level = 0;
114
StoreToken(int id,const char * str)115 static BOOL StoreToken( int id, const char *str )
116 {
117 // Validation check for IF-ELSE-ENDIF
118 if ( !cond_valid ) return TRUE;
119
120 if ( tokenBufferEnd >= TOKEN_LEN )
121 {
122 tlcf_yyerror( "Out of token buffer" );
123 return FALSE;
124 }
125 tokenBuffer[tokenBufferEnd].id = id;
126 tokenBuffer[tokenBufferEnd].string = str;
127 tokenBufferEnd ++;
128 return TRUE;
129 }
130
PushLoopStack(int id,const char * sectionName)131 static BOOL PushLoopStack( int id, const char* sectionName )
132 {
133 // Validation check for IF-ELSE-ENDIF
134 if ( !cond_valid ) return TRUE;
135
136 if ( loop_stack_level >= LOOP_STACK_MAX )
137 {
138 tlcf_yyerror( "Out of stack level" );
139 return FALSE;
140 }
141 loop_stack[loop_stack_level].id = id;
142 loop_stack[loop_stack_level].start = tokenBufferEnd;
143 loop_stack_level ++;
144 return StoreToken( id, sectionName );
145 }
146
PopLoopStack(int id)147 static BOOL PopLoopStack( int id )
148 {
149 int start;
150
151 // Validation check for IF-ELSE-ENDIF
152 if ( !cond_valid ) return TRUE;
153
154 loop_stack_level --;
155 if ( loop_stack_level < 0 || id != loop_stack[loop_stack_level].id )
156 {
157 tlcf_yyerror( "Unmatched foreach-end" );
158 return FALSE;
159 }
160 start = loop_stack[loop_stack_level].start;
161 tokenBuffer[start].loop_end = tokenBufferEnd-1;
162
163 // Don't store 'END' token to TokenBuffer
164 return TRUE;
165 }
166
GetLoopStackLevel(void)167 BOOL GetLoopStackLevel( void )
168 {
169 return loop_stack_level;
170 }
171
172 %}
173
174 %union
175 {
176 char *string;
177 };
178
179 %token <string> tSTRING
180
181 %token <string> tFOREACH_STATIC_OBJECTS
182 %token <string> tFOREACH_STATIC_LIBRARIES
183 %token <string> tFOREACH_STATIC_SEARCHSYMBOLS
184 %token tEND_STATIC_OBJECTS
185 %token tEND_STATIC_LIBRARIES
186 %token tEND_STATIC_SEARCHSYMBOLS
187 %token tSTATIC_NAME
188 %token tSTATIC_ADDRESS
189 %token tSTATIC_STACKSIZE
190 %token tSTATIC_IRQSTACKSIZE
191 %token <string> tSTATIC_CRT0_OBJECT
192 %token <string> tSTATIC_OBJECT
193 %token <string> tSTATIC_LIBRARY
194 %token <string> tSTATIC_SEARCHSYMBOL
195
196 %token <string> tFOREACH_AUTOLOADS
197 %token <string> tFOREACH_AUTOLOAD_OBJECTS
198 %token <string> tFOREACH_AUTOLOAD_LIBRARIES
199 %token <string> tFOREACH_AUTOLOAD_SEARCHSYMBOLS
200 %token tEND_AUTOLOADS
201 %token tEND_AUTOLOAD_OBJECTS
202 %token tEND_AUTOLOAD_LIBRARIES
203 %token tEND_AUTOLOAD_SEARCHSYMBOLS
204 %token tNUMBER_AUTOLOADS
205 %token tAUTOLOAD_ID
206 %token tAUTOLOAD_NAME
207 %token tAUTOLOAD_ADDRESS
208 %token <string> tAUTOLOAD_OBJECT
209 %token <string> tAUTOLOAD_LIBRARY
210 %token <string> tAUTOLOAD_SEARCHSYMBOL
211
212 %token <string> tFOREACH_OVERLAYS
213 %token <string> tFOREACH_OVERLAY_OBJECTS
214 %token <string> tFOREACH_OVERLAY_LIBRARIES
215 %token <string> tFOREACH_OVERLAY_SEARCHSYMBOLS
216 %token tEND_OVERLAYS
217 %token tEND_OVERLAY_OBJECTS
218 %token tEND_OVERLAY_LIBRARIES
219 %token tEND_OVERLAY_SEARCHSYMBOLS
220 %token tNUMBER_OVERLAYS
221 %token tOVERLAY_ID
222 %token tOVERLAY_NAME
223 %token tOVERLAY_GROUP
224 %token tOVERLAY_ADDRESS
225 %token <string> tOVERLAY_OBJECT
226 %token <string> tOVERLAY_LIBRARY
227 %token <string> tOVERLAY_SEARCHSYMBOL
228
229 %token <string> tFOREACH_LTDAUTOLOADS
230 %token <string> tFOREACH_LTDAUTOLOAD_OBJECTS
231 %token <string> tFOREACH_LTDAUTOLOAD_LIBRARIES
232 %token <string> tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS
233 %token tEND_LTDAUTOLOADS
234 %token tEND_LTDAUTOLOAD_OBJECTS
235 %token tEND_LTDAUTOLOAD_LIBRARIES
236 %token tEND_LTDAUTOLOAD_SEARCHSYMBOLS
237 %token tNUMBER_LTDAUTOLOADS
238 %token tLTDAUTOLOAD_ID
239 %token tLTDAUTOLOAD_NAME
240 %token tLTDAUTOLOAD_ADDRESS
241 %token <string> tLTDAUTOLOAD_OBJECT
242 %token <string> tLTDAUTOLOAD_LIBRARY
243 %token <string> tLTDAUTOLOAD_SEARCHSYMBOL
244
245 %token <string> tFOREACH_LTDOVERLAYS
246 %token <string> tFOREACH_LTDOVERLAY_OBJECTS
247 %token <string> tFOREACH_LTDOVERLAY_LIBRARIES
248 %token <string> tFOREACH_LTDOVERLAY_SEARCHSYMBOLS
249 %token tEND_LTDOVERLAYS
250 %token tEND_LTDOVERLAY_OBJECTS
251 %token tEND_LTDOVERLAY_LIBRARIES
252 %token tEND_LTDOVERLAY_SEARCHSYMBOLS
253 %token tNUMBER_LTDOVERLAYS
254 %token tLTDOVERLAY_ID
255 %token tLTDOVERLAY_NAME
256 %token tLTDOVERLAY_GROUP
257 %token tLTDOVERLAY_ADDRESS
258 %token <string> tLTDOVERLAY_OBJECT
259 %token <string> tLTDOVERLAY_LIBRARY
260 %token <string> tLTDOVERLAY_SEARCHSYMBOL
261
262 %token tPROPERTY_OVERLAYDEFS
263 %token tPROPERTY_OVERLAYTABLE
264 %token tPROPERTY_LTDOVERLAYDEFS
265 %token tPROPERTY_LTDOVERLAYTABLE
266 %token tPROPERTY_SUFFIX
267 %token tPROPERTY_FLXSUFFIX
268 %token tPROPERTY_LTDSUFFIX
269
270 %token tIF_OPEN
271 %token tIF_CLOSE
272 %token <string> tIF_ID
273 %token <string> tIF_COMP
274 %token <string> tIF_VALUE
275 %token tIF_ELSE
276 %token tIF_ENDIF
277 %%
278
279 /*=========================================================================*
280 ConfigFile
281 *=========================================================================*/
282
283 tlcfFile : tokens
284 ;
285
286 tokens : /*NULL*/
287 | tokens token
288 ;
289
290 token : tSTRING { if (!StoreToken( tSTRING, $1 )) YYABORT; }
291 | tSTATIC_CRT0_OBJECT { if (!StoreToken( tSTATIC_CRT0_OBJECT, $1 )) YYABORT; }
292 | tSTATIC_NAME { if (!StoreToken( tSTATIC_NAME, NULL )) YYABORT; }
293 | tSTATIC_ADDRESS { if (!StoreToken( tSTATIC_ADDRESS, NULL )) YYABORT; }
294 | tSTATIC_OBJECT { if (!StoreToken( tSTATIC_OBJECT, $1 )) YYABORT; }
295 | tSTATIC_LIBRARY { if (!StoreToken( tSTATIC_LIBRARY, $1 )) YYABORT; }
296 | tSTATIC_SEARCHSYMBOL { if (!StoreToken( tSTATIC_SEARCHSYMBOL, $1 )) YYABORT; }
297 | tSTATIC_STACKSIZE { if (!StoreToken( tSTATIC_STACKSIZE, NULL )) YYABORT; }
298 | tSTATIC_IRQSTACKSIZE { if (!StoreToken( tSTATIC_IRQSTACKSIZE, NULL )) YYABORT; }
299 | tFOREACH_STATIC_OBJECTS { if (!PushLoopStack( tFOREACH_STATIC_OBJECTS, $1 )) YYABORT; }
300 | tEND_STATIC_OBJECTS { if (!PopLoopStack ( tFOREACH_STATIC_OBJECTS )) YYABORT; }
301 | tFOREACH_STATIC_LIBRARIES { if (!PushLoopStack( tFOREACH_STATIC_LIBRARIES, $1 )) YYABORT; }
302 | tEND_STATIC_LIBRARIES { if (!PopLoopStack ( tFOREACH_STATIC_LIBRARIES )) YYABORT; }
303 | tFOREACH_STATIC_SEARCHSYMBOLS { if (!PushLoopStack( tFOREACH_STATIC_SEARCHSYMBOLS, $1 )) YYABORT; }
304 | tEND_STATIC_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_STATIC_SEARCHSYMBOLS )) YYABORT; }
305 | tAUTOLOAD_ID { if (!StoreToken( tAUTOLOAD_ID, NULL )) YYABORT; }
306 | tAUTOLOAD_NAME { if (!StoreToken( tAUTOLOAD_NAME, NULL )) YYABORT; }
307 | tAUTOLOAD_ADDRESS { if (!StoreToken( tAUTOLOAD_ADDRESS, NULL )) YYABORT; }
308 | tAUTOLOAD_OBJECT { if (!StoreToken( tAUTOLOAD_OBJECT, $1 )) YYABORT; }
309 | tAUTOLOAD_LIBRARY { if (!StoreToken( tAUTOLOAD_LIBRARY, $1 )) YYABORT; }
310 | tAUTOLOAD_SEARCHSYMBOL { if (!StoreToken( tAUTOLOAD_SEARCHSYMBOL, $1 )) YYABORT; }
311 | tNUMBER_AUTOLOADS { if (!StoreToken( tNUMBER_AUTOLOADS, NULL )) YYABORT; }
312 | tFOREACH_AUTOLOADS { if (!PushLoopStack( tFOREACH_AUTOLOADS, $1 )) YYABORT; }
313 | tEND_AUTOLOADS { if (!PopLoopStack ( tFOREACH_AUTOLOADS )) YYABORT; }
314 | tFOREACH_AUTOLOAD_OBJECTS { if (!PushLoopStack( tFOREACH_AUTOLOAD_OBJECTS, $1 )) YYABORT; }
315 | tEND_AUTOLOAD_OBJECTS { if (!PopLoopStack ( tFOREACH_AUTOLOAD_OBJECTS )) YYABORT; }
316 | tFOREACH_AUTOLOAD_LIBRARIES { if (!PushLoopStack( tFOREACH_AUTOLOAD_LIBRARIES, $1 )) YYABORT; }
317 | tEND_AUTOLOAD_LIBRARIES { if (!PopLoopStack ( tFOREACH_AUTOLOAD_LIBRARIES )) YYABORT; }
318 | tFOREACH_AUTOLOAD_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_AUTOLOAD_SEARCHSYMBOLS, $1 )) YYABORT; }
319 | tEND_AUTOLOAD_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_AUTOLOAD_SEARCHSYMBOLS )) YYABORT; }
320 | tOVERLAY_ID { if (!StoreToken( tOVERLAY_ID, NULL )) YYABORT; }
321 | tOVERLAY_NAME { if (!StoreToken( tOVERLAY_NAME, NULL )) YYABORT; }
322 | tOVERLAY_GROUP { if (!StoreToken( tOVERLAY_GROUP, NULL )) YYABORT; }
323 | tOVERLAY_ADDRESS { if (!StoreToken( tOVERLAY_ADDRESS, NULL )) YYABORT; }
324 | tOVERLAY_OBJECT { if (!StoreToken( tOVERLAY_OBJECT, $1 )) YYABORT; }
325 | tOVERLAY_LIBRARY { if (!StoreToken( tOVERLAY_LIBRARY, $1 )) YYABORT; }
326 | tOVERLAY_SEARCHSYMBOL { if (!StoreToken( tOVERLAY_SEARCHSYMBOL, $1 )) YYABORT; }
327 | tNUMBER_OVERLAYS { if (!StoreToken( tNUMBER_OVERLAYS, NULL )) YYABORT; }
328 | tFOREACH_OVERLAYS { if (!PushLoopStack( tFOREACH_OVERLAYS, $1 )) YYABORT; }
329 | tEND_OVERLAYS { if (!PopLoopStack ( tFOREACH_OVERLAYS )) YYABORT; }
330 | tFOREACH_OVERLAY_OBJECTS { if (!PushLoopStack( tFOREACH_OVERLAY_OBJECTS, $1 )) YYABORT; }
331 | tEND_OVERLAY_OBJECTS { if (!PopLoopStack ( tFOREACH_OVERLAY_OBJECTS )) YYABORT; }
332 | tFOREACH_OVERLAY_LIBRARIES { if (!PushLoopStack( tFOREACH_OVERLAY_LIBRARIES, $1 )) YYABORT; }
333 | tEND_OVERLAY_LIBRARIES { if (!PopLoopStack ( tFOREACH_OVERLAY_LIBRARIES )) YYABORT; }
334 | tFOREACH_OVERLAY_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_OVERLAY_SEARCHSYMBOLS, $1 )) YYABORT; }
335 | tEND_OVERLAY_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_OVERLAY_SEARCHSYMBOLS )) YYABORT; }
336 | tLTDAUTOLOAD_ID { if (!StoreToken( tLTDAUTOLOAD_ID, NULL )) YYABORT; }
337 | tLTDAUTOLOAD_NAME { if (!StoreToken( tLTDAUTOLOAD_NAME, NULL )) YYABORT; }
338 | tLTDAUTOLOAD_ADDRESS { if (!StoreToken( tLTDAUTOLOAD_ADDRESS, NULL )) YYABORT; }
339 | tLTDAUTOLOAD_OBJECT { if (!StoreToken( tLTDAUTOLOAD_OBJECT, $1 )) YYABORT; }
340 | tLTDAUTOLOAD_LIBRARY { if (!StoreToken( tLTDAUTOLOAD_LIBRARY, $1 )) YYABORT; }
341 | tLTDAUTOLOAD_SEARCHSYMBOL { if (!StoreToken( tLTDAUTOLOAD_SEARCHSYMBOL, $1 )) YYABORT; }
342 | tNUMBER_LTDAUTOLOADS { if (!StoreToken( tNUMBER_LTDAUTOLOADS, NULL )) YYABORT; }
343 | tFOREACH_LTDAUTOLOADS { if (!PushLoopStack( tFOREACH_LTDAUTOLOADS, $1 )) YYABORT; }
344 | tEND_LTDAUTOLOADS { if (!PopLoopStack ( tFOREACH_LTDAUTOLOADS )) YYABORT; }
345 | tFOREACH_LTDAUTOLOAD_OBJECTS { if (!PushLoopStack( tFOREACH_LTDAUTOLOAD_OBJECTS, $1 )) YYABORT; }
346 | tEND_LTDAUTOLOAD_OBJECTS { if (!PopLoopStack ( tFOREACH_LTDAUTOLOAD_OBJECTS )) YYABORT; }
347 | tFOREACH_LTDAUTOLOAD_LIBRARIES { if (!PushLoopStack( tFOREACH_LTDAUTOLOAD_LIBRARIES, $1 )) YYABORT; }
348 | tEND_LTDAUTOLOAD_LIBRARIES { if (!PopLoopStack ( tFOREACH_LTDAUTOLOAD_LIBRARIES )) YYABORT; }
349 | tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS, $1 )) YYABORT; }
350 | tEND_LTDAUTOLOAD_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS )) YYABORT; }
351 | tLTDOVERLAY_ID { if (!StoreToken( tLTDOVERLAY_ID, NULL )) YYABORT; }
352 | tLTDOVERLAY_NAME { if (!StoreToken( tLTDOVERLAY_NAME, NULL )) YYABORT; }
353 | tLTDOVERLAY_GROUP { if (!StoreToken( tLTDOVERLAY_GROUP, NULL )) YYABORT; }
354 | tLTDOVERLAY_ADDRESS { if (!StoreToken( tLTDOVERLAY_ADDRESS, NULL )) YYABORT; }
355 | tLTDOVERLAY_OBJECT { if (!StoreToken( tLTDOVERLAY_OBJECT, $1 )) YYABORT; }
356 | tLTDOVERLAY_LIBRARY { if (!StoreToken( tLTDOVERLAY_LIBRARY, $1 )) YYABORT; }
357 | tLTDOVERLAY_SEARCHSYMBOL { if (!StoreToken( tLTDOVERLAY_SEARCHSYMBOL, $1 )) YYABORT; }
358 | tNUMBER_LTDOVERLAYS { if (!StoreToken( tNUMBER_LTDOVERLAYS, NULL )) YYABORT; }
359 | tFOREACH_LTDOVERLAYS { if (!PushLoopStack( tFOREACH_LTDOVERLAYS, $1 )) YYABORT; }
360 | tEND_LTDOVERLAYS { if (!PopLoopStack ( tFOREACH_LTDOVERLAYS )) YYABORT; }
361 | tFOREACH_LTDOVERLAY_OBJECTS { if (!PushLoopStack( tFOREACH_LTDOVERLAY_OBJECTS, $1 )) YYABORT; }
362 | tEND_LTDOVERLAY_OBJECTS { if (!PopLoopStack ( tFOREACH_LTDOVERLAY_OBJECTS )) YYABORT; }
363 | tFOREACH_LTDOVERLAY_LIBRARIES { if (!PushLoopStack( tFOREACH_LTDOVERLAY_LIBRARIES, $1 )) YYABORT; }
364 | tEND_LTDOVERLAY_LIBRARIES { if (!PopLoopStack ( tFOREACH_LTDOVERLAY_LIBRARIES )) YYABORT; }
365 | tFOREACH_LTDOVERLAY_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_LTDOVERLAY_SEARCHSYMBOLS, $1 )) YYABORT; }
366 | tEND_LTDOVERLAY_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_LTDOVERLAY_SEARCHSYMBOLS )) YYABORT; }
367 | tPROPERTY_OVERLAYDEFS { if (!StoreToken( tPROPERTY_OVERLAYDEFS, NULL )) YYABORT; }
368 | tPROPERTY_OVERLAYTABLE { if (!StoreToken( tPROPERTY_OVERLAYTABLE, NULL )) YYABORT; }
369 | tPROPERTY_LTDOVERLAYDEFS { if (!StoreToken( tPROPERTY_LTDOVERLAYDEFS, NULL )) YYABORT; }
370 | tPROPERTY_LTDOVERLAYTABLE { if (!StoreToken( tPROPERTY_LTDOVERLAYTABLE, NULL )) YYABORT; }
371 | tPROPERTY_SUFFIX { if (!StoreToken( tPROPERTY_SUFFIX, NULL )) YYABORT; }
372 | tPROPERTY_FLXSUFFIX { if (!StoreToken( tPROPERTY_FLXSUFFIX, NULL )) YYABORT; }
373 | tPROPERTY_LTDSUFFIX { if (!StoreToken( tPROPERTY_LTDSUFFIX, NULL )) YYABORT; }
374 | cond_if | cond_else | cond_endif
375 ;
376
377 cond_if : tIF_OPEN tIF_ID tIF_COMP tIF_VALUE tIF_CLOSE { if (!CondIf( $2, $3, $4 )) YYABORT; }
378 | tIF_OPEN tIF_ID tIF_COMP tIF_CLOSE { if (!CondIf( $2, $3, "" )) YYABORT; }
379 ;
380
381 cond_else : tIF_ELSE { if (!CondElse()) YYABORT; }
382 ;
383
384 cond_endif : tIF_ENDIF { if (!CondEndIf()) YYABORT; }
385 ;
386
387 %%
388