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