2001-10-31 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / mcs / cs-parser.jay
1 %{
2 //
3 // cs-parser.jay: The Parser for the C# compiler
4 //
5 // Author: Miguel de Icaza (miguel@gnu.org)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2001 Ximian, Inc (http://www.ximian.com)
10 //
11 // TODO:
12 //   (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
13 //       And come to think of it, it is not that great, it duplicates a lot of code
14 //       for something which is not really needed.  We still have piles of typecasts
15 //       anwyays (due to the nature of the stack being a collection of Objects).
16 //
17 //   (2) Figure out why error productions dont work.  `type-declaration' is a
18 //       great spot to put an `error' because you can reproduce it with this input:
19 //       "public X { }"
20 //
21 //   (3) Move Modifier checking from each object into the parser itself, that will
22 //       get rid of the global "error" symbol that we use now to report errors. 
23 //       We still need to pass a pointer to the tree.ErrorHandler, but that is a 
24 //       separate problem
25 //
26 using System.Text;
27 using CIR;
28 using System;
29
30 namespace CIR
31 {
32         using System.Collections;
33         using Mono.Languages;
34
35         /// <summary>
36         ///    The C# Parser
37         /// </summary>
38         public class CSharpParser : GenericParser {
39                 Namespace     current_namespace;
40                 TypeContainer current_container;
41         
42                 // <summary>
43                 //   Current block is used to add statements as we find
44                 //   them.  
45                 // </summary>
46
47                 Block      current_block;
48
49                 // <summary>
50                 //   Current interface is used by the various declaration
51                 //   productions in the interface declaration to "add"
52                 //   the interfaces as we find them.
53                 // </summary>
54                 Interface  current_interface;
55
56                 // <summary>
57                 //   This is used by the unary_expression code to resolve
58                 //   a name against a parameter.  
59                 // </summary>
60                 Parameters current_local_parameters;
61
62                 // <summary>
63                 //   Using during property parsing to describe the implicit
64                 //   value parameter that is passed to the "set" and "get"accesor
65                 //   methods (properties and indexers).
66                 // </summary>
67                 string     implicit_value_parameter_type;
68                 Parameters indexer_parameters;
69
70                 // <summary>
71                 //   Used to determine if we are parsing the get/set pair
72                 //   of an indexer or a property
73                 // </summmary>
74                 bool  parsing_indexer;
75
76                 // <summary>
77                 //   Used to record all types defined
78                 // </summary>
79                 Tree tree;
80
81                 RootContext rc; 
82
83 %}
84
85 %token EOF
86 %token NONE   /* This token is never returned by our lexer */
87 %token ERROR            // This is used not by the parser, but by the tokenizer.
88                         // do not remove.
89
90 /*
91  *These are the C# keywords
92  */
93 %token ABSTRACT 
94 %token AS
95 %token ADD
96 %token BASE     
97 %token BOOL     
98 %token BREAK    
99 %token BYTE     
100 %token CASE     
101 %token CATCH    
102 %token CHAR     
103 %token CHECKED  
104 %token CLASS    
105 %token CONST    
106 %token CONTINUE 
107 %token DECIMAL  
108 %token DEFAULT  
109 %token DELEGATE 
110 %token DO       
111 %token DOUBLE   
112 %token ELSE     
113 %token ENUM     
114 %token EVENT    
115 %token EXPLICIT 
116 %token EXTERN   
117 %token FALSE    
118 %token FINALLY  
119 %token FIXED    
120 %token FLOAT    
121 %token FOR      
122 %token FOREACH  
123 %token GOTO     
124 %token IF       
125 %token IMPLICIT 
126 %token IN       
127 %token INT      
128 %token INTERFACE
129 %token INTERNAL 
130 %token IS       
131 %token LOCK     
132 %token LONG     
133 %token NAMESPACE
134 %token NEW      
135 %token NULL     
136 %token OBJECT   
137 %token OPERATOR 
138 %token OUT      
139 %token OVERRIDE 
140 %token PARAMS   
141 %token PRIVATE  
142 %token PROTECTED
143 %token PUBLIC   
144 %token READONLY 
145 %token REF      
146 %token RETURN   
147 %token REMOVE
148 %token SBYTE    
149 %token SEALED   
150 %token SHORT    
151 %token SIZEOF   
152 %token STATIC   
153 %token STRING   
154 %token STRUCT   
155 %token SWITCH   
156 %token THIS     
157 %token THROW    
158 %token TRUE     
159 %token TRY      
160 %token TYPEOF   
161 %token UINT     
162 %token ULONG    
163 %token UNCHECKED
164 %token UNSAFE   
165 %token USHORT   
166 %token USING    
167 %token VIRTUAL  
168 %token VOID     
169 %token WHILE    
170
171 /* C# keywords which are not really keywords */
172 %token GET           "get"
173 %token SET           "set"
174
175 /* C# single character operators/punctuation. */
176 %token OPEN_BRACE    "{"
177 %token CLOSE_BRACE   "}"
178 %token OPEN_BRACKET  "["
179 %token CLOSE_BRACKET "]"
180 %token OPEN_PARENS   "("
181 %token CLOSE_PARENS  ")"
182 %token DOT           "."
183 %token COMMA         ","
184 %token COLON         ":"
185 %token SEMICOLON     ";"
186 %token TILDE         "~"
187
188 %token PLUS           "+"
189 %token MINUS          "-"
190 %token BANG           "!"
191 %token ASSIGN         "="
192 %token OP_LT          "<"
193 %token OP_GT          ">"
194 %token BITWISE_AND    "&"
195 %token BITWISE_OR     "|"
196 %token STAR           "*"
197 %token PERCENT        "%"
198 %token DIV            "/"
199 %token CARRET         "^"
200 %token INTERR         "?"
201
202 /* C# multi-character operators. */
203 %token OP_INC                 "++"
204 %token OP_DEC                 "--"
205 %token OP_SHIFT_LEFT          "<<"
206 %token OP_SHIFT_RIGHT         ">>"
207 %token OP_LE                  "<="
208 %token OP_GE                  ">="
209 %token OP_EQ                  "=="
210 %token OP_NE                  "!="
211 %token OP_AND                 "&&"
212 %token OP_OR                  "||"
213 %token OP_MULT_ASSIGN         "*="
214 %token OP_DIV_ASSIGN          "/="
215 %token OP_MOD_ASSIGN          "%="
216 %token OP_ADD_ASSIGN          "+="
217 %token OP_SUB_ASSIGN          "-="
218 %token OP_SHIFT_LEFT_ASSIGN   "<<="
219 %token OP_SHIFT_RIGHT_ASSIGN  ">>="
220 %token OP_AND_ASSIGN          "&="
221 %token OP_XOR_ASSIGN          "^="
222 %token OP_OR_ASSIGN           "|="
223 %token OP_PTR                 "->"
224
225 /* Numbers */
226 %token LITERAL_INTEGER           "int literal"
227 %token LITERAL_FLOAT             "float literal"
228 %token LITERAL_DOUBLE            "double literal"
229 %token LITERAL_DECIMAL           "decimal literal"
230 %token LITERAL_CHARACTER         "character literal"
231 %token LITERAL_STRING            "string literal"
232
233 %token IDENTIFIER
234
235 /* Add precedence rules to solve dangling else s/r conflict */
236 %nonassoc LOWPREC
237 %nonassoc IF
238 %nonassoc ELSE
239 %right ASSIGN
240 %left OP_OR
241 %left OP_AND
242 %left BITWISE_OR
243 %left BITWISE_AND
244 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
245 %left PLUS MINUS
246 %left STAR DIV PERCENT
247 %right BANG CARRET UMINUS
248 %nonassoc OP_INC OP_DEC
249 %left OPEN_PARENS
250 %left OPEN_BRACKET OPEN_BRACE
251 %left DOT
252 %nonassoc HIGHPREC
253
254 %start compilation_unit
255 /*%start namespace_declaration */
256 %%
257
258 compilation_unit
259         : opt_using_directives opt_attributes opt_namespace_member_declarations EOF
260           {
261                 // Check that using comes only before namespace elements
262           }
263         ;
264
265 using_directives
266         : using_directive 
267         | using_directives using_directive
268         ;
269
270 using_directive
271         : using_alias_directive
272         | using_namespace_directive
273         ;
274
275 using_alias_directive
276         : USING IDENTIFIER ASSIGN 
277           namespace_or_type_name SEMICOLON
278           {
279                   // FIXME : Need to implement actual action.
280           }
281         ;
282
283 using_namespace_directive
284         : USING namespace_name SEMICOLON 
285           {
286                 current_namespace.Using ((string) $2);
287           }
288         ;
289
290 //  namespace_declarations
291 //      : namespace_declaration
292 //      | namespace_declarations namespace_declaration
293
294 namespace_declaration
295         : NAMESPACE qualified_identifier 
296           {
297                 current_namespace = tree.RecordNamespace (current_namespace, (string) $2);
298           } 
299           namespace_body opt_semicolon
300           { 
301                 current_namespace = current_namespace.Parent;
302           }
303         ;
304
305 opt_semicolon
306         : /* empty */
307         | SEMICOLON
308         ;
309
310 opt_comma
311         : /* empty */
312         | COMMA
313         ;
314
315 qualified_identifier
316         : IDENTIFIER
317         | qualified_identifier DOT IDENTIFIER { 
318             $$ = (($1).ToString ()) + "." + ($3.ToString ()); }
319         ;
320
321
322 namespace_name
323         : namespace_or_type_name
324         ;
325
326 namespace_body
327         : OPEN_BRACE
328           opt_using_directives
329           opt_namespace_member_declarations
330           CLOSE_BRACE
331           {
332           }
333         ;
334
335 opt_using_directives
336         : /* empty */
337         | using_directives
338         ;
339
340 opt_namespace_member_declarations
341         : /* empty */
342         | namespace_member_declarations
343         ;
344
345 namespace_member_declarations
346         : namespace_member_declaration
347         | namespace_member_declarations namespace_member_declaration
348         ;
349
350 namespace_member_declaration
351         : type_declaration
352           {
353                 int mod_flags = 0;
354                 string name = "";
355
356                 if ($1 is Class){
357                         Class c = (Class) $1;
358                         mod_flags = c.ModFlags;
359                         name = c.Name;
360                 } else if ($1 is Struct){
361                         Struct s = (Struct) $1;
362                         mod_flags = s.ModFlags;
363                         name = s.Name;
364                 } else
365                         break;
366
367                 //
368                 // We remove this error until we can 
369                 //if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
370                 //      error (1527, "Namespace elements cant be explicitly " +
371                 //                   "declared private or protected in `" + name + "'");
372                 //}
373           }
374         | namespace_declaration
375         ;
376
377 type_declaration
378         : class_declaration             
379         | struct_declaration            
380         | interface_declaration         
381         | enum_declaration              
382         | delegate_declaration         
383         ;
384
385 //
386 // Attributes 17.2
387 //
388 opt_attributes
389         : /* empty */ { $$ = null; }
390         | attribute_section opt_attributes
391           {
392                 Attributes attrs;
393                 
394                 if ($2 != null) {
395                         attrs = (Attributes) $2;
396                         attrs.AddAttribute ((Attribute) $1);
397                 } else
398                         attrs = new Attributes ((Attribute) $1);
399                 
400                 $$ = attrs;
401           }
402         ;
403
404 attribute_section
405         : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET
406           {
407                 string target = null;
408                 
409                 if ($2 != null)
410                         target = (string) $2;
411                 
412                 $$ = new Attribute (target, (ArrayList) $3);
413           }
414         | OPEN_BRACKET attribute_list CLOSE_BRACKET
415           {
416                 $$ = new Attribute (null, (ArrayList) $2);
417           }
418         ;
419  
420 attribute_target_specifier
421         : attribute_target COLON
422           {
423                 $$ = $1;
424           }
425         ;
426
427 attribute_target
428         : IDENTIFIER
429           {
430                 CheckAttributeTarget ((string) $1);
431                 $$ = $1;
432           }
433         | EVENT  { $$ = "event"; }        
434         | RETURN { $$ = "return"; }
435         ;
436
437 attribute_list
438         : attribute
439           {
440                 ArrayList attrs = new ArrayList ();
441                 attrs.Add ($1);
442
443                 $$ = attrs;
444                
445           }
446         | attribute_list COMMA attribute
447           {
448                 ArrayList attrs = (ArrayList) $1;
449                 attrs.Add ($3);
450
451                 $$ = attrs;
452           }
453         ;
454
455 attribute
456         : attribute_name opt_attribute_arguments
457           {
458                 $$ = new DictionaryEntry ($1, $2);
459           }
460         ;
461
462 attribute_name
463         : type_name  { /* reserved attribute name or identifier: 17.4 */ }
464         ;
465
466 opt_attribute_arguments
467         : /* empty */   { $$ = null; }
468         | OPEN_PARENS attribute_arguments CLOSE_PARENS
469           {
470                 $$ = $2;
471           }
472         ;
473
474 attribute_arguments
475         : expression
476           {
477                 ArrayList args = new ArrayList ();
478                 args.Add ($1);
479                 
480                 $$ = args;
481           }
482         | attribute_arguments COMMA expression
483           {
484                 ArrayList args = (ArrayList) $1;
485                 args.Add ($3);
486
487                 $$ = args;
488           }
489         ;
490
491
492 class_body
493         :  OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
494         ;
495
496 opt_class_member_declarations
497         : /* empty */
498         | class_member_declarations
499         ;
500
501 class_member_declarations
502         : class_member_declaration
503         | class_member_declarations 
504           class_member_declaration
505         ;
506
507 class_member_declaration
508         : constant_declaration                  // done
509         | field_declaration                     // done
510         | method_declaration                    // done
511         | property_declaration                  // done
512         | event_declaration                     // done
513         | indexer_declaration                   // done
514         | operator_declaration                  // done
515         | constructor_declaration               // done
516         | destructor_declaration                // done
517         | type_declaration
518         ;
519
520 struct_declaration
521         : opt_attributes
522           opt_modifiers
523           STRUCT IDENTIFIER
524           { 
525                 Struct new_struct;
526                 string full_struct_name = MakeName ((string) $4);
527
528                 new_struct = new Struct (rc, current_container, full_struct_name, (int) $2, 
529                                          (Attributes) $1, lexer.Location);
530                 current_container = new_struct;
531                 current_container.Namespace = current_namespace;
532                 tree.RecordStruct (full_struct_name, new_struct);
533           }
534           opt_struct_interfaces
535           struct_body
536           opt_semicolon
537           {
538                 Struct new_struct = (Struct) current_container;
539
540                 current_container = current_container.Parent;
541                 CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
542                 $$ = new_struct;
543           }
544         ;
545
546 opt_struct_interfaces
547         : /* empty */
548         | struct_interfaces
549         ;
550
551 struct_interfaces
552         : struct_interface
553         | struct_interfaces struct_interface
554         ; 
555
556 struct_interface
557         : COLON type_list
558         ;
559
560 struct_body
561         : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
562         ;
563
564 opt_struct_member_declarations
565         : /* empty */
566         | struct_member_declarations
567         ;
568
569 struct_member_declarations
570         : struct_member_declaration
571         | struct_member_declarations struct_member_declaration
572         ;
573
574 struct_member_declaration
575         : constant_declaration
576         | field_declaration
577         | method_declaration
578         | property_declaration
579         | event_declaration
580         | indexer_declaration
581         | operator_declaration
582         | constructor_declaration
583         | type_declaration
584         ;
585
586 constant_declaration
587         : opt_attributes 
588           opt_modifiers
589           CONST
590           type
591           constant_declarators
592           SEMICOLON
593           {
594                 foreach (DictionaryEntry constant in (ArrayList) $5){
595                         Constant c = new Constant (
596                                 (string) $4, (string) constant.Key, 
597                                 (Expression) constant.Value, (int) $2, (Attributes) $1);
598
599                         CheckDef (current_container.AddConstant (c), c.Name);
600                 }
601           }
602         ;
603
604 constant_declarators
605         : constant_declarator 
606           {
607                 ArrayList constants = new ArrayList ();
608                 constants.Add ($1);
609                 $$ = constants;
610           }
611         | constant_declarators COMMA constant_declarator
612           {
613                 ArrayList constants = (ArrayList) $1;
614
615                 constants.Add ($3);
616           }
617         ;
618
619 constant_declarator
620         : IDENTIFIER ASSIGN constant_expression
621           {
622                 $$ = new DictionaryEntry ($1, $3);
623           }
624         ;
625
626 field_declaration
627         : opt_attributes
628           opt_modifiers
629           type 
630           variable_declarators
631           SEMICOLON
632         { 
633                 string type = (string) $3;
634                 int mod = (int) $2;
635
636                 foreach (VariableDeclaration var in (ArrayList) $4){
637                         Field field = new Field (type, mod, var.identifier, 
638                                                  var.expression_or_array_initializer, (Attributes) $1);
639
640                         CheckDef (current_container.AddField (field), field.Name);
641                 }
642         }
643
644         ;
645
646 variable_declarators
647         : variable_declarator 
648           {
649                 ArrayList decl = new ArrayList ();
650                 decl.Add ($1);
651                 $$ = decl;
652           }
653         | variable_declarators COMMA variable_declarator
654           {
655                 ArrayList decls = (ArrayList) $1;
656                 decls.Add ($3);
657                 $$ = $1;
658           }
659         ;
660
661 variable_declarator
662         : IDENTIFIER ASSIGN variable_initializer
663           {
664                 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
665           }
666         | IDENTIFIER
667           {
668                 $$ = new VariableDeclaration ((string) $1, null, lexer.Location);
669           }
670         ;
671
672 variable_initializer
673         : expression
674           {
675                 $$ = $1;
676           }
677         | array_initializer
678         {
679                 $$ = $1;
680         }
681         ;
682
683 method_declaration
684         : method_header
685           method_body
686           {
687                 Method method = (Method) $1;
688                 Block b = (Block) $2;
689                 
690                 if (b == null){
691                         if ((method.ModFlags & (Modifiers.EXTERN | Modifiers.ABSTRACT)) == 0){
692                                 Report.Error (
693                                         501, lexer.Location, "`" + 
694                                         current_container.Name + "." + method.Name + "'" +
695                                         "must declare a body because it is not marked abstract or extern");
696                         }
697                 }
698
699                 method.Block = (Block) $2;
700                 CheckDef (current_container.AddMethod (method), method.Name);
701
702                 current_local_parameters = null;
703           }
704         ;
705
706 method_header
707         : opt_attributes
708           opt_modifiers
709           type
710           member_name
711           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
712           {
713                 Method method = new Method ((string) $3, (int) $2, (string) $4, 
714                                             (Parameters) $6, (Attributes) $1, lexer.Location);
715
716                 current_local_parameters = (Parameters) $6;
717
718                 $$ = method;
719           }
720         | opt_attributes
721           opt_modifiers
722           VOID
723           member_name
724           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
725           {
726                 Method method = new Method ("System.Void", (int) $2, (string) $4, 
727                                             (Parameters) $6, (Attributes) $1, lexer.Location);
728
729                 current_local_parameters = (Parameters) $6;
730                 $$ = method;
731           }
732         ;
733
734 method_body
735         : block
736         | SEMICOLON             { $$ = null; }
737         ;
738
739 opt_formal_parameter_list
740         : /* empty */                   { $$ = new Parameters (null, null); }
741         | formal_parameter_list
742         ;
743
744 formal_parameter_list
745         : fixed_parameters              
746           { 
747                 ArrayList pars_list = (ArrayList) $1;
748
749                 Parameter [] pars = new Parameter [pars_list.Count];
750                 pars_list.CopyTo (pars);
751
752                 $$ = new Parameters (pars, null); 
753           } 
754         | fixed_parameters COMMA parameter_array
755           {
756                 ArrayList pars_list = (ArrayList) $1;
757
758                 Parameter [] pars = new Parameter [pars_list.Count];
759                 pars_list.CopyTo (pars);
760
761                 $$ = new Parameters (pars, (Parameter) $3); 
762           }
763         | parameter_array 
764           {
765                 $$ = new Parameters (null, (Parameter) $1);
766           }
767         ;
768
769 fixed_parameters
770         : fixed_parameter       
771           {
772                 ArrayList pars = new ArrayList ();
773
774                 pars.Add ($1);
775                 $$ = pars;
776           }
777         | fixed_parameters COMMA fixed_parameter
778           {
779                 ArrayList pars = (ArrayList) $1;
780
781                 pars.Add ($3);
782                 $$ = $1;
783           }
784         ;
785
786 fixed_parameter
787         : opt_attributes
788           opt_parameter_modifier
789           type
790           IDENTIFIER
791           {
792                 $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
793           }
794         ;
795
796 opt_parameter_modifier
797         : /* empty */           { $$ = Parameter.Modifier.NONE; }
798         | parameter_modifier
799         ;
800
801 parameter_modifier
802         : REF                   { $$ = Parameter.Modifier.REF; }
803         | OUT                   { $$ = Parameter.Modifier.OUT; }
804         ;
805
806 parameter_array
807         : opt_attributes PARAMS type IDENTIFIER
808           { 
809                 $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
810                 note ("type must be a single-dimension array type"); 
811           }
812         ;
813
814 member_name 
815         : IDENTIFIER { $$ = $1.ToString (); }
816         | interface_type DOT IDENTIFIER { $$ = $1.ToString () + "." + $3.ToString (); }
817         ;
818
819 property_declaration
820         : opt_attributes
821           opt_modifiers
822           type member_name
823           OPEN_BRACE 
824           {
825                 implicit_value_parameter_type = (string) $3;
826
827                 lexer.properties = true;
828           }
829           accessor_declarations 
830           {
831                 lexer.properties = false;
832           }
833           CLOSE_BRACE
834           { 
835                 Property prop;
836                 DictionaryEntry pair = (DictionaryEntry) $7;
837                 Block get_block = null;
838                 Block set_block = null;
839
840                 if (pair.Key != null)
841                         get_block = (Block) pair.Key;
842                 if (pair.Value != null)
843                         set_block = (Block) pair.Value;
844
845                 prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block, (Attributes) $1);
846                 
847                 CheckDef (current_container.AddProperty (prop), prop.Name);
848                 implicit_value_parameter_type = null;
849           }
850         ;
851
852 accessor_declarations
853         : get_accessor_declaration opt_set_accessor_declaration
854           { 
855                 $$ = new DictionaryEntry ($1, $2);
856           }
857         | set_accessor_declaration opt_get_accessor_declaration
858           {
859                 $$ = new DictionaryEntry ($2, $1);
860           }
861         ;
862
863 opt_get_accessor_declaration
864         : /* empty */                   { $$ = null; }
865         | get_accessor_declaration
866         ;
867
868 opt_set_accessor_declaration
869         : /* empty */                   { $$ = null; }
870         | set_accessor_declaration
871         ;
872
873 get_accessor_declaration
874         : opt_attributes GET
875           {
876                 // If this is not the case, then current_local_parameters has already
877                 // been set in indexer_declaration
878                 if (parsing_indexer == false)
879                         current_local_parameters = null;
880                 else 
881                         current_local_parameters = indexer_parameters;
882
883                 
884           }
885           accessor_body
886           {
887                 $$ = $4;
888                 current_local_parameters = null;
889           }
890         ;
891
892 set_accessor_declaration
893         : opt_attributes SET 
894           {
895                 Parameter [] args;
896                 Parameter implicit_value_parameter = new Parameter (
897                         implicit_value_parameter_type, "value", 
898                         Parameter.Modifier.NONE, null);
899
900                 if (parsing_indexer == false) {
901                         args  = new Parameter [1];
902                         args [0] = implicit_value_parameter;
903                 } else {
904                         Parameter [] fp = indexer_parameters.FixedParameters;
905                         int count = fp.Length;
906
907                         args = new Parameter [count + 1];
908         
909                         fp.CopyTo (args, 0);
910                         args [count] = implicit_value_parameter;
911                 }
912                 current_local_parameters = new Parameters (args, null);
913           }
914           accessor_body
915           {
916                 $$ = $4;
917                 current_local_parameters = null;
918           }
919         ;
920
921 accessor_body
922         : block 
923         | SEMICOLON             { $$ = new Block (null); }
924         ;
925
926 interface_declaration
927         : opt_attributes
928           opt_modifiers
929           INTERFACE IDENTIFIER
930           {
931                 Interface new_interface;
932                 string full_interface_name = MakeName ((string) $4);
933
934                 new_interface = new Interface (rc, current_container, full_interface_name, (int) $2, 
935                                                (Attributes) $1, lexer.Location);
936                 if (current_interface != null) {
937                         Location l = lexer.Location;
938                         Report.Error (-2, l, "Internal compiler error: interface inside interface");
939                 }
940                 current_interface = new_interface;
941                 tree.RecordInterface (full_interface_name, new_interface);
942           }
943           opt_interface_base
944           interface_body
945           { 
946                 Interface new_interface = (Interface) current_interface;
947
948                 if ($6 != null)
949                         new_interface.Bases = (ArrayList) $6;
950
951                 current_interface = null;
952                 CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
953           }
954         ;
955
956 opt_interface_base
957         : /* empty */                     { $$ = null; }
958         | interface_base
959         ;
960
961 interface_base
962         : COLON interface_type_list       { $$ = $2; }
963         ;
964
965 interface_type_list
966         : interface_type
967           {
968                 ArrayList interfaces = new ArrayList ();
969
970                 interfaces.Add ($1);
971                 $$ = interfaces;
972           }
973         | interface_type_list COMMA interface_type
974           {
975                 ArrayList interfaces = (ArrayList) $1;
976                 interfaces.Add ($3);
977                 $$ = interfaces;
978           }
979         ;
980
981 interface_body
982         : OPEN_BRACE
983           opt_interface_member_declarations
984           CLOSE_BRACE
985         ;
986
987 opt_interface_member_declarations
988         : /* empty */
989         | interface_member_declarations
990         ;
991
992 interface_member_declarations
993         : interface_member_declaration
994         | interface_member_declarations interface_member_declaration
995         ;
996
997 interface_member_declaration
998         : interface_method_declaration          
999           { 
1000                 InterfaceMethod m = (InterfaceMethod) $1;
1001
1002                 CheckDef (current_interface.AddMethod (m), m.Name);
1003           }
1004         | interface_property_declaration        
1005           { 
1006                 InterfaceProperty p = (InterfaceProperty) $1;
1007
1008                 CheckDef (current_interface.AddProperty (p), p.Name);
1009           }
1010         | interface_event_declaration 
1011           { 
1012                 InterfaceEvent e = (InterfaceEvent) $1;
1013
1014                 CheckDef (current_interface.AddEvent (e), e.Name);
1015           }
1016         | interface_indexer_declaration
1017           { 
1018                 InterfaceIndexer i = (InterfaceIndexer) $1;
1019
1020                 CheckDef (current_interface.AddIndexer (i), "indexer");
1021           }
1022         ;
1023
1024 opt_new
1025         : /* empty */   { $$ = false; }
1026         | NEW           { $$ = true; }
1027         ;
1028
1029 interface_method_declaration
1030         : opt_attributes opt_new type IDENTIFIER 
1031           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1032           SEMICOLON
1033           {
1034                 $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
1035           }
1036         | opt_attributes opt_new VOID IDENTIFIER 
1037           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1038           SEMICOLON
1039           {
1040                 $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
1041           }
1042         ;
1043
1044 interface_property_declaration
1045         : opt_attributes
1046           opt_new
1047           type IDENTIFIER 
1048           OPEN_BRACE 
1049           { lexer.properties = true; }
1050           interface_accesors 
1051           { lexer.properties = false; }
1052           CLOSE_BRACE
1053           {
1054                 int gs = (int) $7;
1055
1056                 $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2, 
1057                                             (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1);
1058           }
1059         ;
1060
1061 interface_accesors
1062         : opt_attributes GET SEMICOLON          { $$ = 1; }
1063         | opt_attributes SET SEMICOLON          { $$ = 2; }
1064         | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON 
1065           { $$ = 3; }
1066         | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
1067           { $$ = 3; }
1068         ;
1069
1070 interface_event_declaration
1071         : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
1072           {
1073                 $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2, (Attributes) $1);
1074           }
1075         ;
1076
1077 interface_indexer_declaration 
1078         : opt_attributes opt_new type THIS 
1079           OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1080           OPEN_BRACE 
1081           { lexer.properties = true; }
1082           interface_accesors 
1083           { lexer.properties = false; }
1084           CLOSE_BRACE
1085           {
1086                 int a_flags = (int) $10;
1087
1088                 bool do_get = (a_flags & 1) == 1;
1089                 bool do_set = (a_flags & 2) == 2;
1090
1091                 $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set, (bool) $2, (Attributes) $1);
1092           }
1093         ;
1094
1095 operator_declaration
1096         : opt_attributes opt_modifiers operator_declarator block
1097           {
1098                 OperatorDeclaration decl = (OperatorDeclaration) $3;
1099                 
1100                 Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name,
1101                                             decl.arg2type, decl.arg2name, (Block) $4, (Attributes) $1, decl.location);
1102
1103                 // Note again, checking is done in semantic analysis
1104                 current_container.AddOperator (op);
1105           }
1106         ;
1107
1108 operator_declarator
1109         : type OPERATOR overloadable_operator 
1110           OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1111         {
1112                 Operator.OpType op = (Operator.OpType) $3;
1113                 CheckUnaryOperator (op);
1114
1115                 if (op == Operator.OpType.Addition)
1116                         op = Operator.OpType.UnaryPlus;
1117
1118                 if (op == Operator.OpType.Subtraction)
1119                         op = Operator.OpType.UnaryNegation;
1120
1121                 $$ = new OperatorDeclaration (op, (string) $1, (string) $5, (string) $6,
1122                                               null, null, lexer.Location);
1123         }
1124         | type OPERATOR overloadable_operator
1125           OPEN_PARENS 
1126                 type IDENTIFIER COMMA
1127                 type IDENTIFIER 
1128           CLOSE_PARENS
1129         {
1130                CheckBinaryOperator ((Operator.OpType) $3);
1131                
1132                $$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
1133                                              (string) $8, (string) $9, lexer.Location);
1134         }
1135         | conversion_operator_declarator
1136         ;
1137
1138 overloadable_operator
1139 // Unary operators:
1140         : BANG   { $$ = Operator.OpType.LogicalNot; }
1141         | TILDE  { $$ = Operator.OpType.OnesComplement; }  
1142         | OP_INC { $$ = Operator.OpType.Increment; }
1143         | OP_DEC { $$ = Operator.OpType.Decrement; }
1144         | TRUE   { $$ = Operator.OpType.True; }
1145         | FALSE  { $$ = Operator.OpType.False; }
1146 // Unary and binary:
1147         | PLUS { $$ = Operator.OpType.Addition; }
1148         | MINUS { $$ = Operator.OpType.Subtraction; }
1149 // Binary:
1150         | STAR { $$ = Operator.OpType.Multiply; }
1151         | DIV {  $$ = Operator.OpType.Division; }
1152         | PERCENT { $$ = Operator.OpType.Modulus; }
1153         | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
1154         | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
1155         | CARRET { $$ = Operator.OpType.ExclusiveOr; }
1156         | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
1157         | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
1158         | OP_EQ { $$ = Operator.OpType.Equality; }
1159         | OP_NE { $$ = Operator.OpType.Inequality; }
1160         | OP_GT { $$ = Operator.OpType.GreaterThan; }
1161         | OP_LT { $$ = Operator.OpType.LessThan; }
1162         | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
1163         | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
1164         ;
1165
1166 conversion_operator_declarator
1167         : IMPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1168           {
1169                 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
1170                                               null, null, lexer.Location);
1171           }
1172         | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1173           {
1174                 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
1175                                               null, null, lexer.Location);
1176           }
1177         ;
1178
1179 constructor_declaration
1180         : opt_attributes
1181           opt_modifiers
1182           constructor_declarator
1183           block
1184           { 
1185                 Constructor c = (Constructor) $3;
1186                 c.Block = (Block) $4;
1187                 c.ModFlags = (int) $2;
1188
1189                 if ((c.ModFlags & Modifiers.STATIC) != 0){
1190                         if ((c.ModFlags & Modifiers.Accessibility) != 0) {
1191                                 Location l = lexer.Location;
1192                                 Report.Error (515, l, "Access modifiers are not allowed on static constructors");
1193                         }
1194
1195                         if (c.Initializer != null){
1196                                 Location l = lexer.Location;
1197                                 Report.Error (514, l, "Static constructors can not have an explicit this or base constructor invocations");
1198                         }
1199
1200                         if (!c.Parameters.Empty){
1201                                 Location l = lexer.Location;
1202                                 Report.Error (103, l, "Static constructors should not have parameters");
1203                         }
1204                 } 
1205                 
1206                 CheckDef (current_container.AddConstructor (c), c.Name);
1207
1208                 current_local_parameters = null;
1209           }
1210         ;
1211
1212 constructor_declarator
1213         : IDENTIFIER 
1214           OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
1215           opt_constructor_initializer
1216           {
1217                 Location l = lexer.Location;
1218
1219                 $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5, l);
1220         
1221                 current_local_parameters = (Parameters) $3;
1222           }
1223         ;
1224
1225 opt_constructor_initializer
1226         : /* empty */                   { $$ = null; }
1227         | constructor_initializer
1228         ;
1229
1230 constructor_initializer
1231         : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
1232           {
1233                 $$ = new ConstructorBaseInitializer ((ArrayList) $4, lexer.Location);
1234           }
1235         | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
1236           {
1237                 $$ = new ConstructorThisInitializer ((ArrayList) $4, lexer.Location);
1238           }
1239         ;
1240
1241 destructor_declaration
1242         : opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
1243           {
1244                 //
1245                 // FIXME: The destructor needs to generate special code:
1246                 //
1247                 // ~X ()
1248                 // { balh (); }
1249                 //
1250                 //
1251                 // void Finalize () { 
1252                 // try { code } finally { base.Finalize (); }
1253                 //
1254                 Method d = new Method ("System.Void", 0, "Finalize", 
1255                                        new Parameters (null, null), (Attributes) $1, lexer.Location);
1256                   
1257                 d.Block = (Block) $6;
1258                 CheckDef (current_container.AddMethod (d), d.Name);
1259           }
1260         ;
1261
1262 event_declaration
1263         : opt_attributes
1264           opt_modifiers
1265           EVENT type variable_declarators SEMICOLON
1266           {
1267                 foreach (VariableDeclaration var in (ArrayList) $5) {
1268
1269                         // FIXME : Is this right ?
1270                         Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
1271                                              (int) $2, null, null, (Attributes) $1);
1272
1273                         CheckDef (current_container.AddEvent (e), e.Name);
1274                                        
1275                 }
1276           }
1277         | opt_attributes
1278           opt_modifiers
1279           EVENT type member_name 
1280           OPEN_BRACE event_accessor_declarations CLOSE_BRACE
1281         {
1282                 DictionaryEntry pair = (DictionaryEntry) $7;
1283                 Block add_block = null;
1284                 Block rem_block = null;
1285
1286                 if (pair.Key != null)
1287                         add_block = (Block) pair.Key;
1288                 if (pair.Value != null)
1289                         rem_block = (Block) pair.Value;
1290                 
1291                 Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block, (Attributes) $1);
1292                 
1293                 CheckDef (current_container.AddEvent (e), e.Name);
1294         }
1295         ;
1296
1297 event_accessor_declarations
1298         : add_accessor_declaration remove_accessor_declaration
1299         {
1300                 $$ = new DictionaryEntry ($1, $2);
1301         }
1302         | remove_accessor_declaration add_accessor_declaration
1303         {
1304                 $$ = new DictionaryEntry ($2, $1);
1305         }       
1306         ;
1307
1308 add_accessor_declaration
1309         : opt_attributes ADD block
1310           {
1311                 $$ = $3;
1312           }
1313         ;
1314
1315 remove_accessor_declaration
1316         : opt_attributes REMOVE block
1317         {
1318                 $$ = $3;
1319         }
1320         ;
1321
1322 indexer_declaration
1323         : opt_attributes opt_modifiers indexer_declarator 
1324           OPEN_BRACE 
1325           {
1326                 IndexerDeclaration decl = (IndexerDeclaration) $3;
1327
1328                 implicit_value_parameter_type = decl.type;
1329                 
1330                 lexer.properties = true;
1331                 parsing_indexer  = true;
1332                 
1333                 indexer_parameters = decl.param_list;
1334           }
1335           accessor_declarations 
1336           {
1337                   lexer.properties = false;
1338                   parsing_indexer  = false;
1339           }
1340           CLOSE_BRACE
1341           { 
1342                 // The signature is computed from the signature of the indexer.  Look
1343                 // at section 3.6 on the spec
1344
1345                 Indexer indexer;
1346                 IndexerDeclaration decl = (IndexerDeclaration) $3;
1347                 DictionaryEntry pair = (DictionaryEntry) $6;
1348                 Block get_block = null;
1349                 Block set_block = null;
1350
1351                 if (pair.Key != null)
1352                         get_block = (Block) pair.Key;
1353                 if (pair.Value != null)
1354                         set_block = (Block) pair.Value;
1355
1356                 indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
1357                                        get_block, set_block, (Attributes) $1);
1358
1359                 // Note that there is no equivalent of CheckDef for this case
1360                 // We shall handle this in semantic analysis
1361                 
1362                 current_container.AddIndexer (indexer);
1363                 
1364                 current_local_parameters = null;
1365                 implicit_value_parameter_type = null;
1366                 indexer_parameters = null;
1367           }
1368         ;
1369
1370 indexer_declarator
1371         : type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1372           {
1373                 $$ = new IndexerDeclaration ((string) $1, null, (Parameters) $4);
1374           }
1375         | type interface_type DOT THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1376           {
1377                 $$ = new IndexerDeclaration ((string) $1, (string) $2, (Parameters) $6);
1378           }
1379         ;
1380
1381 enum_declaration
1382         : opt_attributes
1383           opt_modifiers
1384           ENUM IDENTIFIER
1385           opt_enum_base
1386           enum_body
1387           opt_semicolon
1388           { 
1389                 string name = (string) $4;
1390                 Enum e = new Enum ((string) $5, (int) $2, name, (Attributes) $1, lexer.Location);
1391
1392                 foreach (VariableDeclaration ev in (ArrayList) $6){
1393                         CheckDef (e.AddEnumMember (ev.identifier, 
1394                                                    (Expression) ev.expression_or_array_initializer),
1395                                   ev.identifier);
1396                 }
1397
1398                 CheckDef (current_container.AddEnum (e), name);
1399           }
1400         ;
1401
1402 opt_enum_base
1403         : /* empty */                   { $$ = "System.Int32"; }
1404         | COLON integral_type           { $$ = $2;   }
1405         ;
1406
1407 enum_body
1408         : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
1409           {
1410                 $$ = $2;
1411           }
1412         ;
1413
1414 opt_enum_member_declarations
1415         : /* empty */                   { $$ = new ArrayList (); }
1416         | enum_member_declarations opt_comma { $$ = $1; }
1417         ;
1418
1419 enum_member_declarations
1420         : enum_member_declaration 
1421           {
1422                 ArrayList l = new ArrayList ();
1423
1424                 l.Add ($1);
1425                 $$ = l;
1426           }
1427         | enum_member_declarations COMMA enum_member_declaration
1428           {
1429                 ArrayList l = (ArrayList) $1;
1430
1431                 l.Add ($3);
1432
1433                 $$ = l;
1434           }
1435         ;
1436
1437 enum_member_declaration
1438         : opt_attributes IDENTIFIER 
1439           {
1440                 $$ = new VariableDeclaration ((string) $2, null, lexer.Location);
1441           }
1442         | opt_attributes IDENTIFIER ASSIGN expression
1443           { 
1444                 $$ = new VariableDeclaration ((string) $2, $4, lexer.Location);
1445           }
1446         ;
1447
1448 delegate_declaration
1449         : opt_attributes
1450           opt_modifiers
1451           DELEGATE type   
1452           IDENTIFIER OPEN_PARENS 
1453           formal_parameter_list
1454           CLOSE_PARENS 
1455           SEMICOLON
1456           {
1457                 Delegate del = new Delegate (rc, (string) $4, (int) $2, 
1458                                              MakeName ((string) $5), (Parameters) $7, 
1459                                              (Attributes) $1, lexer.Location);
1460                   
1461                 CheckDef (current_container.AddDelegate (del), del.Name);
1462           }     
1463         | opt_attributes
1464           opt_modifiers
1465           DELEGATE VOID   
1466           IDENTIFIER OPEN_PARENS 
1467           formal_parameter_list
1468           CLOSE_PARENS 
1469           SEMICOLON
1470           {
1471                 Delegate del = new Delegate (rc, "System.Void", (int) $2, (string) $5, (Parameters) $7, 
1472                                              (Attributes) $1, lexer.Location);
1473
1474                 CheckDef (current_container.AddDelegate (del), del.Name);
1475           }
1476         ;
1477
1478 type_name
1479         : namespace_or_type_name
1480         ;
1481
1482 namespace_or_type_name
1483         : qualified_identifier
1484         ;
1485
1486 /* 
1487  * Before you think of adding a return_type, notice that we have been
1488  * using two rules in the places where it matters (one rule using type
1489  * and another identical one that uses VOID as the return type).  This
1490  * gets rid of a shift/reduce couple
1491  */
1492 type
1493         : type_name {   /* class_type */
1494                 /* 
1495                    This does interfaces, delegates, struct_types, class_types, 
1496                    parent classes, and more! 4.2 
1497                  */
1498                 $$ = $1; 
1499           }
1500         | builtin_types
1501         | array_type
1502         ;
1503
1504 type_list
1505         : type
1506           {
1507                 ArrayList types = new ArrayList ();
1508
1509                 types.Add ($1);
1510                 $$ = types;
1511           }
1512         | type_list COMMA type
1513           {
1514                 ArrayList types = (ArrayList) $1;
1515
1516                 types.Add ($3);
1517                 $$ = types;
1518           }
1519         ;
1520
1521 /*
1522  * replaces all the productions for isolating the various
1523  * simple types, but we need this to reuse it easily in local_variable_type
1524  */
1525 builtin_types
1526         : OBJECT        { $$ = "System.Object"; }
1527         | STRING        { $$ = "System.String"; }
1528         | BOOL          { $$ = "System.Boolean"; }
1529         | DECIMAL       { $$ = "System.Decimal"; }
1530         | FLOAT         { $$ = "System.Single"; }
1531         | DOUBLE        { $$ = "System.Double"; }
1532         | integral_type
1533         ;
1534
1535 integral_type
1536         : SBYTE         { $$ = "System.SByte"; }
1537         | BYTE          { $$ = "System.Byte"; }
1538         | SHORT         { $$ = "System.Int16"; }
1539         | USHORT        { $$ = "System.UInt16"; }
1540         | INT           { $$ = "System.Int32"; }
1541         | UINT          { $$ = "System.UInt32"; }
1542         | LONG          { $$ = "System.Int64"; }
1543         | ULONG         { $$ = "System.UInt64"; }
1544         | CHAR          { $$ = "System.Char"; }
1545         ;
1546
1547 interface_type
1548         : type_name
1549         ;
1550
1551 array_type
1552         : type rank_specifiers
1553           {
1554                   $$ = (string) $1 + (string) $2;
1555           }
1556         ;
1557
1558 //
1559 // Expressions, section 7.5
1560 //
1561 primary_expression
1562         : literal
1563           {
1564                 // 7.5.1: Literals
1565           }
1566  
1567         | qualified_identifier
1568           {
1569                 string name = (string) $1;
1570
1571                 $$ = null;
1572                 $$ = DecomposeQI (name, lexer.Location);
1573           }
1574         | parenthesized_expression
1575         | member_access
1576         | invocation_expression
1577         | element_access
1578         | this_access
1579         | base_access
1580         | post_increment_expression
1581         | post_decrement_expression
1582         | new_expression
1583         | typeof_expression
1584         | sizeof_expression
1585         | checked_expression
1586         | unchecked_expression
1587         ;
1588
1589 literal
1590         : boolean_literal
1591         | integer_literal
1592         | real_literal
1593         | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
1594         | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
1595         | NULL                  { $$ = new NullLiteral (); }
1596         ;
1597
1598 real_literal
1599         : LITERAL_FLOAT         { $$ = new FloatLiteral ((float) lexer.Value); }
1600         | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
1601         | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
1602         ;
1603
1604 integer_literal
1605         : LITERAL_INTEGER       { 
1606                 object v = lexer.Value;
1607
1608                 // 
1609                 // FIXME: Possible optimization would be to 
1610                 // compute the *Literal objects directly in the scanner
1611                 //
1612                 if (v is int)
1613                         $$ = new IntLiteral ((Int32) v); 
1614                 else if (v is uint)
1615                         $$ = new UIntLiteral ((UInt32) v);
1616                 else if (v is long)
1617                         $$ = new LongLiteral ((Int64) v);
1618                 else if (v is ulong)
1619                         $$ = new ULongLiteral ((UInt64) v);
1620                 else
1621                         Console.WriteLine ("OOPS.  Unexpected result from scanner");
1622           }
1623         ;
1624
1625 boolean_literal
1626         : TRUE                  { $$ = new BoolLiteral (true); }
1627         | FALSE                 { $$ = new BoolLiteral (false); }
1628         ;
1629
1630 parenthesized_expression
1631         : OPEN_PARENS expression CLOSE_PARENS
1632           { $$ = $2; }
1633         ;
1634
1635 member_access
1636         : primary_expression DOT IDENTIFIER
1637           {
1638                 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
1639           }
1640         | predefined_type DOT IDENTIFIER
1641           {
1642                 $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location);
1643           }
1644         ;
1645
1646 predefined_type
1647         : builtin_types
1648         ;
1649
1650 invocation_expression
1651         : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
1652           {
1653                 // FIXME:
1654                 // if $1 is MethodGroup
1655                 //      $$ = new Call ($1, $3);
1656                 // else 
1657                 //      $$ = new DelegateCall ($1, $3);
1658                 if ($1 == null) {
1659                         Location l = lexer.Location;
1660                         Report.Error (1, l, "THIS IS CRAZY");
1661                 }
1662                 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
1663                 
1664           }
1665         ; 
1666
1667 opt_argument_list
1668         : /* empty */           { $$ = null; }
1669         | argument_list
1670         ;
1671
1672 argument_list
1673         : argument              
1674           { 
1675                 ArrayList list = new ArrayList ();
1676                 list.Add ($1);
1677                 $$ = list;
1678           }
1679         | argument_list COMMA argument
1680           {
1681                 ArrayList list = (ArrayList) $1;
1682                 list.Add ($3);
1683                 $$ = list;
1684           }
1685         ;
1686
1687 argument
1688         : expression
1689           {
1690                 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
1691           }
1692         | REF variable_reference 
1693           { 
1694                 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
1695           }
1696         | OUT variable_reference 
1697           { 
1698                 $$ = new Argument ((Expression) $2, Argument.AType.Out);
1699           }
1700         ;
1701
1702 variable_reference
1703         : expression { note ("section 5.4"); $$ = $1; }
1704         ;
1705
1706 element_access
1707         : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET 
1708           {
1709                 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
1710           }
1711         ;
1712
1713 expression_list
1714         : expression
1715           {
1716                 ArrayList list = new ArrayList ();
1717                 list.Add ($1);
1718                 $$ = list;
1719           }
1720         | expression_list COMMA expression
1721           {
1722                 ArrayList list = (ArrayList) $1;
1723                 list.Add ($3);
1724                 $$ = list;
1725           }
1726         ;
1727
1728 this_access
1729         : THIS
1730           {
1731                 $$ = new This (lexer.Location);
1732           }
1733         ;
1734
1735 base_access
1736         : BASE DOT IDENTIFIER
1737           {
1738                 $$ = new BaseAccess (BaseAccess.BaseAccessType.Member, (string) $3, null);
1739           }
1740         | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
1741           {
1742                 $$ = new BaseAccess (BaseAccess.BaseAccessType.Indexer, null, (ArrayList) $3);
1743           }
1744         ;
1745
1746 post_increment_expression
1747         : primary_expression OP_INC
1748           {
1749                 $$ = new Unary (Unary.Operator.PostIncrement, (Expression) $1, lexer.Location);
1750           }
1751         ;
1752
1753 post_decrement_expression
1754         : primary_expression OP_DEC
1755           {
1756                 $$ = new Unary (Unary.Operator.PostDecrement, (Expression) $1, lexer.Location);
1757           }
1758         ;
1759
1760 new_expression
1761         : object_or_delegate_creation_expression
1762         | array_creation_expression
1763         ;
1764
1765 object_or_delegate_creation_expression
1766         : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
1767           {
1768                 $$ = new New ((string) $2, (ArrayList) $4, lexer.Location);
1769           }
1770         ;
1771
1772 array_creation_expression
1773         : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET 
1774           opt_rank_specifier
1775           opt_array_initializer
1776           {
1777                 $$ = new ArrayCreation ((string) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, 
1778                                         lexer.Location);
1779           }
1780         | NEW type rank_specifiers array_initializer
1781           {
1782                 $$ = new ArrayCreation ((string) $2, (string) $3, (ArrayList) $4, lexer.Location);
1783           }
1784         ;
1785
1786 opt_rank_specifier
1787         : /* empty */
1788           {
1789                   $$ = "";
1790           }
1791         | rank_specifiers
1792           {
1793                         $$ = $1;
1794           }
1795         ;
1796
1797 rank_specifiers
1798         : rank_specifier
1799           {
1800                   $$ = $1;
1801           }
1802         | rank_specifiers rank_specifier
1803           {
1804                   $$ = (string) $2 + (string) $1;
1805           }             
1806         ;
1807
1808 rank_specifier
1809         : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
1810           {
1811                 $$ = "[" + (string) $2 + "]";
1812           }
1813         ;
1814
1815 opt_dim_separators
1816         : /* empty */
1817           {
1818                 $$ = "";
1819           }
1820         | dim_separators
1821           {
1822                   $$ = $1;
1823           }               
1824         ;
1825
1826 dim_separators
1827         : COMMA
1828           {
1829                 $$ = ",";
1830           }
1831         | dim_separators COMMA
1832           {
1833                 $$ = (string) $1 + ",";
1834           }
1835         ;
1836
1837 opt_array_initializer
1838         : /* empty */
1839           {
1840                 $$ = null;
1841           }
1842         | array_initializer
1843           {
1844                 $$ = $1;
1845           }
1846         ;
1847
1848 array_initializer
1849         : OPEN_BRACE CLOSE_BRACE
1850           {
1851                 ArrayList list = new ArrayList ();
1852                 $$ = list;
1853           }
1854         | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
1855           {
1856                 $$ = (ArrayList) $2;
1857           }
1858         ;
1859
1860 variable_initializer_list
1861         : variable_initializer
1862           {
1863                 ArrayList list = new ArrayList ();
1864                 list.Add ($1);
1865                 $$ = list;
1866           }
1867         | variable_initializer_list COMMA variable_initializer
1868           {
1869                 ArrayList list = (ArrayList) $1;
1870                 list.Add ($3);
1871                 $$ = list;
1872           }
1873         ;
1874
1875 typeof_expression
1876         : TYPEOF OPEN_PARENS type CLOSE_PARENS
1877           {
1878                 $$ = new TypeOf ((string) $3);
1879           }
1880         ;
1881
1882 sizeof_expression
1883         : SIZEOF OPEN_PARENS type CLOSE_PARENS { 
1884                 $$ = new SizeOf ((string) $3);
1885
1886                 note ("Verify type is unmanaged"); 
1887                 note ("if (5.8) builtin, yield constant expression");
1888           }
1889         ;
1890
1891 checked_expression
1892         : CHECKED OPEN_PARENS expression CLOSE_PARENS
1893           {
1894                 $$ = new CheckedExpr ((Expression) $3);
1895           }
1896         ;
1897
1898 unchecked_expression
1899         : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
1900           {
1901                 $$ = new UnCheckedExpr ((Expression) $3);
1902           }
1903         ;
1904
1905 unary_expression
1906         : primary_expression
1907         | PLUS unary_expression
1908           { 
1909                 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
1910           } 
1911         | MINUS unary_expression 
1912           { 
1913                 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
1914           }
1915         | BANG unary_expression 
1916           {
1917                 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
1918           }
1919         | TILDE unary_expression
1920           {
1921                 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
1922           }
1923         | STAR unary_expression
1924           {
1925                 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, lexer.Location);
1926           }
1927         | BITWISE_AND unary_expression
1928           {
1929                 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, lexer.Location);
1930           }
1931         | OP_INC unary_expression 
1932           {
1933                 $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
1934           }
1935         | OP_DEC unary_expression 
1936           {
1937                 $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
1938           }
1939         | cast_expression 
1940         /*
1941          we can not do cast expressions at this level,
1942          as there is an ambiguity.  Check "Cast Expressions" 7.6.8
1943          for the recipe to handle this.
1944          */
1945         ;
1946
1947 pre_increment_expression
1948         : OP_INC unary_expression 
1949           {
1950                 $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2, lexer.Location);
1951           }
1952         ;
1953
1954 pre_decrement_expression
1955         : OP_DEC unary_expression 
1956           {
1957                 $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2, lexer.Location);
1958           }
1959         ;
1960
1961 cast_expression
1962         /* 
1963          * FIXME: This is actually wrong, it should be `type' but that
1964          * introduces a lot of {shift,reduce}/reduces
1965          *
1966          * This is really really wrong.  We need to track down
1967          * the source of problems with QIs because expressions like:
1968          * foreach (string s in (string []) object) wont be parsed.
1969          */
1970         : OPEN_PARENS qualified_identifier CLOSE_PARENS unary_expression
1971           {
1972                 $$ = new Cast ((string) $2, (Expression) $4, lexer.Location);
1973           }
1974         | OPEN_PARENS builtin_types CLOSE_PARENS unary_expression
1975           {
1976                 $$ = new Cast ((string) $2, (Expression) $4, lexer.Location);
1977           }
1978         ;
1979
1980 multiplicative_expression
1981         : unary_expression
1982         | multiplicative_expression STAR unary_expression
1983           {
1984                 $$ = new Binary (Binary.Operator.Multiply, 
1985                                  (Expression) $1, (Expression) $3, lexer.Location);
1986           }
1987         | multiplicative_expression DIV unary_expression
1988           {
1989                 $$ = new Binary (Binary.Operator.Division, 
1990                                  (Expression) $1, (Expression) $3, lexer.Location);
1991           }
1992         | multiplicative_expression PERCENT unary_expression 
1993           {
1994                 $$ = new Binary (Binary.Operator.Modulus, 
1995                                  (Expression) $1, (Expression) $3, lexer.Location);
1996           }
1997         ;
1998
1999 additive_expression
2000         : multiplicative_expression
2001         | additive_expression PLUS multiplicative_expression 
2002           {
2003                 $$ = new Binary (Binary.Operator.Addition, 
2004                                  (Expression) $1, (Expression) $3, lexer.Location);
2005           }
2006         | additive_expression MINUS multiplicative_expression
2007           {
2008                 $$ = new Binary (Binary.Operator.Subtraction, 
2009                                  (Expression) $1, (Expression) $3, lexer.Location);
2010           }
2011         ;
2012
2013 shift_expression
2014         : additive_expression
2015         | shift_expression OP_SHIFT_LEFT additive_expression
2016           {
2017                 $$ = new Binary (Binary.Operator.LeftShift, 
2018                                  (Expression) $1, (Expression) $3, lexer.Location);
2019           }
2020         | shift_expression OP_SHIFT_RIGHT additive_expression
2021           {
2022                 $$ = new Binary (Binary.Operator.RightShift, 
2023                                  (Expression) $1, (Expression) $3, lexer.Location);
2024           }
2025         ; 
2026
2027 relational_expression
2028         : shift_expression
2029         | relational_expression OP_LT shift_expression
2030           {
2031                 $$ = new Binary (Binary.Operator.LessThan, 
2032                                  (Expression) $1, (Expression) $3, lexer.Location);
2033           }
2034         | relational_expression OP_GT shift_expression
2035           {
2036                 $$ = new Binary (Binary.Operator.GreaterThan, 
2037                                  (Expression) $1, (Expression) $3, lexer.Location);
2038           }
2039         | relational_expression OP_LE shift_expression
2040           {
2041                 $$ = new Binary (Binary.Operator.LessThanOrEqual, 
2042                                  (Expression) $1, (Expression) $3, lexer.Location);
2043           }
2044         | relational_expression OP_GE shift_expression
2045           {
2046                 $$ = new Binary (Binary.Operator.GreaterThanOrEqual, 
2047                                  (Expression) $1, (Expression) $3, lexer.Location);
2048           }
2049         | relational_expression IS type
2050           {
2051                 $$ = new Probe (Probe.Operator.Is, 
2052                                  (Expression) $1, (string) $3);
2053           }
2054         | relational_expression AS type
2055           {
2056                 $$ = new Probe (Probe.Operator.As, 
2057                                  (Expression) $1, (string) $3);
2058           }
2059         ;
2060
2061 equality_expression
2062         : relational_expression
2063         | equality_expression OP_EQ relational_expression
2064           {
2065                 $$ = new Binary (Binary.Operator.Equality, 
2066                                  (Expression) $1, (Expression) $3, lexer.Location);
2067           }
2068         | equality_expression OP_NE relational_expression
2069           {
2070                 $$ = new Binary (Binary.Operator.Inequality, 
2071                                  (Expression) $1, (Expression) $3, lexer.Location);
2072           }
2073         ; 
2074
2075 and_expression
2076         : equality_expression
2077         | and_expression BITWISE_AND equality_expression
2078           {
2079                 $$ = new Binary (Binary.Operator.BitwiseAnd, 
2080                                  (Expression) $1, (Expression) $3, lexer.Location);
2081           }
2082         ;
2083
2084 exclusive_or_expression
2085         : and_expression
2086         | exclusive_or_expression CARRET and_expression
2087           {
2088                 $$ = new Binary (Binary.Operator.ExclusiveOr, 
2089                                  (Expression) $1, (Expression) $3, lexer.Location);
2090           }
2091         ;
2092
2093 inclusive_or_expression
2094         : exclusive_or_expression
2095         | inclusive_or_expression BITWISE_OR exclusive_or_expression
2096           {
2097                 $$ = new Binary (Binary.Operator.BitwiseOr, 
2098                                  (Expression) $1, (Expression) $3, lexer.Location);
2099           }
2100         ;
2101
2102 conditional_and_expression
2103         : inclusive_or_expression
2104         | conditional_and_expression OP_AND inclusive_or_expression
2105           {
2106                 $$ = new Binary (Binary.Operator.LogicalAnd, 
2107                                  (Expression) $1, (Expression) $3, lexer.Location);
2108           }
2109         ;
2110
2111 conditional_or_expression
2112         : conditional_and_expression
2113         | conditional_or_expression OP_OR conditional_and_expression
2114           {
2115                 $$ = new Binary (Binary.Operator.LogicalOr, 
2116                                  (Expression) $1, (Expression) $3, lexer.Location);
2117           }
2118         ;
2119
2120 conditional_expression
2121         : conditional_or_expression
2122         | conditional_or_expression INTERR expression COLON expression 
2123           {
2124                 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5, lexer.Location);
2125           }
2126         ;
2127
2128 assignment_expression
2129         : unary_expression ASSIGN expression
2130           {
2131                 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
2132           }
2133         | unary_expression OP_MULT_ASSIGN expression
2134           {
2135                 Location l = lexer.Location;
2136
2137                 $$ = new Assign ((Expression) $1,
2138                                  new Binary (Binary.Operator.Multiply, 
2139                                              (Expression) $1,
2140                                              (Expression) $3, l), l);
2141           }
2142         | unary_expression OP_DIV_ASSIGN expression
2143           {
2144                 Location l = lexer.Location;
2145
2146                 $$ = new Assign ((Expression) $1,
2147                                  new Binary (Binary.Operator.Division, 
2148                                              (Expression) $1,
2149                                              (Expression) $3, l), l);
2150           }
2151         | unary_expression OP_MOD_ASSIGN expression
2152           {
2153                 Location l = lexer.Location;
2154
2155                 $$ = new Assign ((Expression) $1,
2156                                  new Binary (Binary.Operator.Modulus, 
2157                                              (Expression) $1,
2158                                              (Expression) $3, l), l);
2159           }
2160         | unary_expression OP_ADD_ASSIGN expression
2161           {
2162                 Location l = lexer.Location;
2163
2164                 $$ = new Assign ((Expression) $1,
2165                                  new Binary (Binary.Operator.Addition, 
2166                                              (Expression) $1,
2167                                              (Expression) $3, l), l);
2168           }
2169         | unary_expression OP_SUB_ASSIGN expression
2170           {
2171                 Location l = lexer.Location;
2172
2173                 $$ = new Assign ((Expression) $1,
2174                                  new Binary (Binary.Operator.Subtraction, 
2175                                              (Expression) $1,
2176                                              (Expression) $3, l), l);
2177           }
2178         | unary_expression OP_SHIFT_LEFT_ASSIGN expression
2179           {
2180                 Location l = lexer.Location;
2181
2182                 $$ = new Assign ((Expression) $1,
2183                                  new Binary (Binary.Operator.LeftShift, 
2184                                              (Expression) $1,
2185                                              (Expression) $3, l), l);
2186           }
2187         | unary_expression OP_SHIFT_RIGHT_ASSIGN expression
2188           {
2189                 Location l = lexer.Location;
2190
2191                 $$ = new Assign ((Expression) $1,
2192                                  new Binary (Binary.Operator.RightShift, 
2193                                              (Expression) $1,
2194                                              (Expression) $3, l), l);
2195           }
2196         | unary_expression OP_AND_ASSIGN expression
2197           {
2198                 Location l = lexer.Location;
2199
2200                 $$ = new Assign ((Expression) $1,
2201                                  new Binary (Binary.Operator.BitwiseAnd, 
2202                                              (Expression) $1,
2203                                              (Expression) $3, l), l);
2204           }
2205         | unary_expression OP_OR_ASSIGN expression
2206           {
2207                 Location l = lexer.Location;
2208
2209                 $$ = new Assign ((Expression) $1,
2210                                  new Binary (Binary.Operator.BitwiseOr, 
2211                                              (Expression) $1,
2212                                              (Expression) $3, l), l);
2213           }
2214         | unary_expression OP_XOR_ASSIGN expression
2215           {
2216                 Location l = lexer.Location;
2217
2218                 $$ = new Assign ((Expression) $1,
2219                                  new Binary (Binary.Operator.ExclusiveOr, 
2220                                              (Expression) $1,
2221                                              (Expression) $3, l), l);
2222           }
2223         ;
2224
2225 expression
2226         : conditional_expression
2227         | assignment_expression
2228         ;
2229
2230 constant_expression
2231         : expression
2232         ;
2233
2234 boolean_expression
2235         : expression    { CheckBoolean ((Expression) $1); $$ = $1; } 
2236         ;
2237
2238 //
2239 // 10 classes
2240 //
2241 class_declaration
2242         : opt_attributes
2243           opt_modifiers
2244           CLASS IDENTIFIER
2245           {
2246                 Class new_class;
2247                 string full_class_name = MakeName ((string) $4);
2248
2249                 new_class = new Class (rc, current_container, full_class_name, (int) $2, 
2250                                        (Attributes) $1, lexer.Location);
2251                 current_container = new_class;
2252                 current_container.Namespace = current_namespace;
2253                 tree.RecordClass (full_class_name, new_class);
2254           }
2255           opt_class_base
2256           class_body 
2257           opt_semicolon 
2258           {
2259                 Class new_class = (Class) current_container;
2260
2261                 if ($6 != null)
2262                         new_class.Bases = (ArrayList) $6;
2263
2264                 current_container = current_container.Parent;
2265                 CheckDef (current_container.AddClass (new_class), new_class.Name);
2266
2267                 $$ = new_class;
2268           }
2269         ;       
2270
2271 opt_modifiers
2272         : /* empty */           { $$ = (int) 0; }
2273         | modifiers
2274         ;
2275
2276 modifiers
2277         : modifier
2278         | modifiers modifier
2279           { 
2280                 int m1 = (int) $1;
2281                 int m2 = (int) $2;
2282
2283                 if ((m1 & m2) != 0) {
2284                         Location l = lexer.Location;
2285                         Report.Error (1002, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
2286                 }
2287                 $$ = (int) (m1 | m2);
2288           }
2289         ;
2290
2291 modifier
2292         : NEW                   { $$ = Modifiers.NEW; }
2293         | PUBLIC                { $$ = Modifiers.PUBLIC; }
2294         | PROTECTED             { $$ = Modifiers.PROTECTED; }
2295         | INTERNAL              { $$ = Modifiers.INTERNAL; }
2296         | PRIVATE               { $$ = Modifiers.PRIVATE; }
2297         | ABSTRACT              { $$ = Modifiers.ABSTRACT; }
2298         | SEALED                { $$ = Modifiers.SEALED; }
2299         | STATIC                { $$ = Modifiers.STATIC; }
2300         | READONLY              { $$ = Modifiers.READONLY; }
2301         | VIRTUAL               { $$ = Modifiers.VIRTUAL; }
2302         | OVERRIDE              { $$ = Modifiers.OVERRIDE; }
2303         | EXTERN                { $$ = Modifiers.EXTERN; }
2304         ;
2305
2306 opt_class_base
2307         : /* empty */           { $$ = null; }
2308         | class_base            { $$ = $1;   }
2309         ;
2310
2311 class_base
2312         : COLON type_list { $$ = $2; }
2313         ;
2314
2315 //
2316 // Statements (8.2)
2317 //
2318
2319 //
2320 // A block is "contained" on the following places:
2321 //      method_body
2322 //      property_declaration as part of the accessor body (get/set)
2323 //      operator_declaration
2324 //      constructor_declaration
2325 //      destructor_declaration
2326 //      event_declaration as part of add_accessor_declaration or remove_accessor_declaration
2327 //      
2328 block
2329         : OPEN_BRACE 
2330           {
2331                 current_block = new Block (current_block);
2332           } 
2333           opt_statement_list CLOSE_BRACE 
2334           { 
2335                 while (current_block.Implicit)
2336                         current_block = current_block.Parent;
2337                 $$ = current_block;
2338                 current_block = current_block.Parent;
2339           }
2340         ;
2341
2342 opt_statement_list
2343         : /* empty */
2344         | statement_list 
2345         ;
2346
2347 statement_list
2348         : statement
2349         | statement_list statement
2350         ;
2351
2352 statement
2353         : declaration_statement
2354           {
2355                 if ((Block) $1 != current_block){
2356                         current_block.AddStatement ((Statement) $1);
2357                         current_block = (Block) $1;
2358                 }
2359           }
2360         | embedded_statement
2361           {
2362                 current_block.AddStatement ((Statement) $1);
2363           }
2364         | labeled_statement 
2365           {
2366                 current_block.AddStatement ((Statement) $1);
2367           }
2368         ;
2369
2370 embedded_statement
2371         : block
2372         | empty_statement
2373         | expression_statement
2374         | selection_statement
2375         | iteration_statement
2376         | jump_statement                  
2377         | try_statement
2378         | checked_statement
2379         | unchecked_statement
2380         | lock_statement
2381         | using_statement
2382         ;
2383
2384 empty_statement
2385         : SEMICOLON
2386           {
2387                   $$ = new EmptyStatement ();
2388           }
2389         ;
2390
2391 labeled_statement
2392         : IDENTIFIER COLON statement
2393           {
2394                 string lab = (String) $1;
2395                 Block block;
2396
2397                 block = new Block (current_block, lab);
2398                 block.AddStatement ((Statement) $3);
2399                 $$ = block;
2400
2401                 if (!current_block.AddLabel (lab, block)){
2402                         Location l = lexer.Location;
2403                         Report.Error (140, l, "The label '" + lab + "' is a duplicate");
2404                         $$ = $3;
2405                 }       
2406           }
2407         ;
2408
2409 declaration_statement
2410         : local_variable_declaration SEMICOLON          // done
2411         | local_constant_declaration SEMICOLON          // finishme
2412         ;
2413
2414 /* 
2415  * The following is from Rhys' grammar:
2416  * > Types in local variable declarations must be recognized as 
2417  * > expressions to prevent reduce/reduce errors in the grammar.
2418  * > The expressions are converted into types during semantic analysis.
2419  */
2420 local_variable_type
2421         : primary_expression opt_rank_specifier
2422           { 
2423                 // FIXME: Do something smart here regarding the composition of the type.
2424
2425                 // Ok, the above "primary_expression" is there to get rid of
2426                 // both reduce/reduce and shift/reduces in the grammar, it should
2427                 // really just be "type_name".  If you use type_name, a reduce/reduce
2428                 // creeps up.  If you use qualified_identifier (which is all we need
2429                 // really) two shift/reduces appear.
2430                 // 
2431                 // So, instead we do a super trick: we just allow ($1) to be a 
2432                 // SimpleName Expression.
2433                 //
2434                 if (((Expression) $1) is SimpleName)
2435                         $$ = ((SimpleName) $1).Name + (string) $2;
2436                 else {
2437                         Location l = lexer.Location;
2438                         Report.Error (-1, l, "Invalid Type definition");
2439                         $$ = "System.Object";
2440                 }
2441           }
2442         | builtin_types opt_rank_specifier
2443           {
2444                   $$ = (string) $1 + (string) $2;
2445           }
2446         ;
2447
2448 // FIXME : How can the type of a local variable be void ? I don't quite see ;-)
2449 //          | VOID 
2450 //        {
2451 //              // FIXME: this is a string that represents the type
2452 //              // Figure out something to make this work.
2453 //              $$ = "void";
2454 //        }
2455 //      ;
2456
2457 local_variable_declaration
2458         : local_variable_type variable_declarators
2459           {
2460                 $$ = declare_local_variables ((string) $1, (ArrayList) $2);
2461           }
2462         ;
2463
2464 local_constant_declaration
2465         : CONST type constant_declarator
2466                 // finishme     
2467         ;
2468
2469 expression_statement
2470         : statement_expression SEMICOLON
2471           {
2472                 $$ = $1;
2473           }
2474         ;
2475
2476         //
2477         // We have to do the wrapping here and not in the case above,
2478         // because statement_expression is used for example in for_statement
2479         //
2480 statement_expression
2481         : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1); }
2482         | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1); }
2483         | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1); }
2484         | post_increment_expression     { $$ = new StatementExpression ((ExpressionStatement) $1); }
2485         | post_decrement_expression     { $$ = new StatementExpression ((ExpressionStatement) $1); }
2486         | pre_increment_expression      { $$ = new StatementExpression ((ExpressionStatement) $1); }
2487         | pre_decrement_expression      { $$ = new StatementExpression ((ExpressionStatement) $1); }
2488         ;
2489
2490 object_creation_expression
2491         : object_or_delegate_creation_expression
2492           { note ("complain if this is a delegate maybe?"); } 
2493         ;
2494
2495 selection_statement
2496         : if_statement
2497         | switch_statement
2498         ; 
2499
2500 if_statement
2501         : IF OPEN_PARENS boolean_expression CLOSE_PARENS 
2502           embedded_statement
2503           { 
2504                 $$ = new If ((Expression) $3, (Statement) $5);
2505           }
2506         | IF OPEN_PARENS boolean_expression CLOSE_PARENS
2507           embedded_statement ELSE embedded_statement
2508           {
2509                 $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7);
2510           }
2511         ;
2512
2513 switch_statement
2514         : SWITCH OPEN_PARENS expression CLOSE_PARENS 
2515           switch_block
2516           {
2517                 $$ = new Switch ((Expression) $3, (ArrayList) $5);
2518           }
2519         ;
2520
2521 switch_block
2522         : OPEN_BRACE
2523           opt_switch_sections
2524           CLOSE_BRACE
2525           {
2526                 $$ = $2;
2527           }
2528         ;
2529
2530 opt_switch_sections
2531         : /* empty */           { $$ = new ArrayList (); }
2532         | switch_sections
2533         ;
2534
2535 switch_sections
2536         : switch_section 
2537           {
2538                 ArrayList sections = new ArrayList ();
2539
2540                 sections.Add ($1);
2541                 $$ = sections;
2542           }
2543         | switch_sections switch_section
2544           {
2545                 ArrayList sections = (ArrayList) $1;
2546
2547                 sections.Add ($2);
2548                 $$ = sections;
2549           }
2550         ;
2551
2552 switch_section
2553         : switch_labels
2554           {
2555                 current_block = new Block (current_block);
2556           }
2557           statement_list 
2558           {
2559                 while (current_block.Implicit)
2560                         current_block = current_block.Parent;
2561                 $$ = new SwitchSection ((ArrayList) $1, current_block);
2562                 current_block = current_block.Parent;
2563           }
2564         ;
2565
2566 switch_labels
2567         : switch_label 
2568           {
2569                 ArrayList labels = new ArrayList ();
2570
2571                 labels.Add ($1);
2572                 $$ = labels;
2573           }
2574         | switch_labels switch_label 
2575           {
2576                 ArrayList labels = (ArrayList) ($1);
2577                 labels.Add ($2);
2578
2579                 $$ = labels;
2580           }
2581         ;
2582
2583 switch_label
2584         : CASE constant_expression COLON        { $$ = new SwitchLabel ((Expression) $2); }
2585         | DEFAULT COLON                         { $$ = new SwitchLabel (null); }
2586         ;
2587
2588 iteration_statement
2589         : while_statement
2590         | do_statement
2591         | for_statement
2592         | foreach_statement
2593         ;
2594
2595 while_statement
2596         : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
2597         {
2598                 $$ = new While ((Expression) $3, (Statement) $5);
2599         }
2600         ;
2601
2602 do_statement
2603         : DO embedded_statement 
2604           WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
2605           {
2606                 $$ = new Do ((Statement) $2, (Expression) $5);
2607           }
2608         ;
2609
2610 for_statement
2611         : FOR OPEN_PARENS 
2612           opt_for_initializer SEMICOLON
2613           opt_for_condition SEMICOLON
2614           opt_for_iterator CLOSE_PARENS 
2615           embedded_statement
2616           {
2617                 $$ = new For ((Statement) $3, (Expression) $5, (Statement) $7, (Statement) $9);
2618           }
2619         ;
2620
2621 opt_for_initializer
2622         : /* empty */           { $$ = new EmptyStatement (); }
2623         | for_initializer       
2624         ;
2625
2626 for_initializer
2627         : local_variable_declaration 
2628           {
2629                 if ((Block) $1 != current_block){
2630                         current_block.AddStatement ((Statement) $1);
2631                         current_block = (Block) $1;
2632                 }
2633           }
2634         | statement_expression_list
2635         ;
2636
2637 opt_for_condition
2638         : /* empty */           { $$ = new BoolLiteral (true); }
2639         | boolean_expression
2640         ;
2641
2642 opt_for_iterator
2643         : /* empty */           { $$ = new EmptyStatement (); }
2644         | for_iterator
2645         ;
2646
2647 for_iterator
2648         : statement_expression_list
2649         ;
2650
2651 statement_expression_list
2652         : statement_expression  
2653           {
2654                 Block b = new Block (null, true);
2655
2656                 b.AddStatement ((Statement) $1);
2657                 $$ = b;
2658           }
2659         | statement_expression_list COMMA statement_expression
2660           {
2661                 Block b = (Block) $1;
2662
2663                 b.AddStatement ((Statement) $3);
2664                 $$ = $1;
2665           }
2666         ;
2667
2668 foreach_statement
2669         : FOREACH OPEN_PARENS type IDENTIFIER IN 
2670           { 
2671                 $1 = lexer.Location;
2672           } 
2673           expression CLOSE_PARENS 
2674           embedded_statement
2675           {
2676                 Block foreach_block = new Block (current_block, true);
2677                 LocalVariableReference v;
2678
2679                 foreach_block.AddVariable ((string) $3, (string) $4, (Location) $1);
2680                 v = new LocalVariableReference (foreach_block, (string) $4);
2681                 foreach_block.AddStatement (new Foreach ((string) $3, v, (Expression) $7, 
2682                                             (Statement) $9, (Location) $1));
2683                 $$ = foreach_block;
2684           }
2685         ;
2686
2687 jump_statement
2688         : break_statement
2689         | continue_statement
2690         | goto_statement
2691         | return_statement
2692         | throw_statement
2693         ;
2694
2695 break_statement
2696         : BREAK SEMICOLON
2697           {
2698                 $$ = new Break (lexer.Location);
2699           }
2700         ;
2701
2702 continue_statement
2703         : CONTINUE SEMICOLON
2704           {
2705                 $$ = new Continue (lexer.Location);
2706           }
2707         ;
2708
2709 goto_statement
2710         : GOTO IDENTIFIER SEMICOLON 
2711           {
2712                 $$ = new Goto ((string) $2, lexer.Location);
2713           }
2714         | GOTO CASE constant_expression SEMICOLON
2715           {
2716                 // FIXME
2717           }
2718         | GOTO DEFAULT SEMICOLON 
2719           {
2720                 // FIXME
2721           }
2722         ; 
2723
2724 return_statement
2725         : RETURN opt_expression SEMICOLON
2726           {
2727                 $$ = new Return ((Expression) $2, lexer.Location);
2728           }
2729         ;
2730
2731 throw_statement
2732         : THROW opt_expression SEMICOLON
2733           {
2734                 $$ = new Throw ((Expression) $2);
2735           }
2736         ;
2737
2738 opt_expression
2739         : /* empty */
2740         | expression
2741         ;
2742
2743 try_statement
2744         : TRY block catch_clauses 
2745         {
2746                 Catch g = null;
2747                 ArrayList s = new ArrayList ();
2748                 
2749                 foreach (Catch cc in (ArrayList) $3) {
2750                         if (cc.Type == null)
2751                                 g = cc;
2752                         else
2753                                 s.Add (cc);
2754                 }
2755
2756                 // Now s contains the list of specific catch clauses
2757                 // and g contains the general one.
2758                 
2759                 $$ = new Try ((Block) $2, s, g, null);
2760         }
2761         | TRY block opt_catch_clauses FINALLY block
2762           {
2763                 Catch g = null;
2764                 ArrayList s = new ArrayList ();
2765                 
2766                 foreach (Catch cc in (ArrayList) $3) {
2767                         if (cc.Type == null)
2768                                 g = cc;
2769                         else
2770                                 s.Add (cc);
2771                 }
2772
2773                 $$ = new Try ((Block) $2, s, g, (Block) $5);
2774           }
2775         ;
2776
2777 opt_catch_clauses
2778         : /* empty */  { $$ = null; }
2779         | catch_clauses
2780         ;
2781
2782 catch_clauses
2783         : catch_clause 
2784           {
2785                 ArrayList l = new ArrayList ();
2786
2787                 l.Add ($1);
2788                 $$ = l;
2789           }
2790         | catch_clauses catch_clause
2791           {
2792                 ArrayList l = (ArrayList) $1;
2793
2794                 l.Add ($2);
2795                 $$ = l;
2796           }
2797         ;
2798
2799 opt_identifier
2800         : /* empty */   { $$ = null; }
2801         | IDENTIFIER
2802         ;
2803
2804 catch_clause 
2805         : CATCH opt_catch_args 
2806         {
2807                 string type = null, id = null;
2808                 
2809                 if ($2 != null) {
2810                         DictionaryEntry cc = (DictionaryEntry) $2;
2811                         type = (string) cc.Key;
2812                         id   = (string) cc.Value;
2813
2814                         if (id != null){
2815                                 ArrayList one = new ArrayList ();
2816                                 one.Add (new VariableDeclaration (id, null, lexer.Location));
2817
2818                                 $1 = current_block;
2819                                 current_block = new Block (current_block);
2820                                 Block b = declare_local_variables (type, one);
2821                                 current_block = b;
2822
2823                                 
2824                         }
2825                 }
2826         } block {
2827                 string type = null, id = null;
2828
2829                 if ($2 != null){
2830                         DictionaryEntry cc = (DictionaryEntry) $2;
2831                         type = (string) cc.Key;
2832                         id   = (string) cc.Value;
2833
2834                         if ($1 != null){
2835                                 while (current_block != (Block) $1)
2836                                         current_block = current_block.Parent;
2837                         }
2838                 }
2839
2840
2841                 $$ = new Catch (type, id , (Block) $4);
2842         }
2843         ;
2844
2845 opt_catch_args
2846         : /* empty */ { $$ = null; }
2847         | catch_args
2848         ;         
2849
2850 catch_args 
2851         : OPEN_PARENS type opt_identifier CLOSE_PARENS 
2852         {
2853                 $$ = new DictionaryEntry ($2, $3);
2854         }
2855         ;
2856
2857 checked_statement
2858         : CHECKED block
2859           {
2860                 $$ = new Checked ((Block) $2);
2861           }
2862         ;
2863
2864 unchecked_statement
2865         : UNCHECKED block
2866           {
2867                 $$ = new Unchecked ((Block) $2);
2868           }
2869         ;
2870
2871 lock_statement
2872         : LOCK OPEN_PARENS expression CLOSE_PARENS 
2873           {
2874                 $1 = lexer.Location;
2875           } 
2876           embedded_statement
2877           {
2878                 $$ = new Lock ((Expression) $3, (Statement) $6, (Location) $1);
2879           }
2880         ;
2881
2882 using_statement
2883         : USING OPEN_PARENS resource_acquisition CLOSE_PARENS 
2884           {
2885                 $1 = lexer.Location;
2886           } 
2887           embedded_statement
2888           {
2889                 $$ = new Using ($3, (Statement) $6, (Location) $1);
2890           }
2891         ; 
2892
2893 resource_acquisition
2894         : local_variable_declaration
2895           {
2896                 if ((Block) $1 != current_block){
2897                         current_block.AddStatement ((Statement) $1);
2898                         current_block = (Block) $1;
2899                 }
2900           }
2901         | expression
2902         ;
2903
2904 %%
2905
2906 // <summary>
2907 //   A class used to pass around variable declarations and constants
2908 // </summary>
2909 public class VariableDeclaration {
2910         public string identifier;
2911         public object expression_or_array_initializer;
2912         public Location Location;
2913
2914         public VariableDeclaration (string id, object eoai, Location l){
2915                 this.identifier = id;
2916                 this.expression_or_array_initializer = eoai;
2917                 this.Location = l;
2918         }
2919 }
2920
2921 // <summary>
2922 //   A class used to hold info about an indexer declarator
2923 // </summary>
2924
2925 public class IndexerDeclaration {
2926         public string type;
2927         public string interface_type;
2928         public Parameters param_list;
2929
2930         public IndexerDeclaration (string type, string interface_type, Parameters param_list)
2931         {
2932                 this.type = type;
2933                 this.interface_type = interface_type;
2934                 this.param_list = param_list;
2935         }
2936 }
2937
2938 // <summary>
2939 //  A class used to hold info about an operator declarator
2940 // </summary>
2941
2942 public class OperatorDeclaration {
2943         public Operator.OpType optype;
2944         public string ret_type;
2945         public string arg1type;
2946         public string arg1name;
2947         public string arg2type;
2948         public string arg2name;
2949         public Location location;
2950
2951         public OperatorDeclaration (Operator.OpType op, string ret_type, string arg1type, string arg1name,
2952                                     string arg2type, string arg2name, Location location)
2953         {
2954                 optype = op;
2955                 this.ret_type = ret_type;
2956                 this.arg1type = arg1type;
2957                 this.arg1name = arg1name;
2958                 this.arg2type = arg2type;
2959                 this.arg2name = arg2name;
2960                 this.location = location;
2961         }
2962
2963 }
2964
2965 // <summary>
2966 //   Given the @class_name name, it creates a fully qualified name
2967 //   based on the containing declaration space
2968 // </summary>
2969 string 
2970 MakeName (string class_name)
2971 {
2972         string ns = current_namespace.Name;
2973         string container_name = current_container.Name;
2974
2975         if (container_name == ""){
2976                 if (ns != "")
2977                         return ns + "." + class_name;
2978                 else
2979                         return class_name;
2980         } else
2981                 return container_name + "." + class_name;
2982 }
2983
2984 // <summary>
2985 //   Used to report back to the user the result of a declaration
2986 //   in the current declaration space
2987 // </summary>
2988 void 
2989 CheckDef (DeclSpace.AdditionResult result, string name)
2990 {
2991         if (result == DeclSpace.AdditionResult.Success)
2992                 return;
2993
2994         Location l = lexer.Location;
2995         
2996         switch (result){
2997         case DeclSpace.AdditionResult.NameExists:
2998                 Report.Error (102, l, "The namespace `" + current_container.Name + 
2999                                  "' already contains a definition for `"+
3000                                  name + "'");
3001                 break;
3002
3003
3004 //      NEED TO HANDLE THIS IN SEMANTIC ANALYSIS:
3005 //
3006 //      case DeclSpace.AdditionResult.MethodDuplicated:
3007 //              error (111, "Class `"+current_container.Name+
3008 //                          "' already defines a member called '" + 
3009 //                          name + "' with the same parameter types");
3010 //              break;
3011
3012         case DeclSpace.AdditionResult.EnclosingClash:
3013                 Report.Error (542, l, "Member names cannot be the same as their enclosing type");
3014                 break;
3015                 
3016         case DeclSpace.AdditionResult.NotAConstructor:
3017                 Report.Error (1520, l, "Class, struct, or interface method must have a return type");
3018                 break;
3019         }
3020 }
3021
3022 void 
3023 CheckDef (bool result, string name)
3024 {
3025         if (result)
3026                 return;
3027         CheckDef (DeclSpace.AdditionResult.NameExists, name);
3028 }
3029
3030 Expression
3031 SimpleLookup (string name)
3032 {
3033         //
3034         // we need to check against current_block not being null
3035         // as `expression' is allowed in argument_lists, which 
3036         // do not exist inside a block.  
3037         //
3038         if (current_block != null){
3039                 if (current_block.IsVariableDefined (name))
3040                         return new LocalVariableReference (current_block, name);
3041         }
3042
3043         if (current_local_parameters != null){
3044                 int idx;
3045                 Parameter par = current_local_parameters.GetParameterByName (name, out idx);
3046                 if (par != null)
3047                         return new ParameterReference (current_local_parameters, idx, name);
3048         }
3049
3050         return null;
3051 }
3052
3053 Expression DecomposeQI (string name, Location l)
3054 {
3055         Expression o;
3056
3057         if (name.IndexOf ('.') == -1){
3058                 o = SimpleLookup (name);
3059                 if (o == null)
3060                         return new SimpleName (name, l);
3061                 return o;
3062         } else {
3063                 int pos = name.LastIndexOf (".");
3064                 string left = name.Substring (0, pos);
3065                 string right = name.Substring (pos + 1);
3066
3067                 o = DecomposeQI (left, l);
3068                 return new MemberAccess (o, right, l);
3069         }
3070 }
3071
3072 Block declare_local_variables (string type, ArrayList variable_declarators)
3073 {
3074         Block implicit_block;
3075         ArrayList inits = null;
3076
3077         //
3078         // We use the `Used' property to check whether statements
3079         // have been added to the current block.  If so, we need
3080         // to create another block to contain the new declaration
3081         // otherwise, as an optimization, we use the same block to
3082         // add the declaration.
3083         //
3084         // FIXME: A further optimization is to check if the statements
3085         // that were added were added as part of the initialization
3086         // below.  In which case, no other statements have been executed
3087         // and we might be able to reduce the number of blocks for
3088         // situations like this:
3089         //
3090         // int j = 1;  int k = j + 1;
3091         //
3092         if (current_block.Used)
3093                 implicit_block = new Block (current_block, true);
3094         else
3095                 implicit_block = current_block;
3096
3097         foreach (VariableDeclaration decl in variable_declarators){
3098                 if (implicit_block.AddVariable (type, decl.identifier, decl.Location)){
3099                         if (decl.expression_or_array_initializer != null){
3100                                 if (inits == null)
3101                                         inits = new ArrayList ();
3102                                 inits.Add (decl);
3103                         }
3104                 } else {
3105                         Location l = lexer.Location;
3106                         Report.Error (128, l, "A local variable `" + decl.identifier +
3107                                          "' is already defined in this scope");
3108                 }
3109         }
3110
3111         if (inits == null)
3112                 return implicit_block;
3113
3114         foreach (VariableDeclaration decl in inits){
3115                 if (decl.expression_or_array_initializer is Expression){
3116                         Expression expr = (Expression) decl.expression_or_array_initializer;
3117                         Assign assign;
3118                         
3119                         assign = new Assign (new LocalVariableReference (
3120                                              implicit_block, decl.identifier), 
3121                                              expr, lexer.Location);
3122                         implicit_block.AddStatement (new StatementExpression (assign));
3123                 } else {
3124                         Console.WriteLine ("Not handling Array initializers yet");
3125                 }
3126         }
3127                         
3128         return implicit_block;
3129 }
3130
3131 void CheckConstant (Expression expr)
3132 {
3133         // finishme
3134 }
3135
3136 void CheckBoolean (Expression expr)
3137 {
3138         // finishme
3139 }
3140
3141 void CheckAttributeTarget (string a)
3142 {
3143         switch (a) {
3144
3145         case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
3146                 return;
3147                 
3148         default :
3149                 Location l = lexer.Location;
3150                 Report.Error (658, l, "Invalid attribute target");
3151                 break;
3152         }
3153
3154 }
3155
3156 void CheckUnaryOperator (Operator.OpType op)
3157 {
3158         switch (op) {
3159                 
3160         case Operator.OpType.LogicalNot: 
3161         case Operator.OpType.OnesComplement: 
3162         case Operator.OpType.Increment:
3163         case Operator.OpType.Decrement:
3164         case Operator.OpType.True: 
3165         case Operator.OpType.False: 
3166         case Operator.OpType.Addition: 
3167         case Operator.OpType.Subtraction:
3168                 
3169                 break;
3170                 
3171         default :
3172                 Location l = lexer.Location;
3173                 Report.Error (1019, l, "Overloadable unary operator expected"); 
3174                 break;
3175                 
3176         }
3177 }
3178
3179 void CheckBinaryOperator (Operator.OpType op)
3180 {
3181         switch (op) {
3182                 
3183         case Operator.OpType.Addition: 
3184         case Operator.OpType.Subtraction: 
3185         case Operator.OpType.Multiply:
3186         case Operator.OpType.Division:
3187         case Operator.OpType.Modulus: 
3188         case Operator.OpType.BitwiseAnd: 
3189         case Operator.OpType.BitwiseOr:
3190         case Operator.OpType.ExclusiveOr: 
3191         case Operator.OpType.LeftShift: 
3192         case Operator.OpType.RightShift:
3193         case Operator.OpType.Equality: 
3194         case Operator.OpType.Inequality:
3195         case Operator.OpType.GreaterThan: 
3196         case Operator.OpType.LessThan: 
3197         case Operator.OpType.GreaterThanOrEqual:
3198         case Operator.OpType.LessThanOrEqual:
3199                 break;
3200                 
3201         default :
3202                 Location l = lexer.Location;
3203                 Report.Error (1020, l, "Overloadable binary operator expected");
3204                 break;
3205         }
3206         
3207 }
3208
3209 void output (string s)
3210 {
3211         Console.WriteLine (s);
3212 }
3213
3214 void note (string s)
3215 {
3216         // Used to put annotations
3217 }
3218
3219 Tokenizer lexer;
3220
3221 public Tokenizer Lexer {
3222         get {
3223                 return lexer;
3224         }
3225 }                  
3226
3227 public CSharpParser(RootContext rc, string name, System.IO.Stream input)
3228 {
3229         current_namespace = new Namespace (null, "");
3230         this.rc = rc;
3231         this.tree = rc.Tree;
3232         this.name = name;
3233         this.input = input;
3234         current_container = tree.Types;
3235         current_container.Namespace = current_namespace;
3236
3237         lexer = new Tokenizer (input, name);
3238 }
3239
3240 public override int parse ()
3241 {
3242         StringBuilder value = new StringBuilder ();
3243
3244         global_errors = 0;
3245         try {
3246                 if (yacc_verbose_flag)
3247                         yyparse (lexer, new yydebug.yyDebugSimple ());
3248                 else
3249                         yyparse (lexer);
3250         } catch (Exception e){
3251                 // Console.WriteLine ("Fatal error: " + name);
3252                 // Console.WriteLine (lexer.location);
3253
3254                 Console.WriteLine (lexer.location + "  : Parsing error ");
3255                 Console.WriteLine (e);
3256                 global_errors++;
3257         }
3258         
3259         return global_errors;
3260 }
3261
3262
3263 /* end end end */
3264 }