xref: /AOO41X/main/rsc/source/parser/rscyacc.y (revision e26f32421ede4ae50ba26ef41f332da4ec2903b3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 %{
25 #if defined __GNUC__
26 #pragma GCC system_header
27 #elif defined __SUNPRO_CC
28 #pragma disable_warn
29 #endif
30 %}
31 
32 /* Compilerstack */
33 
34 %union {
35     Atom            varid;
36     struct {
37         Atom            hashid;
38         sal_Int32           nValue;
39     }               constname;
40     RscTop *        pClass;
41     RSCHEADER       header;
42     struct {
43         CLASS_DATA  pData;
44         RscTop *    pClass;
45     }               instance;
46     sal_Int32           value;
47     sal_uInt16          ushort;
48     short           exp_short;
49     char *          string;
50     sal_Bool            svbool;
51     REF_ENUM        copyref;
52     RscDefine     * defineele;
53     CharSet         charset;
54     RscExpType      macrostruct;
55 }
56 
57 /* Token */
58 %token <value>          NUMBER
59 %token <string>         SYMBOL
60 %token <defineele>      RSCDEFINE
61 %token <string>         STRING
62 %token <string>         INCLUDE_STRING
63 %token <character>      CHARACTER
64 %token <svbool>         BOOLEAN
65 
66 %token LINE
67 %token AUTO_ID
68 %token NOT
69 %token XSCALE
70 %token YSCALE
71 %token RGB
72 %token GEOMETRY
73 %token POSITION
74 %token DIMENSION
75 %token INZOOMOUTPUTSIZE
76 %token FLOATINGPOS
77 %token DEFINE
78 %token INCLUDE
79 %token MACROTARGET
80 %token DEFAULT
81 
82 
83 %token <pClass>         CLASSNAME
84 %token <varid>          VARNAME
85 %token <constname>      CONSTNAME
86 %token CLASS
87 %token EXTENDABLE
88 %token WRITEIFSET
89 
90 
91 %type  <macrostruct>    macro_expression
92 %type  <macrostruct>    id_expression
93 %type  <value>          long_expression
94 %type  <string>         string_multiline
95 
96 %type  <pClass>         type
97 %type  <pClass>         type_base
98 %type  <header>         class_header_body
99 %type  <header>         class_header
100 %type  <header>         var_header_class
101 %type  <copyref>        copy_ref
102 %type  <ushort>         type_flags
103 
104 
105 %left '|'
106 %left '&'
107 %left LEFTSHIFT RIGHTSHIFT
108 %left '+' '-'
109 %left '*' '/'
110 %left UNARYMINUS
111 %left UNARYPLUS
112 %left ','
113 %left '(' ')'
114 
115 
116 /*  Grammatik  */
117 
118 %start resource_definitions
119 
120 %%
121 
122 /********************** D E F I N I T I O N S ****************************/
123 resource_definitions
124   :
125   | resource_definitions resource_definition
126   | MACROTARGET macro_expression
127     {
128         RscExpType      aExpType;
129         sal_Int32           lValue;
130 
131         aExpType.cType = RSCEXP_NOTHING;
132         pExp = new RscExpression( aExpType, '+', $2 );
133         if( !pExp->Evaluate( &lValue ) )
134             pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() );
135     }
136   ;
137 
138 resource_definition
139   : line_number
140   | '#' DEFINE SYMBOL macro_expression
141     {
142         sal_Bool        bError = sal_False;
143 
144         if( $4.IsNumber() ){
145             if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
146                                        ByteString( $3 ),
147                                        $4.GetLong(), LIST_APPEND ) )
148                 bError = sal_True;
149         }
150         else if( $4.IsDefinition() ){
151             RscExpType      aExpType;
152             RscExpression * pExpr;
153 
154             aExpType.cType = RSCEXP_NOTHING;
155             aExpType.SetLong( 0 );
156             aExpType.cType = RSCEXP_LONG;
157             pExpr = new RscExpression( aExpType, '+', $4 );
158 
159             if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
160                                        ByteString( $3 ), pExpr, LIST_APPEND ) )
161                 bError = sal_True;
162         }
163         else if( $4.IsExpression() ){
164             if( !pTC->aFileTab.NewDef( pFI->GetFileIndex(),
165                                        ByteString( $3 ), $4.aExp.pExp,
166                                        LIST_APPEND ) )
167                 bError = sal_True;
168         }
169 
170         if( bError ){
171             pTC->pEH->Error( ERR_DECLAREDEFINE, NULL, RscId(), $3 );
172         }
173     }
174   | '#' DEFINE RSCDEFINE macro_expression
175     {
176         pTC->pEH->Error( ERR_DOUBLEDEFINE, NULL, RscId(), $3->GetName().GetBuffer() );
177     }
178   | '#' INCLUDE STRING
179     {
180     }
181   | '#' INCLUDE INCLUDE_STRING
182     {
183     }
184   | class_definition ';'
185     {
186 #ifdef D40
187             void * pMem;
188             pMem = rtl_allocateMemory( 20000 );
189             rtl_freeMemory( pMem );
190 #endif
191     }
192   | new_class_definition_header '{' new_class_definition_body '}' ';'
193   | new_class_definition_header ';'
194   ;
195 
196 new_class_definition_header
197   : CLASS SYMBOL id_expression ':' CLASSNAME
198     {
199         sal_Int32   lType;
200 
201         $3.Evaluate( &lType );
202 
203         // Klasse anlegen
204         Atom nId = pHS->getID( $2 );
205         pCurClass = new RscClass( nId, lType, $5 );
206         nCurMask = 1;
207         pTC->aNmTb.Put( nId, CLASSNAME, pCurClass );
208         pTC->GetRoot()->Insert( pCurClass );
209     }
210   | CLASS CLASSNAME id_expression ':' CLASSNAME
211     {
212         pCurClass = $2;
213         nCurMask = 1;
214     }
215   ;
216 
217 new_class_definition_body
218   :
219   | property_definition ';' new_class_definition_body
220   ;
221 
222 property_definition
223   : type_flags type SYMBOL
224   {
225     // Variable anlegen
226     Atom nId = pTC->aNmTb.Put( $3, VARNAME );
227     pCurClass->SetVariable( nId, $2, NULL, $1, nCurMask );
228     nCurMask <<= 1;
229   }
230   | type_flags type VARNAME
231   {
232     pCurClass->SetVariable( $3, $2, NULL, $1, nCurMask );
233     nCurMask <<= 1;
234   }
235   ;
236 
237 type_flags
238   : type_flags EXTENDABLE
239   {
240     $$ = $1 | VAR_EXTENDABLE;
241   }
242   | type_flags WRITEIFSET
243   {
244     $$ = $1 | VAR_SVDYNAMIC;
245   }
246   |
247   {
248     $$ = 0;
249   }
250   ;
251 
252 type
253   : type_base
254   {
255     $$ = $1;
256   }
257   | type_base '[' ']'
258   {
259     if( $1 )
260     {
261         ByteString aTypeName = pHS->getString( $1->GetId() );
262         aTypeName += "[]";
263         $$ = pTC->SearchType( pHS->getID( aTypeName.GetBuffer(), true ) );
264         if( !$$ )
265         {
266             RscCont * pCont;
267             pCont = new RscCont( pHS->getID( aTypeName.GetBuffer() ), RSC_NOTYPE );
268             pCont->SetTypeClass( $1 );
269             pTC->InsertType( pCont );
270             $$ = pCont;
271         }
272     }
273     else
274         $$ = NULL;
275   }
276   ;
277 
278 type_base
279   : CLASSNAME
280   {
281     $$ = $1;
282   }
283   | SYMBOL
284   {
285     RscTop * pType = pTC->SearchType( pHS->getID( $1, true ) );
286     if( !pType )
287         pTC->pEH->Error( ERR_NOTYPE, pCurClass, RscId() );
288     $$ = pType;
289   }
290   ;
291 
292 class_definition
293   : class_header class_body
294   {
295     if( TYPE_REF == $1.nTyp )
296         pTC->pEH->Error( ERR_REFNOTALLOWED, S.Top().pClass,
297                          RscId( $1.nName1 ) );
298     S.Pop();
299   }
300   | class_header
301   {
302     ERRTYPE aError;
303     RscId aRscId( $1.nName1 );
304 
305     if( TYPE_NOTHING == $1.nTyp && aRscId.IsId() )
306         aError = S.Top().pClass->SetRef( S.Top(), aRscId );
307     else if( TYPE_COPY == $1.nTyp )
308         aError = ERR_COPYNOTALLOWED;
309     if( aError.IsError() || aError.IsWarning() )
310         pTC->pEH->Error( aError, S.Top().pClass, aRscId );
311     S.Pop();
312   }
313   ;
314 
315 class_header
316   : class_header_body
317     {
318         if( !DoClassHeader( &$1, sal_False ) )
319             return( ERR_ERROR );
320         $$ = $1;
321     }
322   ;
323 
324 copy_ref
325   : '<'
326     {
327         $$ = TYPE_COPY;
328     }
329   | ','
330     {
331         $$ = TYPE_REF;
332     }
333   ;
334 
335 class_header_body
336   : CLASSNAME id_expression copy_ref CLASSNAME id_expression
337     {
338         $$.pClass = $1;
339         $$.nName1 = $2;
340         $$.nTyp = $3;
341         $$.pRefClass = $4;
342         $$.nName2 = $5;
343     }
344   | CLASSNAME id_expression copy_ref id_expression
345     {
346         $$.pClass = $1;
347         $$.nName1 = $2;
348         $$.nTyp = $3;
349         $$.pRefClass = NULL;
350         $$.nName2 = $4;
351     }
352   | CLASSNAME id_expression
353     {
354         $$.pClass = $1;
355         $$.nName1 = $2;
356         $$.nTyp = TYPE_NOTHING;
357         $$.pRefClass = NULL;
358         $$.nName2.cType = RSCEXP_NOTHING;
359     }
360   | CLASSNAME copy_ref id_expression
361     {
362         $$.pClass = $1;
363         $$.nName1.cType = RSCEXP_NOTHING;
364         $$.nTyp = $2;
365         $$.pRefClass = NULL;
366         $$.nName2 = $3;
367     }
368   | CLASSNAME copy_ref CLASSNAME id_expression
369     {
370         $$.pClass = $1;
371         $$.nName1.cType = RSCEXP_NOTHING;
372         $$.nTyp = $2;
373         $$.pRefClass = $3;
374         $$.nName2 = $4;
375     }
376   | CLASSNAME
377     {
378         $$.pClass = $1;
379         $$.nName1.cType = RSCEXP_NOTHING;
380         $$.nTyp = TYPE_NOTHING;
381         $$.nName2.cType = RSCEXP_NOTHING;
382     }
383   ;
384 
385 class_body
386   : '{' var_definitions '}'
387   | '{' '}'
388   | string_multiline
389     {
390         SetString( S.Top(), "TEXT", $1 );
391     }
392   ;
393 
394 var_definitions
395   : var_definition
396   | var_definitions var_definition
397   ;
398 
399 xy_mapmode
400   : CONSTNAME
401     {
402         SetConst( S.Top(), "_XYMAPMODE", $1.hashid, $1.nValue );
403     }
404   |
405   ;
406 
407 wh_mapmode
408   : CONSTNAME
409     {
410         SetConst( S.Top(), "_WHMAPMODE", $1.hashid, $1.nValue );
411     }
412   |
413   ;
414 
415 xywh_mapmode
416   : CONSTNAME
417     {
418         SetConst( S.Top(), "_XYMAPMODE", $1.hashid, $1.nValue );
419         SetConst( S.Top(), "_WHMAPMODE", $1.hashid, $1.nValue );
420     }
421   |
422   ;
423 
424 var_definition
425   : line_number
426   | var_header var_body ';'
427     {
428         S.Pop();
429     }
430   | class_definition ';'
431   | var_header_class class_body ';'
432     {
433         if( TYPE_REF == $1.nTyp )
434             pTC->pEH->Error( ERR_REFNOTALLOWED, S.Top().pClass,
435                              RscId( $1.nName1 ) );
436 
437         if( S.Top().pClass->GetCount( S.Top() ) )
438             pTC->pEH->Error( WRN_SUBINMEMBER, S.Top().pClass,
439                              RscId(  $1.nName1 ) );
440 
441         S.Pop();
442     }
443   | var_header_class ';'
444     {
445         ERRTYPE aError;
446         RscId aRscId( $1.nName1 );
447 
448         if( TYPE_NOTHING == $1.nTyp && aRscId.IsId() )
449             aError = S.Top().pClass->SetRef( S.Top(), aRscId );
450         else if( TYPE_COPY == $1.nTyp )
451             aError = ERR_COPYNOTALLOWED;
452         if( S.Top().pClass->GetCount( S.Top() ) )
453             aError = WRN_SUBINMEMBER;
454         if( aError.IsError() || aError.IsWarning() )
455             pTC->pEH->Error( aError, S.Top().pClass, aRscId );
456 
457         S.Pop();
458     }
459   | XSCALE '=' '(' long_expression ',' long_expression ')' ';'
460     {
461         SetNumber( S.Top(), "_XNUMERATOR", $4 );
462         SetNumber( S.Top(), "_XDENOMINATOR", $6 );
463     }
464   | YSCALE '=' '(' long_expression ',' long_expression ')' ';'
465     {
466         SetNumber( S.Top(), "_YNUMERATOR", $4 );
467         SetNumber( S.Top(), "_YDENOMINATOR", $6 );
468     }
469   | RGB '=' '(' long_expression ',' long_expression
470                 ',' long_expression ')' ';'
471     {
472         SetNumber( S.Top(), "RED", $4 );
473         SetNumber( S.Top(), "GREEN", $6 );
474         SetNumber( S.Top(), "BLUE", $8 );
475     }
476   | GEOMETRY '=' xywh_mapmode '(' long_expression ',' long_expression ','
477                         long_expression ',' long_expression ')' ';'
478     {
479         SetNumber( S.Top(), "_X", $5 );
480         SetNumber( S.Top(), "_Y", $7 );
481         SetNumber( S.Top(), "_WIDTH", $9 );
482         SetNumber( S.Top(), "_HEIGHT", $11 );
483     }
484   | POSITION '=' xy_mapmode '(' long_expression ',' long_expression
485                             ')' ';'
486     {
487         SetNumber( S.Top(), "_X", $5 );
488         SetNumber( S.Top(), "_Y", $7 );
489     }
490   | DIMENSION '=' wh_mapmode '(' long_expression ',' long_expression
491                              ')' ';'
492     {
493         SetNumber( S.Top(), "_WIDTH", $5 );
494         SetNumber( S.Top(), "_HEIGHT", $7 );
495     }
496   | INZOOMOUTPUTSIZE '=' CONSTNAME '(' long_expression ',' long_expression
497                              ')' ';'
498     {
499         SetConst( S.Top(), "_ZOOMINMAPMODE", $3.hashid, $3.nValue );
500         SetNumber( S.Top(), "_ZOOMINWIDTH", $5 );
501         SetNumber( S.Top(), "_ZOOMINHEIGHT", $7 );
502     }
503   | INZOOMOUTPUTSIZE '=' '(' long_expression ',' long_expression ')' ';'
504     {
505         SetNumber( S.Top(), "_ZOOMINWIDTH", $4 );
506         SetNumber( S.Top(), "_ZOOMINHEIGHT", $6 );
507     }
508   | FLOATINGPOS '=' CONSTNAME '(' long_expression ',' long_expression
509                              ')' ';'
510     {
511         SetConst( S.Top(),  "_FLOATINGPOSMAPMODE", $3.hashid, $3.nValue );
512         SetNumber( S.Top(), "_FLOATINGPOSX", $5 );
513         SetNumber( S.Top(), "_FLOATINGPOSY", $7 );
514     }
515   | FLOATINGPOS '=' '(' long_expression ',' long_expression ')' ';'
516     {
517         SetNumber( S.Top(), "_FLOATINGPOSX", $4 );
518         SetNumber( S.Top(), "_FLOATINGPOSY", $6 );
519     }
520   ;
521 
522 var_header_class
523   : VARNAME '=' class_header_body
524     {
525         RSCINST aInst;
526 
527         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST(), sal_False, $3.pClass );
528 
529         if( aInst.pData )
530             S.Push( aInst );
531         else
532         {
533             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
534                              pHS->getString( $1 )  );
535             return( ERR_ERROR );
536         };
537 
538         if( !DoClassHeader( &$3, sal_True ) )
539             return( ERR_ERROR );
540         $$ = $3;
541     }
542   | VARNAME '[' CONSTNAME ']' '=' class_header_body
543     {
544         RSCINST aInst;
545 
546         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() );
547 
548         if( aInst.pData )
549         {
550             ERRTYPE aError;
551             RSCINST aIdxInst;
552 
553             aError = aInst.pClass->GetArrayEle( aInst, $3.hashid, NULL, &aIdxInst );
554             if( aError.IsError() || aError.IsWarning() )
555                  pTC->pEH->Error( aError, S.Top().pClass, RscId() );
556             if( aError.IsError() )
557                 return( ERR_ERROR );
558             S.Push( aIdxInst );
559         }
560         else
561         {
562             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
563                              pHS->getString( $1 )  );
564             return( ERR_ERROR );
565         };
566         if( !DoClassHeader( &$6, sal_True ) )
567             return( ERR_ERROR );
568         $$ = $6;
569     }
570   | VARNAME '[' SYMBOL ']' '=' class_header_body
571     {
572         RSCINST aInst;
573 
574         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() );
575 
576         if( aInst.pData )
577         {
578             long nNewLang = pTC->AddLanguage( $3 );
579             ERRTYPE aError;
580             RSCINST aIdxInst;
581 
582             aError = aInst.pClass->GetArrayEle( aInst, nNewLang, NULL, &aIdxInst );
583             if( aError.IsError() || aError.IsWarning() )
584                  pTC->pEH->Error( aError, S.Top().pClass, RscId() );
585             if( aError.IsError() )
586                 return( ERR_ERROR );
587             S.Push( aIdxInst );
588         }
589         else
590         {
591             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
592                              pHS->getString( $1 )  );
593             return( ERR_ERROR );
594         };
595         if( !DoClassHeader( &$6, sal_True ) )
596             return( ERR_ERROR );
597         $$ = $6;
598     }
599   ;
600 
601 var_header
602   : VARNAME '='
603     {
604         RSCINST aInst;
605 
606         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() );
607 
608         if( aInst.pData )
609             S.Push( aInst );
610         else{
611             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
612                              pHS->getString( $1 )  );
613             return( ERR_ERROR );
614         };
615     }
616   | VARNAME '[' CONSTNAME ']' '='
617     {
618         RSCINST aInst;
619 
620         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() );
621 
622         if( aInst.pData )
623         {
624             ERRTYPE aError;
625             RSCINST aIdxInst;
626 
627             aError = aInst.pClass->GetArrayEle( aInst, $3.hashid, NULL, &aIdxInst );
628             if( aError.IsError() || aError.IsWarning() )
629                  pTC->pEH->Error( aError, S.Top().pClass, RscId() );
630             if( aError.IsError() )
631                 return( ERR_ERROR );
632             S.Push( aIdxInst );
633         }
634         else{
635             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
636                              pHS->getString( $1 )  );
637             return( ERR_ERROR );
638         };
639     }
640   | VARNAME '[' SYMBOL ']' '='
641     {
642         RSCINST aInst;
643 
644         aInst = S.Top().pClass->GetVariable( S.Top(), $1, RSCINST() );
645 
646         if( aInst.pData )
647         {
648             long nNewLang = pTC->AddLanguage( $3 );
649             ERRTYPE aError;
650             RSCINST aIdxInst;
651 
652             aError = aInst.pClass->GetArrayEle( aInst, nNewLang, NULL, &aIdxInst );
653             if( aError.IsError() || aError.IsWarning() )
654                  pTC->pEH->Error( aError, S.Top().pClass, RscId() );
655             if( aError.IsError() )
656                 return( ERR_ERROR );
657             S.Push( aIdxInst );
658         }
659         else{
660             pTC->pEH->Error( ERR_NOVARIABLENAME, S.Top().pClass, RscId(),
661                              pHS->getString( $1 )  );
662             return( ERR_ERROR );
663         };
664     }
665   ;
666 tupel_header0
667   :
668     {
669         RSCINST aInst;
670 
671         aInst = S.Top().pClass->GetTupelVar( S.Top(), 0, RSCINST() );
672         if( aInst.pData )
673             S.Push( aInst );
674         else
675         {
676             pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() );
677             return( ERR_ERROR );
678         };
679     }
680   ;
681 
682 tupel_header1
683   :
684     {
685         RSCINST aInst;
686 
687         aInst = S.Top().pClass->GetTupelVar( S.Top(), 1, RSCINST() );
688         if( aInst.pData )
689             S.Push( aInst );
690         else
691         {
692             pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() );
693             return( ERR_ERROR );
694         };
695     }
696   ;
697 
698 tupel_header2
699   :
700     {
701         RSCINST aInst;
702 
703         aInst = S.Top().pClass->GetTupelVar( S.Top(), 2, RSCINST() );
704         if( aInst.pData )
705             S.Push( aInst );
706         else
707         {
708             pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() );
709             return( ERR_ERROR );
710         };
711     }
712   ;
713 
714 tupel_header3
715   :
716     {
717         RSCINST aInst;
718 
719         aInst = S.Top().pClass->GetTupelVar( S.Top(), 3, RSCINST() );
720         if( !aInst.pData )
721         {
722             pTC->pEH->Error( ERR_NOTUPELNAME, S.Top().pClass, RscId() );
723             return( ERR_ERROR );
724         };
725         S.Push( aInst );
726     }
727   ;
728 
729 tupel_body
730   : var_body
731     {
732         S.Pop();
733     }
734   ;
735 
736 var_list_header
737   :
738     {
739         ERRTYPE aError;
740         RSCINST aInst;
741 
742         aError = S.Top().pClass->GetElement( S.Top(), RscId(),
743                                             NULL, RSCINST(), &aInst );
744         if( aError.IsError() || aError.IsWarning() )
745             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
746         if( aError.IsError() )
747         { // unbedingt Instanz auf den Stack bringen
748             aInst = S.Top().pClass->Create( NULL, RSCINST() );
749         }
750         S.Push( aInst );
751     }
752   ;
753 
754 list_body
755   : var_bodycomplex
756     {
757         S.Pop();
758     }
759   ;
760 
761 list_header
762   :
763     {
764         sal_uInt32 nCount = S.Top().pClass->GetCount( S.Top() );
765         sal_uInt32 i;
766 
767         for( i = nCount; i > 0; i-- )
768             S.Top().pClass->DeletePos( S.Top(), i -1 );
769     }
770   ;
771 
772 list
773   : list var_list_header list_body ';'
774   | list var_bodysimple ';'
775   | list class_definition ';'
776   | list line_number
777   |
778   ;
779 
780 var_bodysimple
781   : macro_expression
782     {
783         sal_Int32   l;
784         ERRTYPE aError;
785 
786         if( !$1.Evaluate( &l ) )
787             pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() );
788         else
789         {
790             aError = S.Top().pClass->SetRef( S.Top(), RscId( $1 ) );
791             if( aError.IsError() )
792             {
793                 aError.Clear();
794                 aError = S.Top().pClass->SetNumber( S.Top(), l );
795             }
796             if( aError.IsError() )
797             { // Aufwaertskompatible, Tupel probieren
798                 RSCINST aInst = GetFirstTupelEle( S.Top() );
799                 if( aInst.pData )
800                 {
801                     aError.Clear(); // Fehler zuruecksetzen
802                     aError = aInst.pClass->SetRef( aInst, RscId( $1 ) );
803                     if( aError.IsError() )
804                     {
805                         aError.Clear();
806                         aError = aInst.pClass->SetNumber( aInst, l );
807                     }
808                 }
809             }
810         }
811 
812         if( $1.IsExpression() )
813             delete $1.aExp.pExp;
814 
815         if( aError.IsError() || aError.IsWarning() )
816             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
817     }
818   | CONSTNAME
819     {
820         ERRTYPE aError;
821         aError = S.Top().pClass->SetConst( S.Top(), $1.hashid, $1.nValue );
822         if( aError.IsError() )
823         { // Aufwaertskompatible, Tupel probieren
824             RSCINST aInst = GetFirstTupelEle( S.Top() );
825             if( aInst.pData )
826             {
827                 aError.Clear(); // Fehler zuruecksetzen
828                 aError = aInst.pClass->SetConst( aInst, $1.hashid, $1.nValue );
829             }
830         }
831 
832         if( aError.IsError() || aError.IsWarning() )
833             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
834     }
835   | NOT CONSTNAME
836     {
837         ERRTYPE aError;
838         aError = S.Top().pClass->SetNotConst( S.Top(), $2.hashid );
839         if( aError.IsError() )
840         { // Aufwaertskompatible, Tupel probieren
841             RSCINST aInst = GetFirstTupelEle( S.Top() );
842             if( aInst.pData )
843             {
844                 aError.Clear(); // Fehler zuruecksetzen
845                 aError = aInst.pClass->SetNotConst( aInst, $2.hashid );
846             }
847         }
848 
849         if( aError.IsError() || aError.IsWarning() )
850             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
851     }
852   | BOOLEAN
853     {
854         ERRTYPE aError;
855         aError = S.Top().pClass->SetBool( S.Top(), $1 );
856         if( aError.IsError() )
857         { // Aufwaertskompatible, Tupel probieren
858             RSCINST aInst = GetFirstTupelEle( S.Top() );
859             if( aInst.pData )
860             {
861                 aError.Clear(); // Fehler zuruecksetzen
862                 aError = aInst.pClass->SetBool( aInst, $1 );
863             }
864         }
865 
866         if( aError.IsError() || aError.IsWarning() )
867             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
868     }
869   | string_multiline
870     {
871         ERRTYPE aError;
872         aError = S.Top().pClass->SetString( S.Top(), $1 );
873         if( aError.IsError() )
874         { // Aufwaertskompatible, Tupel probieren
875             RSCINST aInst = GetFirstTupelEle( S.Top() );
876             if( aInst.pData )
877             {
878                 aError.Clear(); // Fehler zuruecksetzen
879                 aError = aInst.pClass->SetString( aInst, $1 );
880             }
881         }
882 
883         if( aError.IsError() || aError.IsWarning() )
884             pTC->pEH->Error( aError, S.Top().pClass, RscId() );
885     }
886   | DEFAULT
887   ;
888 
889 var_bodycomplex
890   : '{' list_header list '}'
891   | '<' tupel_header0 tupel_body ';' '>'
892   | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';' '>'
893   | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';'
894         tupel_header2 tupel_body ';' '>'
895   | '<' tupel_header0 tupel_body ';' tupel_header1 tupel_body ';'
896         tupel_header2 tupel_body ';' tupel_header3 tupel_body ';' '>'
897   ;
898 
899 var_body
900   : var_bodysimple
901   | var_bodycomplex
902   ;
903 
904 /********************** work on yacc stack *******************************/
905 string_multiline
906   : STRING
907     {
908         $$ = $1;
909     }
910   | string_multiline STRING
911     {
912         rtl::OStringBuffer aBuf( 256 );
913         aBuf.append( $1 );
914         aBuf.append( $2 );
915         $$ = (char*)pStringContainer->putString( aBuf.getStr() );
916     }
917   ;
918 
919 long_expression
920   : macro_expression
921     {
922         if( !$1.Evaluate( &$$ ) )
923             pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() );
924         if( $1.IsExpression() )
925             delete $1.aExp.pExp;
926     }
927   ;
928 
929 macro_expression
930   : RSCDEFINE
931     {
932         $$.cType = RSCEXP_DEF;
933         $$.aExp.pDef = $1;
934     }
935   | NUMBER
936     {
937         $$.cType = RSCEXP_LONG;
938         $$.SetLong( $1 );
939     }
940   | '-' macro_expression %prec UNARYMINUS
941     {
942         if( $2.IsNumber() ){
943             $$.cType = $2.cType;
944             $$.SetLong( - $2.GetLong() );
945         }
946         else{
947             RscExpType aLeftExp;
948 
949             aLeftExp.cType = RSCEXP_NOTHING;
950             $$.cType = RSCEXP_EXP;
951             $$.aExp.pExp = new RscExpression( aLeftExp, '-', $2 );
952         }
953     }
954   | '+' macro_expression %prec UNARYPLUS
955     {
956         $$ = $2;
957     }
958   | macro_expression '+' macro_expression
959     {
960         if( $1.IsNumber() && $3.IsNumber() ){
961             $$.cType = RSCEXP_LONG;
962             $$.SetLong( $1.GetLong() + $3.GetLong() );
963         }
964         else{
965             $$.cType = RSCEXP_EXP;
966             $$.aExp.pExp = new RscExpression( $1, '+', $3 );
967         }
968     }
969   | macro_expression '-' macro_expression
970     {
971         if( $1.IsNumber() && $3.IsNumber() ){
972             $$.cType = RSCEXP_LONG;
973             $$.SetLong( $1.GetLong() - $3.GetLong() );
974         }
975         else{
976             $$.cType = RSCEXP_EXP;
977             $$.aExp.pExp = new RscExpression( $1, '-', $3 );
978         }
979     }
980   | macro_expression '*' macro_expression
981     {
982         if( $1.IsNumber() && $3.IsNumber() ){
983             $$.cType = RSCEXP_LONG;
984             $$.SetLong( $1.GetLong() * $3.GetLong() );
985         }
986         else{
987             $$.cType = RSCEXP_EXP;
988             $$.aExp.pExp = new RscExpression( $1, '*', $3 );
989         }
990     }
991   | macro_expression '/' macro_expression
992     {
993         if( $1.IsNumber() && $3.IsNumber() ){
994             if( 0 == $3.GetLong() ){
995                 $$.cType = RSCEXP_EXP;
996                 $$.aExp.pExp = new RscExpression( $1, '/', $3 );
997             }
998             else{
999                 $$.cType = RSCEXP_LONG;
1000                 $$.SetLong( $1.GetLong() / $3.GetLong() );
1001             }
1002         }
1003         else{
1004             $$.cType = RSCEXP_EXP;
1005             $$.aExp.pExp = new RscExpression( $1, '/', $3 );
1006         }
1007     }
1008   | macro_expression '&' macro_expression
1009     {
1010         if( $1.IsNumber() && $3.IsNumber() ){
1011             $$.cType = RSCEXP_LONG;
1012             $$.SetLong( $1.GetLong() & $3.GetLong() );
1013         }
1014         else{
1015             $$.cType = RSCEXP_EXP;
1016             $$.aExp.pExp = new RscExpression( $1, '&', $3 );
1017         }
1018     }
1019   | macro_expression '|' macro_expression
1020     {
1021         if( $1.IsNumber() && $3.IsNumber() ){
1022             $$.cType = RSCEXP_LONG;
1023             $$.SetLong( $1.GetLong() | $3.GetLong() );
1024         }
1025         else{
1026             $$.cType = RSCEXP_EXP;
1027             $$.aExp.pExp = new RscExpression( $1, '|', $3 );
1028         }
1029     }
1030   | '(' macro_expression ')'
1031     {
1032         $$ = $2;
1033     }
1034   | macro_expression LEFTSHIFT macro_expression
1035     {
1036         if( $1.IsNumber() && $3.IsNumber() ){
1037             $$.cType = RSCEXP_LONG;
1038             $$.SetLong( $1.GetLong() << $3.GetLong() );
1039         }
1040         else{
1041             $$.cType = RSCEXP_EXP;
1042             $$.aExp.pExp = new RscExpression( $1, 'l', $3 );
1043         }
1044     }
1045   | macro_expression RIGHTSHIFT macro_expression
1046     {
1047         if( $1.IsNumber() && $3.IsNumber() ){
1048             $$.cType = RSCEXP_LONG;
1049             $$.SetLong( $1.GetLong() >> $3.GetLong() );
1050         }
1051         else{
1052             $$.cType = RSCEXP_EXP;
1053             $$.aExp.pExp = new RscExpression( $1, 'r', $3 );
1054         }
1055     }
1056   ;
1057 
1058 id_expression
1059   : id_expression line_number
1060   | macro_expression
1061     {  // pExpession auswerten und loeschen
1062         if( RSCEXP_EXP == $1.cType ){
1063             sal_Int32   lValue;
1064 
1065             if( !$1.Evaluate( &lValue ) )
1066                 pTC->pEH->Error( ERR_ZERODIVISION, NULL, RscId() );
1067             delete $1.aExp.pExp;
1068             $$.cType = RSCEXP_LONG;
1069             $$.SetLong( lValue );
1070         }
1071         else
1072             $$ = $1;
1073     }
1074   ;
1075 
1076 DUMMY_NUMBER
1077   : NUMBER
1078     {
1079     }
1080   |
1081     {
1082     }
1083   ;
1084 
1085 line_number
1086   : '#' LINE NUMBER STRING
1087     {
1088         RscFile * pFName;
1089 
1090         pFI->SetLineNo( $3 );
1091         pFI->SetFileIndex( pTC->aFileTab.NewCodeFile( ByteString( $4 ) ) );
1092         pFName = pTC->aFileTab.Get( pFI->GetFileIndex() );
1093         pFName->bLoaded = sal_True;
1094         pFName->bScanned = sal_True;
1095     }
1096   | '#' NUMBER STRING DUMMY_NUMBER
1097     {
1098         RscFile * pFName;
1099 
1100         pFI->SetLineNo( $2 );
1101         pFI->SetFileIndex( pTC->aFileTab.NewCodeFile( ByteString( $3 ) ) );
1102         pFName = pTC->aFileTab.Get( pFI->GetFileIndex() );
1103         pFName->bLoaded = sal_True;
1104         pFName->bScanned = sal_True;
1105     }
1106   | '#' NUMBER
1107     {
1108         pFI->SetLineNo( $2 );
1109     }
1110   ;
1111 
1112 
1113 
1114 
1115