3 // cs-parser.jay: The Parser for the C# compiler
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 // Ravi Pratap (ravi@ximian.com)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001 Ximian, Inc (http://www.ximian.com)
11 // (C) 2004 Novell, Inc
14 // (1) Figure out why error productions dont work. `type-declaration' is a
15 // great spot to put an `error' because you can reproduce it with this input:
18 // Possible optimization:
19 // Run memory profiler with parsing only, and consider dropping
20 // arraylists where not needed. Some pieces can use linked lists.
28 using System.Collections;
33 public class CSharpParser {
34 NamespaceEntry current_namespace;
35 TypeContainer current_container;
36 TypeContainer current_class;
38 IIteratorContainer iterator_container;
41 /// Current block is used to add statements as we find
44 Block current_block, top_current_block;
47 /// This is used by the unary_expression code to resolve
48 /// a name against a parameter.
50 Parameters current_local_parameters;
53 /// Using during property parsing to describe the implicit
54 /// value parameter that is passed to the "set" and "get"accesor
55 /// methods (properties and indexers).
57 Expression implicit_value_parameter_type;
58 Parameters indexer_parameters;
61 /// Used to determine if we are parsing the get/set pair
62 /// of an indexer or a property
67 /// An out-of-band stack.
76 static public int yacc_verbose_flag;
78 // Name of the file we are parsing
87 /// Temporary Xml documentation cache.
88 /// For enum types, we need one more temporary store.
91 string enumTypeComment;
93 /// Current attribute target
94 string current_attr_target;
96 /// assembly and module attribute definition is enabled
97 bool global_attrs_enabled = true;
102 %token NONE /* This token is never returned by our lexer */
103 %token ERROR // This is used not by the parser, but by the tokenizer.
107 *These are the C# keywords
193 /* C# keywords which are not really keywords */
199 /* C# single character operators/punctuation. */
200 %token OPEN_BRACE "{"
201 %token CLOSE_BRACE "}"
202 %token OPEN_BRACKET "["
203 %token CLOSE_BRACKET "]"
204 %token OPEN_PARENS "("
205 %token CLOSE_PARENS ")"
218 %token BITWISE_AND "&"
219 %token BITWISE_OR "|"
226 /* C# multi-character operators. */
229 %token OP_SHIFT_LEFT "<<"
230 %token OP_SHIFT_RIGHT ">>"
237 %token OP_MULT_ASSIGN "*="
238 %token OP_DIV_ASSIGN "/="
239 %token OP_MOD_ASSIGN "%="
240 %token OP_ADD_ASSIGN "+="
241 %token OP_SUB_ASSIGN "-="
242 %token OP_SHIFT_LEFT_ASSIGN "<<="
243 %token OP_SHIFT_RIGHT_ASSIGN ">>="
244 %token OP_AND_ASSIGN "&="
245 %token OP_XOR_ASSIGN "^="
246 %token OP_OR_ASSIGN "|="
250 %token LITERAL_INTEGER "int literal"
251 %token LITERAL_FLOAT "float literal"
252 %token LITERAL_DOUBLE "double literal"
253 %token LITERAL_DECIMAL "decimal literal"
254 %token LITERAL_CHARACTER "character literal"
255 %token LITERAL_STRING "string literal"
258 %token CLOSE_PARENS_CAST
259 %token CLOSE_PARENS_NO_CAST
260 %token CLOSE_PARENS_OPEN_PARENS
261 %token CLOSE_PARENS_MINUS
263 /* Add precedence rules to solve dangling else s/r conflict */
272 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
274 %left STAR DIV PERCENT
275 %right BANG CARRET UMINUS
276 %nonassoc OP_INC OP_DEC
278 %left OPEN_BRACKET OPEN_BRACE
282 %start compilation_unit
286 : outer_declarations opt_EOF
287 | outer_declarations global_attributes opt_EOF
288 | global_attributes opt_EOF
289 | opt_EOF /* allow empty files */
295 Lexer.check_incorrect_doc_comment ();
299 Lexer.check_incorrect_doc_comment ();
305 | outer_declarations outer_declaration
310 | namespace_member_declaration
315 | using_directives using_directive
319 : using_alias_directive
321 if (RootContext.Documentation != null)
322 Lexer.doc_state = XmlCommentState.Allowed;
324 | using_namespace_directive
326 if (RootContext.Documentation != null)
327 Lexer.doc_state = XmlCommentState.Allowed;
331 using_alias_directive
332 : USING IDENTIFIER ASSIGN
333 namespace_or_type_name SEMICOLON
335 MemberName name = (MemberName) $4;
336 current_namespace.UsingAlias ((string) $2, name.GetTypeExpression (lexer.Location), lexer.Location);
339 CheckIdentifierToken (yyToken);
343 using_namespace_directive
344 : USING namespace_name SEMICOLON
346 MemberName ns_name = (MemberName) $2;
347 current_namespace.Using (ns_name.GetTypeExpression (lexer.Location), lexer.Location);
352 // Strictly speaking, namespaces don't have attributes but
353 // we parse global attributes along with namespace declarations and then
356 namespace_declaration
357 : opt_attributes NAMESPACE namespace_or_type_name
360 Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
361 + " Expected class, delegate, enum, interface, or struct");
364 MemberName name = (MemberName) $3;
366 if ((current_namespace.Parent != null) && (name.Left != null)) {
367 Report.Error (134, lexer.Location,
368 "Cannot use qualified namespace names in nested " +
369 "namespace declarations");
372 current_namespace = new NamespaceEntry (
373 current_namespace, file, name.GetName (), lexer.Location);
375 namespace_body opt_semicolon
377 current_namespace = current_namespace.Parent;
392 : namespace_or_type_name
398 if (RootContext.Documentation != null)
399 Lexer.doc_state = XmlCommentState.Allowed;
402 opt_namespace_member_declarations
413 opt_namespace_member_declarations
415 | namespace_member_declarations
418 namespace_member_declarations
419 : namespace_member_declaration
420 | namespace_member_declarations namespace_member_declaration
423 namespace_member_declaration
430 Class c = (Class) $1;
431 mod_flags = c.ModFlags;
433 } else if ($1 is Struct){
434 Struct s = (Struct) $1;
435 mod_flags = s.ModFlags;
440 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
442 1527, lexer.Location,
443 "Namespace elements cant be explicitly " +
444 "declared private or protected in `" + name + "'");
446 current_namespace.DeclarationFound = true;
448 | namespace_declaration {
449 current_namespace.DeclarationFound = true;
452 | field_declaration {
453 Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
455 | method_declaration {
456 Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
463 | interface_declaration
465 | delegate_declaration
467 // Enable this when we have handled all errors, because this acts as a generic fallback
470 // Console.WriteLine ("Token=" + yyToken);
471 // Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
483 CodeGen.Assembly.AddAttributes (((Attributes)$1).Attrs);
491 global_attrs_enabled = false;
496 global_attrs_enabled = false;
505 ArrayList sect = (ArrayList) $1;
507 if (global_attrs_enabled) {
508 if (current_attr_target == "module") {
509 CodeGen.Module.AddAttributes (sect);
511 } else if (current_attr_target == "assembly") {
512 CodeGen.Assembly.AddAttributes (sect);
515 $$ = new Attributes (sect);
518 if (RootContext.Documentation != null) {
519 Lexer.check_incorrect_doc_comment ();
521 XmlCommentState.Allowed;
525 $$ = new Attributes (sect);
527 current_attr_target = null;
529 | attribute_sections attribute_section
531 Attributes attrs = $1 as Attributes;
532 ArrayList sect = (ArrayList) $2;
534 if (global_attrs_enabled) {
535 if (current_attr_target == "module") {
536 CodeGen.Module.AddAttributes (sect);
538 } else if (current_attr_target == "assembly") {
539 CodeGen.Assembly.AddAttributes (sect);
543 attrs = new Attributes (sect);
545 attrs.AddAttributes (sect);
549 attrs = new Attributes (sect);
551 attrs.AddAttributes (sect);
554 current_attr_target = null;
559 : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
563 | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
569 attribute_target_specifier
570 : attribute_target COLON
572 current_attr_target = (string)$1;
580 CheckAttributeTarget ((string) $1);
583 | EVENT { $$ = "event"; }
584 | RETURN { $$ = "return"; }
590 ArrayList attrs = new ArrayList (4);
596 | attribute_list COMMA attribute
598 ArrayList attrs = (ArrayList) $1;
610 opt_attribute_arguments
612 Location loc = (Location) $2;
613 MemberName mname = (MemberName) $1;
614 MemberName left = mname.Left;
615 string identifier = mname.Name;
617 Expression left_expr = left == null ? null : left.GetTypeExpression (loc);
619 if (current_attr_target == "assembly" || current_attr_target == "module")
620 $$ = new GlobalAttribute (current_container, current_attr_target,
621 left_expr, identifier, (ArrayList) $3, loc);
623 $$ = new Attribute (current_attr_target, left_expr, identifier, (ArrayList) $3, loc);
628 : namespace_or_type_name { /* reserved attribute name or identifier: 17.4 */ }
631 opt_attribute_arguments
632 : /* empty */ { $$ = null; }
633 | OPEN_PARENS attribute_arguments CLOSE_PARENS
641 : opt_positional_argument_list
646 ArrayList args = new ArrayList (4);
652 | positional_argument_list COMMA named_argument_list
654 ArrayList args = new ArrayList (4);
660 | named_argument_list
662 ArrayList args = new ArrayList (4);
671 opt_positional_argument_list
672 : /* empty */ { $$ = null; }
673 | positional_argument_list
676 positional_argument_list
679 ArrayList args = new ArrayList (4);
680 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
684 | positional_argument_list COMMA expression
686 ArrayList args = (ArrayList) $1;
687 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
696 ArrayList args = new ArrayList (4);
701 | named_argument_list COMMA named_argument
703 ArrayList args = (ArrayList) $1;
708 | named_argument_list COMMA expression
710 Report.Error (1016, lexer.Location, "Named attribute argument expected");
716 : IDENTIFIER ASSIGN expression
718 $$ = new DictionaryEntry (
720 new Argument ((Expression) $3, Argument.AType.Expression));
726 : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
729 opt_class_member_declarations
731 | class_member_declarations
734 class_member_declarations
735 : class_member_declaration
736 | class_member_declarations
737 class_member_declaration
740 class_member_declaration
741 : constant_declaration // done
742 | field_declaration // done
743 | method_declaration // done
744 | property_declaration // done
745 | event_declaration // done
746 | indexer_declaration // done
747 | operator_declaration // done
748 | constructor_declaration // done
749 | destructor_declaration // done
759 MemberName name = MakeName ((MemberName) $5);
760 bool partial = (bool) $3;
763 ClassPart part = PartialContainer.CreatePart (
764 current_namespace, current_container, name, (int) $2,
765 (Attributes) $1, Kind.Struct, lexer.Location);
767 current_container = part.PartialContainer;
768 current_class = part;
770 current_class = new Struct (
771 current_namespace, current_container, name, (int) $2,
772 (Attributes) $1, lexer.Location);
774 current_container = current_class;
775 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
781 current_class.Bases = (ArrayList) $7;
783 if (RootContext.Documentation != null)
784 current_class.DocComment = Lexer.consume_doc_comment ();
786 current_class.Register ();
790 if (RootContext.Documentation != null)
791 Lexer.doc_state = XmlCommentState.Allowed;
797 current_container = current_container.Parent;
798 current_class = current_container;
800 | opt_attributes opt_modifiers opt_partial STRUCT error {
801 CheckIdentifierToken (yyToken);
808 if (RootContext.Documentation != null)
809 Lexer.doc_state = XmlCommentState.Allowed;
811 opt_struct_member_declarations CLOSE_BRACE
814 opt_struct_member_declarations
816 | struct_member_declarations
819 struct_member_declarations
820 : struct_member_declaration
821 | struct_member_declarations struct_member_declaration
824 struct_member_declaration
825 : constant_declaration
828 | property_declaration
830 | indexer_declaration
831 | operator_declaration
832 | constructor_declaration
836 * This is only included so we can flag error 575:
837 * destructors only allowed on class types
839 | destructor_declaration
850 int modflags = (int) $2;
851 foreach (VariableDeclaration constant in (ArrayList) $5){
852 Location l = constant.Location;
853 if ((modflags & Modifiers.STATIC) != 0) {
854 Report.Error (504, l, "The constant '{0}' cannot be marked static", current_container.GetSignatureForError () + '.' + (string) constant.identifier);
858 Const c = new Const (
859 current_class, (Expression) $4, (string) constant.identifier,
860 (Expression) constant.expression_or_array_initializer, modflags,
863 if (RootContext.Documentation != null) {
864 c.DocComment = Lexer.consume_doc_comment ();
865 Lexer.doc_state = XmlCommentState.Allowed;
867 current_container.AddConstant (c);
873 : constant_declarator
875 ArrayList constants = new ArrayList (4);
880 | constant_declarators COMMA constant_declarator
883 ArrayList constants = (ArrayList) $1;
890 : IDENTIFIER ASSIGN constant_expression
892 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
896 // A const field requires a value to be provided
897 Report.Error (145, lexer.Location, "A const field requires a value to be provided");
909 Expression type = (Expression) $3;
912 foreach (VariableDeclaration var in (ArrayList) $4){
913 Location l = var.Location;
915 Field field = new Field (current_class, type, mod, var.identifier,
916 var.expression_or_array_initializer,
919 if (RootContext.Documentation != null) {
920 field.DocComment = Lexer.consume_doc_comment ();
921 Lexer.doc_state = XmlCommentState.Allowed;
923 current_container.AddField (field);
931 Report.Error (670, lexer.Location, "void type is not allowed for fields");
936 : variable_declarator
938 ArrayList decl = new ArrayList (4);
942 | variable_declarators COMMA variable_declarator
944 ArrayList decls = (ArrayList) $1;
951 : IDENTIFIER ASSIGN variable_initializer
953 $$ = new VariableDeclaration ((string) $1, $3, lexer.Location);
957 $$ = new VariableDeclaration ((string) $1, null, lexer.Location);
970 | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
972 $$ = new StackAlloc ((Expression) $2, (Expression) $4, lexer.Location);
976 Report.Error (1575, lexer.Location, "A stackalloc expression requires [] after type");
983 iterator_container = (IIteratorContainer) $1;
984 if (RootContext.Documentation != null)
985 Lexer.doc_state = XmlCommentState.NotAllowed;
989 Method method = (Method) $1;
990 Block b = (Block) $3;
991 const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
994 if ((method.ModFlags & extern_abstract) == 0){
996 501, lexer.Location, current_container.MakeName (method.Name) +
997 "must declare a body because it is not marked abstract or extern");
1000 if ((method.ModFlags & Modifiers.EXTERN) != 0){
1002 179, lexer.Location, current_container.MakeName (method.Name) +
1003 " is declared extern, but has a body");
1007 method.Block = (ToplevelBlock) $3;
1008 current_container.AddMethod (method);
1010 current_local_parameters = null;
1011 iterator_container = null;
1013 if (RootContext.Documentation != null)
1014 Lexer.doc_state = XmlCommentState.Allowed;
1028 1585, lexer.Location, "Member modifier `" +
1029 Modifiers.Name (i) + "' must precede member type and name");
1040 type namespace_or_type_name
1041 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1043 MemberName name = (MemberName) $4;
1045 Method method = new Method (current_class, (Expression) $3, (int) $2,
1046 false, name, (Parameters) $6, (Attributes) $1,
1049 current_local_parameters = (Parameters) $6;
1051 if (RootContext.Documentation != null)
1052 method.DocComment = Lexer.consume_doc_comment ();
1058 VOID namespace_or_type_name
1059 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1061 MemberName name = (MemberName) $4;
1063 Method method = new Method (current_class, TypeManager.system_void_expr,
1064 (int) $2, false, name, (Parameters) $6,
1065 (Attributes) $1, lexer.Location);
1067 current_local_parameters = (Parameters) $6;
1069 if (RootContext.Documentation != null)
1070 method.DocComment = Lexer.consume_doc_comment ();
1077 modifiers namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1079 Report.Error (1585, lexer.Location,
1080 String.Format ("Modifier {0} should appear before type",
1081 Modifiers.Name ((int) $4)));
1082 MemberName name = (MemberName) $4;
1084 Method method = new Method (current_class, TypeManager.system_void_expr,
1085 0, false, name, (Parameters) $7, (Attributes) $1,
1088 current_local_parameters = (Parameters) $7;
1090 if (RootContext.Documentation != null)
1091 method.DocComment = Lexer.consume_doc_comment ();
1099 | SEMICOLON { $$ = null; }
1102 opt_formal_parameter_list
1103 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
1104 | formal_parameter_list
1107 formal_parameter_list
1110 ArrayList pars_list = (ArrayList) $1;
1112 Parameter [] pars = new Parameter [pars_list.Count];
1113 pars_list.CopyTo (pars);
1115 $$ = new Parameters (pars, null, lexer.Location);
1117 | fixed_parameters COMMA parameter_array
1119 ArrayList pars_list = (ArrayList) $1;
1121 Parameter [] pars = new Parameter [pars_list.Count];
1122 pars_list.CopyTo (pars);
1124 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1126 | fixed_parameters COMMA ARGLIST
1128 ArrayList pars_list = (ArrayList) $1;
1130 Parameter [] pars = new Parameter [pars_list.Count];
1131 pars_list.CopyTo (pars);
1133 $$ = new Parameters (pars, true, lexer.Location);
1135 | parameter_array COMMA fixed_parameters
1137 Report.Error (231, lexer.Location, "A params parameter must be the last parameter in a formal parameter list");
1140 | ARGLIST COMMA fixed_parameters
1142 Report.Error (257, lexer.Location, "An __arglist parameter must be the last parameter in a formal parameter list");
1147 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1151 $$ = new Parameters (null, true, lexer.Location);
1158 ArrayList pars = new ArrayList (4);
1163 | fixed_parameters COMMA fixed_parameter
1165 ArrayList pars = (ArrayList) $1;
1174 opt_parameter_modifier
1178 $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
1181 opt_parameter_modifier
1184 Report.Error (1001, lexer.Location, "Identifier expected");
1188 opt_parameter_modifier
1191 CheckIdentifierToken (yyToken);
1195 opt_parameter_modifier
1201 Report.Error (241, lexer.Location, "Default parameter specifiers are not permitted");
1206 opt_parameter_modifier
1207 : /* empty */ { $$ = Parameter.Modifier.NONE; }
1208 | parameter_modifier
1212 : REF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
1213 | OUT { $$ = Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF; }
1217 : opt_attributes PARAMS type IDENTIFIER
1219 $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
1220 note ("type must be a single-dimension array type");
1222 | opt_attributes PARAMS parameter_modifier type IDENTIFIER
1224 Report.Error (1611, lexer.Location, "The params parameter cannot be declared as ref or out");
1227 | opt_attributes PARAMS type error {
1228 CheckIdentifierToken (yyToken);
1233 property_declaration
1237 namespace_or_type_name
1239 if (RootContext.Documentation != null)
1240 tmpComment = Lexer.consume_doc_comment ();
1244 implicit_value_parameter_type = (Expression) $3;
1246 lexer.PropertyParsing = true;
1248 $$ = lexer.Location;
1250 iterator_container = SimpleIteratorContainer.GetSimple ();
1252 accessor_declarations
1254 lexer.PropertyParsing = false;
1259 Pair pair = (Pair) $8;
1260 Accessor get_block = (Accessor) pair.First;
1261 Accessor set_block = (Accessor) pair.Second;
1263 Location loc = (Location) $7;
1264 MemberName name = (MemberName) $4;
1266 prop = new Property (current_class, (Expression) $3, (int) $2, false,
1267 name, (Attributes) $1, get_block, set_block, loc);
1268 if (SimpleIteratorContainer.Simple.Yields)
1271 current_container.AddProperty (prop);
1272 implicit_value_parameter_type = null;
1273 iterator_container = null;
1275 if (RootContext.Documentation != null)
1276 prop.DocComment = ConsumeStoredComment ();
1281 accessor_declarations
1282 : get_accessor_declaration opt_set_accessor_declaration
1284 $$ = new Pair ($1, $2);
1286 | set_accessor_declaration opt_get_accessor_declaration
1288 $$ = new Pair ($2, $1);
1292 opt_get_accessor_declaration
1293 : /* empty */ { $$ = null; }
1294 | get_accessor_declaration
1297 opt_set_accessor_declaration
1298 : /* empty */ { $$ = null; }
1299 | set_accessor_declaration
1302 get_accessor_declaration
1303 : opt_attributes opt_modifiers GET
1305 // If this is not the case, then current_local_parameters has already
1306 // been set in indexer_declaration
1307 if (parsing_indexer == false)
1308 current_local_parameters = null;
1310 current_local_parameters = indexer_parameters;
1311 lexer.PropertyParsing = false;
1315 $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
1316 current_local_parameters = null;
1317 lexer.PropertyParsing = true;
1319 if (RootContext.Documentation != null)
1320 if (Lexer.doc_state == XmlCommentState.Error)
1321 Lexer.doc_state = XmlCommentState.NotAllowed;
1325 set_accessor_declaration
1326 : opt_attributes opt_modifiers SET
1329 Parameter implicit_value_parameter = new Parameter (
1330 implicit_value_parameter_type, "value",
1331 Parameter.Modifier.NONE, null);
1333 if (parsing_indexer == false) {
1334 args = new Parameter [1];
1335 args [0] = implicit_value_parameter;
1336 current_local_parameters = new Parameters (args, null, lexer.Location);
1338 Parameter [] fpars = indexer_parameters.FixedParameters;
1341 int count = fpars.Length;
1343 args = new Parameter [count + 1];
1344 fpars.CopyTo (args, 0);
1345 args [count] = implicit_value_parameter;
1348 current_local_parameters = new Parameters (
1349 args, indexer_parameters.ArrayParameter, lexer.Location);
1352 lexer.PropertyParsing = false;
1356 $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
1357 current_local_parameters = null;
1358 lexer.PropertyParsing = true;
1360 if (RootContext.Documentation != null
1361 && Lexer.doc_state == XmlCommentState.Error)
1362 Lexer.doc_state = XmlCommentState.NotAllowed;
1368 | SEMICOLON { $$ = null; }
1371 interface_declaration
1375 INTERFACE member_name
1377 MemberName name = MakeName ((MemberName) $5);
1378 bool partial = (bool) $3;
1381 ClassPart part = PartialContainer.CreatePart (
1382 current_namespace, current_container, name, (int) $2,
1383 (Attributes) $1, Kind.Interface, lexer.Location);
1385 current_container = part.PartialContainer;
1386 current_class = part;
1388 current_class = new Interface (
1389 current_namespace, current_container, name, (int) $2,
1390 (Attributes) $1, lexer.Location);
1392 current_container = current_class;
1393 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
1398 current_class.Bases = (ArrayList) $7;
1400 if (RootContext.Documentation != null) {
1401 current_class.DocComment = Lexer.consume_doc_comment ();
1402 Lexer.doc_state = XmlCommentState.Allowed;
1405 current_class.Register ();
1409 if (RootContext.Documentation != null)
1410 Lexer.doc_state = XmlCommentState.Allowed;
1416 current_container = current_container.Parent;
1417 current_class = current_container;
1419 | opt_attributes opt_modifiers opt_partial INTERFACE error {
1420 CheckIdentifierToken (yyToken);
1426 opt_interface_member_declarations
1430 opt_interface_member_declarations
1432 | interface_member_declarations
1435 interface_member_declarations
1436 : interface_member_declaration
1437 | interface_member_declarations interface_member_declaration
1440 interface_member_declaration
1441 : interface_method_declaration
1443 Method m = (Method) $1;
1445 if (m.IsExplicitImpl)
1446 Report.Error (541, lexer.Location,
1447 "Explicit interface declaration can only be declared in a class or struct");
1449 current_container.AddMethod (m);
1451 if (RootContext.Documentation != null)
1452 Lexer.doc_state = XmlCommentState.Allowed;
1454 | interface_property_declaration
1456 Property p = (Property) $1;
1458 if (p.IsExplicitImpl)
1459 Report.Error (541, lexer.Location,
1460 "Explicit interface declaration can only be declared in a class or struct");
1462 current_container.AddProperty (p);
1464 if (RootContext.Documentation != null)
1465 Lexer.doc_state = XmlCommentState.Allowed;
1467 | interface_event_declaration
1470 Event e = (Event) $1;
1472 if (e.IsExplicitImpl)
1473 Report.Error (541, lexer.Location,
1474 "Explicit interface declaration can only be declared in a class or struct");
1476 current_container.AddEvent (e);
1479 if (RootContext.Documentation != null)
1480 Lexer.doc_state = XmlCommentState.Allowed;
1482 | interface_indexer_declaration
1484 Indexer i = (Indexer) $1;
1486 if (i.IsExplicitImpl)
1487 Report.Error (541, lexer.Location,
1488 "Explicit interface declaration can only be declared in a class or struct");
1490 current_container.AddIndexer (i);
1492 if (RootContext.Documentation != null)
1493 Lexer.doc_state = XmlCommentState.Allowed;
1495 | delegate_declaration
1497 Report.Error (524, lexer.Location, "Interfaces can not declare delegates");
1501 Report.Error (524, lexer.Location, "Interfaces can not declare classes");
1503 | struct_declaration
1505 Report.Error (524, lexer.Location, "Interfaces can not declare structures");
1509 Report.Error (524, lexer.Location, "Interfaces can not declare enumerations");
1511 | interface_declaration
1513 Report.Error (524, lexer.Location, "Interfaces can not declare interfaces");
1521 val = Modifiers.Check (Modifiers.NEW | Modifiers.UNSAFE, val, 0, lexer.Location);
1526 interface_method_declaration
1527 : opt_attributes opt_new type namespace_or_type_name
1528 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1531 MemberName name = (MemberName) $4;
1533 $$ = new Method (current_class, (Expression) $3, (int) $2, true,
1534 name, (Parameters) $6, (Attributes) $1, lexer.Location);
1535 if (RootContext.Documentation != null)
1536 ((Method) $$).DocComment = Lexer.consume_doc_comment ();
1538 | opt_attributes opt_new VOID namespace_or_type_name
1539 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1542 MemberName name = (MemberName) $4;
1544 $$ = new Method (current_class, TypeManager.system_void_expr, (int) $2,
1545 true, name, (Parameters) $6, (Attributes) $1, lexer.Location);
1546 if (RootContext.Documentation != null)
1547 ((Method) $$).DocComment = Lexer.consume_doc_comment ();
1551 interface_property_declaration
1556 { lexer.PropertyParsing = true; }
1558 { lexer.PropertyParsing = false; }
1561 InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
1563 $$ = new Property (current_class, (Expression) $3, (int) $2, true,
1564 new MemberName ((string) $4), (Attributes) $1,
1565 pinfo.Get, pinfo.Set, lexer.Location);
1566 if (RootContext.Documentation != null)
1567 ((Property) $$).DocComment = Lexer.consume_doc_comment ();
1572 CheckIdentifierToken (yyToken);
1578 : opt_attributes opt_modifiers GET SEMICOLON
1579 { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, lexer.Location, lexer.Location); }
1580 | opt_attributes opt_modifiers SET SEMICOLON
1581 { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, 0, (int) $2, lexer.Location, lexer.Location); }
1582 | opt_attributes opt_modifiers GET SEMICOLON opt_attributes opt_modifiers SET SEMICOLON
1583 { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $5, (int) $2, (int) $6, lexer.Location, lexer.Location); }
1584 | opt_attributes opt_modifiers SET SEMICOLON opt_attributes opt_modifiers GET SEMICOLON
1585 { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $5, (Attributes) $1, (int) $6, (int) $2, lexer.Location, lexer.Location); }
1588 interface_event_declaration
1589 : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
1591 $$ = new EventField (current_class, (Expression) $4, (int) $2, true,
1592 new MemberName ((string) $5), null,
1593 (Attributes) $1, lexer.Location);
1594 if (RootContext.Documentation != null)
1595 ((EventField) $$).DocComment = Lexer.consume_doc_comment ();
1597 | opt_attributes opt_new EVENT type error {
1598 CheckIdentifierToken (yyToken);
1601 | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN {
1602 Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized.");
1605 | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE {
1606 Report.Error (69, lexer.Location, "Event accessors not valid on interfaces");
1611 interface_indexer_declaration
1612 : opt_attributes opt_new type THIS
1613 OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
1615 { lexer.PropertyParsing = true; }
1617 { lexer.PropertyParsing = false; }
1620 InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
1622 $$ = new Indexer (current_class, (Expression) $3,
1623 new MemberName (TypeContainer.DefaultIndexerName),
1624 (int) $2, true, (Parameters) $6, (Attributes) $1,
1625 info.Get, info.Set, lexer.Location);
1626 if (RootContext.Documentation != null)
1627 ((Indexer) $$).DocComment = ConsumeStoredComment ();
1631 operator_declaration
1632 : opt_attributes opt_modifiers operator_declarator
1634 iterator_container = SimpleIteratorContainer.GetSimple ();
1638 OperatorDeclaration decl = (OperatorDeclaration) $3;
1640 Parameter [] param_list = new Parameter [decl.arg2type != null ? 2 : 1];
1642 param_list[0] = new Parameter (decl.arg1type, decl.arg1name, Parameter.Modifier.NONE, null);
1643 if (decl.arg2type != null)
1644 param_list[1] = new Parameter (decl.arg2type, decl.arg2name, Parameter.Modifier.NONE, null);
1646 Operator op = new Operator (
1647 current_class, decl.optype, decl.ret_type, (int) $2,
1648 new Parameters (param_list, null, decl.location),
1649 (ToplevelBlock) $5, (Attributes) $1, decl.location);
1651 if (RootContext.Documentation != null) {
1652 op.DocComment = tmpComment;
1653 Lexer.doc_state = XmlCommentState.Allowed;
1656 if (SimpleIteratorContainer.Simple.Yields)
1659 // Note again, checking is done in semantic analysis
1660 current_container.AddOperator (op);
1662 current_local_parameters = null;
1663 iterator_container = null;
1669 | SEMICOLON { $$ = null; }
1672 : type OPERATOR overloadable_operator
1673 OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1675 Operator.OpType op = (Operator.OpType) $3;
1676 CheckUnaryOperator (op);
1678 if (op == Operator.OpType.Addition)
1679 op = Operator.OpType.UnaryPlus;
1681 if (op == Operator.OpType.Subtraction)
1682 op = Operator.OpType.UnaryNegation;
1684 Parameter [] pars = new Parameter [1];
1685 Expression type = (Expression) $5;
1687 pars [0] = new Parameter (type, (string) $6, Parameter.Modifier.NONE, null);
1689 current_local_parameters = new Parameters (pars, null, lexer.Location);
1691 if (RootContext.Documentation != null) {
1692 tmpComment = Lexer.consume_doc_comment ();
1693 Lexer.doc_state = XmlCommentState.NotAllowed;
1696 $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6,
1697 null, null, lexer.Location);
1699 | type OPERATOR overloadable_operator
1701 type IDENTIFIER COMMA
1705 CheckBinaryOperator ((Operator.OpType) $3);
1707 Parameter [] pars = new Parameter [2];
1709 Expression typeL = (Expression) $5;
1710 Expression typeR = (Expression) $8;
1712 pars [0] = new Parameter (typeL, (string) $6, Parameter.Modifier.NONE, null);
1713 pars [1] = new Parameter (typeR, (string) $9, Parameter.Modifier.NONE, null);
1715 current_local_parameters = new Parameters (pars, null, lexer.Location);
1717 if (RootContext.Documentation != null) {
1718 tmpComment = Lexer.consume_doc_comment ();
1719 Lexer.doc_state = XmlCommentState.NotAllowed;
1722 $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1,
1724 typeR, (string) $9, lexer.Location);
1726 | conversion_operator_declarator
1729 overloadable_operator
1731 : BANG { $$ = Operator.OpType.LogicalNot; }
1732 | TILDE { $$ = Operator.OpType.OnesComplement; }
1733 | OP_INC { $$ = Operator.OpType.Increment; }
1734 | OP_DEC { $$ = Operator.OpType.Decrement; }
1735 | TRUE { $$ = Operator.OpType.True; }
1736 | FALSE { $$ = Operator.OpType.False; }
1737 // Unary and binary:
1738 | PLUS { $$ = Operator.OpType.Addition; }
1739 | MINUS { $$ = Operator.OpType.Subtraction; }
1741 | STAR { $$ = Operator.OpType.Multiply; }
1742 | DIV { $$ = Operator.OpType.Division; }
1743 | PERCENT { $$ = Operator.OpType.Modulus; }
1744 | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
1745 | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
1746 | CARRET { $$ = Operator.OpType.ExclusiveOr; }
1747 | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
1748 | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
1749 | OP_EQ { $$ = Operator.OpType.Equality; }
1750 | OP_NE { $$ = Operator.OpType.Inequality; }
1751 | OP_GT { $$ = Operator.OpType.GreaterThan; }
1752 | OP_LT { $$ = Operator.OpType.LessThan; }
1753 | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
1754 | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
1757 conversion_operator_declarator
1758 : IMPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1760 Parameter [] pars = new Parameter [1];
1762 pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1764 current_local_parameters = new Parameters (pars, null, lexer.Location);
1766 if (RootContext.Documentation != null) {
1767 tmpComment = Lexer.consume_doc_comment ();
1768 Lexer.doc_state = XmlCommentState.NotAllowed;
1771 $$ = new OperatorDeclaration (Operator.OpType.Implicit, (Expression) $3, (Expression) $5, (string) $6,
1772 null, null, lexer.Location);
1774 | EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS
1776 Parameter [] pars = new Parameter [1];
1778 pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
1780 current_local_parameters = new Parameters (pars, null, lexer.Location);
1782 if (RootContext.Documentation != null) {
1783 tmpComment = Lexer.consume_doc_comment ();
1784 Lexer.doc_state = XmlCommentState.NotAllowed;
1787 $$ = new OperatorDeclaration (Operator.OpType.Explicit, (Expression) $3, (Expression) $5, (string) $6,
1788 null, null, lexer.Location);
1792 syntax_error (lexer.Location, "'operator' expected");
1796 syntax_error (lexer.Location, "'operator' expected");
1800 constructor_declaration
1803 constructor_declarator
1806 Constructor c = (Constructor) $3;
1807 c.Block = (ToplevelBlock) $4;
1808 c.OptAttributes = (Attributes) $1;
1809 c.ModFlags = (int) $2;
1811 if (RootContext.Documentation != null)
1812 c.DocComment = ConsumeStoredComment ();
1814 if (c.Name == current_container.Basename){
1815 if ((c.ModFlags & Modifiers.STATIC) != 0){
1816 if ((c.ModFlags & Modifiers.Accessibility) != 0){
1818 515, c.Location, String.Format (
1819 "`{0}.{1}': static constructor can not have access modifiers",
1820 c.Name, current_container.Name));
1823 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
1825 if (c.Initializer != null){
1828 "Static constructors can not have an explicit this or base " +
1829 "constructor invocations");
1832 if (!c.Parameters.Empty){
1834 132, c.Location, "Static constructors should not have parameters");
1837 c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
1840 // We let another layer check the validity of the constructor.
1841 //Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
1844 current_container.AddConstructor (c);
1846 current_local_parameters = null;
1847 if (RootContext.Documentation != null)
1848 Lexer.doc_state = XmlCommentState.Allowed;
1852 constructor_declarator
1855 if (RootContext.Documentation != null) {
1856 tmpComment = Lexer.consume_doc_comment ();
1857 Lexer.doc_state = XmlCommentState.Allowed;
1860 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS _mark_
1862 current_local_parameters = (Parameters) $4;
1864 opt_constructor_initializer
1866 $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $4,
1867 (ConstructorInitializer) $8, (Location) $6);
1873 | SEMICOLON { $$ = null; }
1876 opt_constructor_initializer
1877 : /* empty */ { $$ = null; }
1878 | constructor_initializer
1881 constructor_initializer
1882 : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS
1884 $$ = new ConstructorBaseInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
1886 | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS
1888 $$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
1891 Report.Error (1018, lexer.Location, "Keyword this or base expected");
1897 : /* EMPTY */ { $$ = 0; }
1898 | UNSAFE { $$ = Modifiers.UNSAFE; }
1899 | EXTERN { $$ = Modifiers.EXTERN; }
1902 destructor_declaration
1903 : opt_attributes opt_finalizer TILDE
1905 if (RootContext.Documentation != null) {
1906 tmpComment = Lexer.consume_doc_comment ();
1907 Lexer.doc_state = XmlCommentState.NotAllowed;
1910 IDENTIFIER OPEN_PARENS CLOSE_PARENS block
1912 if ((string) $5 != current_container.Basename){
1913 Report.Error (574, lexer.Location, "Name of destructor must match name of class");
1914 } else if (current_container.Kind != Kind.Class){
1915 Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
1917 Location l = lexer.Location;
1920 if (!RootContext.StdLib && current_container.Name == "System.Object")
1921 m |= Modifiers.PROTECTED | Modifiers.VIRTUAL;
1923 m |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
1925 if ((m & Modifiers.UNSAFE) != 0){
1926 if (!RootContext.Unsafe){
1927 Report.Error (227, l,
1928 "Unsafe code requires the -unsafe command " +
1929 "line option to be specified");
1933 Method d = new Destructor (
1934 current_class, TypeManager.system_void_expr, m, "Finalize",
1935 new Parameters (null, null, l), (Attributes) $1, l);
1936 if (RootContext.Documentation != null)
1937 d.DocComment = ConsumeStoredComment ();
1939 d.Block = (ToplevelBlock) $8;
1940 current_container.AddMethod (d);
1948 EVENT type variable_declarators SEMICOLON
1950 foreach (VariableDeclaration var in (ArrayList) $5) {
1952 MemberName name = new MemberName (var.identifier);
1954 Event e = new EventField (
1955 current_class, (Expression) $4, (int) $2, false, name,
1956 var.expression_or_array_initializer, (Attributes) $1,
1959 current_container.AddEvent (e);
1961 if (RootContext.Documentation != null) {
1962 e.DocComment = Lexer.consume_doc_comment ();
1963 Lexer.doc_state = XmlCommentState.Allowed;
1969 EVENT type namespace_or_type_name
1972 implicit_value_parameter_type = (Expression) $4;
1973 lexer.EventParsing = true;
1975 event_accessor_declarations
1977 lexer.EventParsing = false;
1981 Location loc = (Location) $7;
1984 Report.Error (65, lexer.Location, "Event must have both add and remove accesors");
1987 Pair pair = (Pair) $9;
1989 MemberName name = (MemberName) $5;
1991 Event e = new EventProperty (
1992 current_class, (Expression) $4, (int) $2, false, name, null,
1993 (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second,
1995 if (RootContext.Documentation != null) {
1996 e.DocComment = Lexer.consume_doc_comment ();
1997 Lexer.doc_state = XmlCommentState.Allowed;
2000 current_container.AddEvent (e);
2001 implicit_value_parameter_type = null;
2004 | opt_attributes opt_modifiers EVENT type namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS block {
2005 MemberName mn = (MemberName) $5;
2007 if (mn.Left != null)
2008 Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax");
2010 Report.Error (71, lexer.Location, "Event declaration should use property syntax");
2012 if (RootContext.Documentation != null)
2013 Lexer.doc_state = XmlCommentState.Allowed;
2017 event_accessor_declarations
2018 : add_accessor_declaration remove_accessor_declaration
2020 $$ = new Pair ($1, $2);
2022 | remove_accessor_declaration add_accessor_declaration
2024 $$ = new Pair ($2, $1);
2026 | add_accessor_declaration { $$ = null; }
2027 | remove_accessor_declaration { $$ = null; }
2030 Report.Error (1055, lexer.Location, "An add or remove accessor expected");
2036 add_accessor_declaration
2037 : opt_attributes ADD
2039 Parameter [] args = new Parameter [1];
2040 Parameter implicit_value_parameter = new Parameter (
2041 implicit_value_parameter_type, "value",
2042 Parameter.Modifier.NONE, null);
2044 args [0] = implicit_value_parameter;
2046 current_local_parameters = new Parameters (args, null, lexer.Location);
2047 lexer.EventParsing = false;
2051 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
2052 lexer.EventParsing = true;
2054 | opt_attributes ADD error {
2055 Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
2060 remove_accessor_declaration
2061 : opt_attributes REMOVE
2063 Parameter [] args = new Parameter [1];
2064 Parameter implicit_value_parameter = new Parameter (
2065 implicit_value_parameter_type, "value",
2066 Parameter.Modifier.NONE, null);
2068 args [0] = implicit_value_parameter;
2070 current_local_parameters = new Parameters (args, null, lexer.Location);
2071 lexer.EventParsing = false;
2075 $$ = new Accessor ((ToplevelBlock) $4, 0, (Attributes) $1, lexer.Location);
2076 lexer.EventParsing = true;
2078 | opt_attributes REMOVE error {
2079 Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
2085 : opt_attributes opt_modifiers indexer_declarator
2088 IndexerDeclaration decl = (IndexerDeclaration) $3;
2090 implicit_value_parameter_type = decl.type;
2092 lexer.PropertyParsing = true;
2093 parsing_indexer = true;
2095 indexer_parameters = decl.param_list;
2097 accessor_declarations
2099 lexer.PropertyParsing = false;
2100 parsing_indexer = false;
2104 // The signature is computed from the signature of the indexer. Look
2105 // at section 3.6 on the spec
2106 Location loc = (Location) $5;
2108 IndexerDeclaration decl = (IndexerDeclaration) $3;
2109 Pair pair = (Pair) $7;
2110 Accessor get_block = (Accessor) pair.First;
2111 Accessor set_block = (Accessor) pair.Second;
2114 if (decl.interface_type != null)
2115 name = new MemberName (decl.interface_type,
2116 TypeContainer.DefaultIndexerName);
2118 name = new MemberName (TypeContainer.DefaultIndexerName);
2120 indexer = new Indexer (current_class, decl.type, name,
2121 (int) $2, false, decl.param_list, (Attributes) $1,
2122 get_block, set_block, loc);
2123 if (RootContext.Documentation != null)
2124 indexer.DocComment = ConsumeStoredComment ();
2126 current_container.AddIndexer (indexer);
2128 current_local_parameters = null;
2129 implicit_value_parameter_type = null;
2130 indexer_parameters = null;
2135 : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2137 Parameters pars = (Parameters) $4;
2138 if (pars.HasArglist) {
2139 // "__arglist is not valid in this context"
2140 Report.Error (1669, lexer.Location, "__arglist is not valid in this context");
2141 } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
2142 Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
2144 if (RootContext.Documentation != null) {
2145 tmpComment = Lexer.consume_doc_comment ();
2146 Lexer.doc_state = XmlCommentState.Allowed;
2149 $$ = new IndexerDeclaration ((Expression) $1, null, pars);
2151 | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
2153 Parameters pars = (Parameters) $6;
2155 if (pars.HasArglist) {
2156 // "__arglist is not valid in this context"
2157 Report.Error (1669, lexer.Location, "__arglist is not valid in this context");
2158 } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
2159 Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
2162 MemberName name = (MemberName) $2;
2163 $$ = new IndexerDeclaration ((Expression) $1, name, pars);
2165 if (RootContext.Documentation != null) {
2166 tmpComment = Lexer.consume_doc_comment ();
2167 Lexer.doc_state = XmlCommentState.Allowed;
2177 if (RootContext.Documentation != null)
2178 enumTypeComment = Lexer.consume_doc_comment ();
2183 Location enum_location = lexer.Location;
2185 MemberName full_name = MakeName (new MemberName ((string) $4));
2186 Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
2187 full_name, (Attributes) $1, enum_location);
2189 if (RootContext.Documentation != null)
2190 e.DocComment = enumTypeComment;
2192 foreach (VariableDeclaration ev in (ArrayList) $7) {
2193 e.AddEnumMember (ev.identifier,
2194 (Expression) ev.expression_or_array_initializer,
2195 ev.Location, ev.OptAttributes,
2199 string name = full_name.GetName ();
2200 current_container.AddEnum (e);
2201 RootContext.Tree.RecordDecl (name, e);
2207 : /* empty */ { $$ = TypeManager.system_int32_expr; }
2208 | COLON type { $$ = $2; }
2214 if (RootContext.Documentation != null)
2215 Lexer.doc_state = XmlCommentState.Allowed;
2217 opt_enum_member_declarations
2219 // here will be evaluated after CLOSE_BLACE is consumed.
2220 if (RootContext.Documentation != null)
2221 Lexer.doc_state = XmlCommentState.Allowed;
2229 opt_enum_member_declarations
2230 : /* empty */ { $$ = new ArrayList (4); }
2231 | enum_member_declarations opt_comma { $$ = $1; }
2234 enum_member_declarations
2235 : enum_member_declaration
2237 ArrayList l = new ArrayList (4);
2242 | enum_member_declarations COMMA enum_member_declaration
2244 ArrayList l = (ArrayList) $1;
2252 enum_member_declaration
2253 : opt_attributes IDENTIFIER
2255 VariableDeclaration vd = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
2257 if (RootContext.Documentation != null) {
2258 vd.DocComment = Lexer.consume_doc_comment ();
2259 Lexer.doc_state = XmlCommentState.Allowed;
2264 | opt_attributes IDENTIFIER
2266 $$ = lexer.Location;
2267 if (RootContext.Documentation != null) {
2268 tmpComment = Lexer.consume_doc_comment ();
2269 Lexer.doc_state = XmlCommentState.NotAllowed;
2274 VariableDeclaration vd = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
2276 if (RootContext.Documentation != null)
2277 vd.DocComment = ConsumeStoredComment ();
2283 delegate_declaration
2286 DELEGATE type member_name
2287 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2290 Location l = lexer.Location;
2291 MemberName name = MakeName ((MemberName) $5);
2292 Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
2293 (int) $2, name, (Parameters) $7, (Attributes) $1, l);
2295 if (RootContext.Documentation != null) {
2296 del.DocComment = Lexer.consume_doc_comment ();
2297 Lexer.doc_state = XmlCommentState.Allowed;
2300 current_container.AddDelegate (del);
2301 RootContext.Tree.RecordDecl (name.GetName (true), del);
2305 DELEGATE VOID member_name
2306 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
2309 Location l = lexer.Location;
2310 MemberName name = MakeName ((MemberName) $5);
2311 Delegate del = new Delegate (
2312 current_namespace, current_container,
2313 TypeManager.system_void_expr, (int) $2, name,
2314 (Parameters) $7, (Attributes) $1, l);
2316 if (RootContext.Documentation != null) {
2317 del.DocComment = Lexer.consume_doc_comment ();
2318 Lexer.doc_state = XmlCommentState.Allowed;
2321 current_container.AddDelegate (del);
2322 RootContext.Tree.RecordDecl (name.GetName (true), del);
2326 namespace_or_type_name
2328 | namespace_or_type_name DOT IDENTIFIER {
2329 $$ = new MemberName ((MemberName) $1, (string) $3);
2335 $$ = new MemberName ((string) $1);
2340 * Before you think of adding a return_type, notice that we have been
2341 * using two rules in the places where it matters (one rule using type
2342 * and another identical one that uses VOID as the return type). This
2343 * gets rid of a shift/reduce couple
2346 : namespace_or_type_name
2348 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
2360 // Note that here only unmanaged types are allowed but we
2361 // can't perform checks during this phase - we do it during
2362 // semantic analysis.
2364 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2368 $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);
2374 | non_expression_type rank_specifier
2376 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2378 | non_expression_type STAR
2380 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2382 | expression rank_specifiers
2384 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2388 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2392 // We need this because the parser will happily go and reduce IDENTIFIER STAR
2393 // through this different path
2395 | multiplicative_expression STAR
2397 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
2404 ArrayList types = new ArrayList (4);
2409 | type_list COMMA type
2411 ArrayList types = (ArrayList) $1;
2419 * replaces all the productions for isolating the various
2420 * simple types, but we need this to reuse it easily in local_variable_type
2423 : OBJECT { $$ = TypeManager.system_object_expr; }
2424 | STRING { $$ = TypeManager.system_string_expr; }
2425 | BOOL { $$ = TypeManager.system_boolean_expr; }
2426 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
2427 | FLOAT { $$ = TypeManager.system_single_expr; }
2428 | DOUBLE { $$ = TypeManager.system_double_expr; }
2433 : SBYTE { $$ = TypeManager.system_sbyte_expr; }
2434 | BYTE { $$ = TypeManager.system_byte_expr; }
2435 | SHORT { $$ = TypeManager.system_int16_expr; }
2436 | USHORT { $$ = TypeManager.system_uint16_expr; }
2437 | INT { $$ = TypeManager.system_int32_expr; }
2438 | UINT { $$ = TypeManager.system_uint32_expr; }
2439 | LONG { $$ = TypeManager.system_int64_expr; }
2440 | ULONG { $$ = TypeManager.system_uint64_expr; }
2441 | CHAR { $$ = TypeManager.system_char_expr; }
2442 | VOID { $$ = TypeManager.system_void_expr; }
2446 : type rank_specifiers
2448 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
2453 // Expressions, section 7.5
2463 $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
2465 | parenthesized_expression
2467 | invocation_expression
2471 | post_increment_expression
2472 | post_decrement_expression
2476 | checked_expression
2477 | unchecked_expression
2478 | pointer_member_access
2479 | anonymous_method_expression
2486 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
2487 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
2488 | NULL { $$ = NullLiteral.Null; }
2492 : LITERAL_FLOAT { $$ = new FloatLiteral ((float) lexer.Value); }
2493 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
2494 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
2499 object v = lexer.Value;
2505 $$ = IntLiteral.Zero;
2507 $$ = IntLiteral.One;
2509 $$ = new IntLiteral (i);
2510 } else if (v is uint)
2511 $$ = new UIntLiteral ((UInt32) v);
2513 $$ = new LongLiteral ((Int64) v);
2514 else if (v is ulong)
2515 $$ = new ULongLiteral ((UInt64) v);
2517 Console.WriteLine ("OOPS. Unexpected result from scanner");
2522 : TRUE { $$ = new BoolLiteral (true); }
2523 | FALSE { $$ = new BoolLiteral (false); }
2526 parenthesized_expression_0
2527 : OPEN_PARENS expression CLOSE_PARENS
2530 lexer.Deambiguate_CloseParens ();
2531 // After this, the next token returned is one of
2532 // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
2533 // or CLOSE_PARENS_MINUS.
2537 parenthesized_expression
2538 : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
2542 | parenthesized_expression_0 CLOSE_PARENS_MINUS
2544 // If a parenthesized expression is followed by a minus, we need to wrap
2545 // the expression inside a ParenthesizedExpression for the CS0075 check
2546 // in Binary.DoResolve().
2547 $$ = new ParenthesizedExpression ((Expression) $1, lexer.Location);
2552 : primary_expression DOT IDENTIFIER
2554 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2556 | predefined_type DOT IDENTIFIER
2558 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
2566 invocation_expression
2567 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
2570 Location l = lexer.Location;
2571 Report.Error (1, l, "Parse error");
2573 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
2575 | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
2577 $$ = new Invocation ((Expression) $1, new ArrayList (), lexer.Location);
2579 | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
2581 $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location);
2583 | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS
2585 ArrayList args = new ArrayList (1);
2587 $$ = new Invocation ((Expression) $1, args, lexer.Location);
2589 | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS
2591 ArrayList args = ((ArrayList) $4);
2593 $$ = new Invocation ((Expression) $1, args, lexer.Location);
2598 : /* empty */ { $$ = null; }
2605 ArrayList list = new ArrayList (4);
2609 | argument_list COMMA argument
2611 ArrayList list = (ArrayList) $1;
2615 | argument_list error {
2616 CheckToken (1026, yyToken, ", or ) expected");
2623 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
2625 | non_simple_argument
2632 : REF variable_reference
2634 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
2636 | OUT variable_reference
2638 $$ = new Argument ((Expression) $2, Argument.AType.Out);
2640 | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
2642 ArrayList list = (ArrayList) $3;
2643 Argument[] args = new Argument [list.Count];
2644 list.CopyTo (args, 0);
2646 Expression expr = new Arglist (args, lexer.Location);
2647 $$ = new Argument (expr, Argument.AType.Expression);
2651 $$ = new Argument (new ArglistAccess (lexer.Location), Argument.AType.ArgList);
2656 : expression { note ("section 5.4"); $$ = $1; }
2660 : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET
2662 $$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
2664 | primary_expression rank_specifiers
2666 // So the super-trick is that primary_expression
2667 // can only be either a SimpleName or a MemberAccess.
2668 // The MemberAccess case arises when you have a fully qualified type-name like :
2670 // SimpleName is when you have
2673 Expression expr = (Expression) $1;
2674 if (expr is ComposedCast){
2675 $$ = new ComposedCast (expr, (string) $2, lexer.Location);
2676 } else if (!(expr is SimpleName || expr is MemberAccess)){
2677 Error_ExpectingTypeName (lexer.Location, expr);
2678 $$ = TypeManager.system_object_expr;
2681 // So we extract the string corresponding to the SimpleName
2684 $$ = new ComposedCast (expr, (string) $2, lexer.Location);
2692 ArrayList list = new ArrayList (4);
2696 | expression_list COMMA expression
2698 ArrayList list = (ArrayList) $1;
2707 $$ = new This (current_block, lexer.Location);
2712 : BASE DOT IDENTIFIER
2714 $$ = new BaseAccess ((string) $3, lexer.Location);
2716 | BASE OPEN_BRACKET expression_list CLOSE_BRACKET
2718 $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
2721 Report.Error (175, lexer.Location, "Use of keyword `base' is not valid in this context");
2726 post_increment_expression
2727 : primary_expression OP_INC
2729 $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement,
2730 (Expression) $1, lexer.Location);
2734 post_decrement_expression
2735 : primary_expression OP_DEC
2737 $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement,
2738 (Expression) $1, lexer.Location);
2743 : object_or_delegate_creation_expression
2744 | array_creation_expression
2747 object_or_delegate_creation_expression
2748 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2750 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2754 array_creation_expression
2755 : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET
2757 opt_array_initializer
2759 $$ = new ArrayCreation ((Expression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, lexer.Location);
2761 | NEW type rank_specifiers array_initializer
2763 $$ = new ArrayCreation ((Expression) $2, (string) $3, (ArrayList) $4, lexer.Location);
2767 Report.Error (1031, lexer.Location, "Type expected");
2772 Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
2788 : rank_specifier opt_rank_specifier
2790 $$ = (string) $2 + (string) $1;
2795 : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET
2797 $$ = "[" + (string) $2 + "]";
2817 | dim_separators COMMA
2819 $$ = (string) $1 + ",";
2823 opt_array_initializer
2835 : OPEN_BRACE CLOSE_BRACE
2837 ArrayList list = new ArrayList (4);
2840 | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
2842 $$ = (ArrayList) $2;
2846 variable_initializer_list
2847 : variable_initializer
2849 ArrayList list = new ArrayList (4);
2853 | variable_initializer_list COMMA variable_initializer
2855 ArrayList list = (ArrayList) $1;
2862 : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
2864 $$ = new TypeOfVoid (lexer.Location);
2866 | TYPEOF OPEN_PARENS type CLOSE_PARENS
2868 $$ = new TypeOf ((Expression) $3, lexer.Location);
2873 : SIZEOF OPEN_PARENS type CLOSE_PARENS {
2874 $$ = new SizeOf ((Expression) $3, lexer.Location);
2879 : CHECKED OPEN_PARENS expression CLOSE_PARENS
2881 $$ = new CheckedExpr ((Expression) $3, lexer.Location);
2885 unchecked_expression
2886 : UNCHECKED OPEN_PARENS expression CLOSE_PARENS
2888 $$ = new UnCheckedExpr ((Expression) $3, lexer.Location);
2892 pointer_member_access
2893 : primary_expression OP_PTR IDENTIFIER
2897 deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lexer.Location);
2898 $$ = new MemberAccess (deref, (string) $3, lexer.Location);
2902 anonymous_method_expression
2903 : DELEGATE opt_anonymous_method_signature _mark_
2905 oob_stack.Push (current_local_parameters);
2906 current_local_parameters = (Parameters)$2;
2908 // Force the next block to be created as a ToplevelBlock
2909 oob_stack.Push (current_block);
2910 oob_stack.Push (top_current_block);
2911 current_block = null;
2915 Location loc = (Location) $3;
2916 top_current_block = (Block) oob_stack.Pop ();
2917 current_block = (Block) oob_stack.Pop ();
2918 if (RootContext.Version == LanguageVersion.ISO_1){
2919 Report.FeatureIsNotStandardized (lexer.Location, "anonymous methods");
2922 ToplevelBlock anon_block = (ToplevelBlock) $5;
2924 anon_block.Parent = current_block;
2925 $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block,
2928 current_local_parameters = (Parameters) oob_stack.Pop ();
2932 opt_anonymous_method_signature
2933 : /* empty */ { $$ = null; }
2934 | anonymous_method_signature
2937 anonymous_method_signature
2938 : OPEN_PARENS opt_anonymous_method_parameter_list CLOSE_PARENS
2941 $$ = Parameters.EmptyReadOnlyParameters;
2943 ArrayList par_list = (ArrayList) $2;
2944 Parameter [] pars = new Parameter [par_list.Count];
2945 par_list.CopyTo (pars);
2946 $$ = new Parameters (pars, null, lexer.Location);
2951 opt_anonymous_method_parameter_list
2952 : /* empty */ { $$ = null; }
2953 | anonymous_method_parameter_list { $$ = $1; }
2956 anonymous_method_parameter_list
2957 : anonymous_method_parameter
2959 ArrayList a = new ArrayList (4);
2963 | anonymous_method_parameter_list COMMA anonymous_method_parameter
2965 ArrayList a = (ArrayList) $1;
2971 anonymous_method_parameter
2972 : opt_parameter_modifier type IDENTIFIER {
2973 $$ = new Parameter ((Expression) $2, (string) $3, (Parameter.Modifier) $1, null);
2975 | PARAMS type IDENTIFIER {
2976 Report.Error (-221, lexer.Location, "params modifier not allowed in anonymous method declaration");
2982 : primary_expression
2983 | BANG prefixed_unary_expression
2985 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
2987 | TILDE prefixed_unary_expression
2989 $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, lexer.Location);
2995 : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
2997 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
2999 | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
3001 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3007 | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
3009 $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
3014 // The idea to split this out is from Rhys' grammar
3015 // to solve the problem with casts.
3017 prefixed_unary_expression
3019 | PLUS prefixed_unary_expression
3021 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3023 | MINUS prefixed_unary_expression
3025 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3027 | OP_INC prefixed_unary_expression
3029 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3030 (Expression) $2, lexer.Location);
3032 | OP_DEC prefixed_unary_expression
3034 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3035 (Expression) $2, lexer.Location);
3037 | STAR prefixed_unary_expression
3039 $$ = new Unary (Unary.Operator.Indirection, (Expression) $2, lexer.Location);
3041 | BITWISE_AND prefixed_unary_expression
3043 $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, lexer.Location);
3047 pre_increment_expression
3048 : OP_INC prefixed_unary_expression
3050 $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement,
3051 (Expression) $2, lexer.Location);
3055 pre_decrement_expression
3056 : OP_DEC prefixed_unary_expression
3058 $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement,
3059 (Expression) $2, lexer.Location);
3063 multiplicative_expression
3064 : prefixed_unary_expression
3065 | multiplicative_expression STAR prefixed_unary_expression
3067 $$ = new Binary (Binary.Operator.Multiply,
3068 (Expression) $1, (Expression) $3, lexer.Location);
3070 | multiplicative_expression DIV prefixed_unary_expression
3072 $$ = new Binary (Binary.Operator.Division,
3073 (Expression) $1, (Expression) $3, lexer.Location);
3075 | multiplicative_expression PERCENT prefixed_unary_expression
3077 $$ = new Binary (Binary.Operator.Modulus,
3078 (Expression) $1, (Expression) $3, lexer.Location);
3083 : multiplicative_expression
3084 | additive_expression PLUS multiplicative_expression
3086 $$ = new Binary (Binary.Operator.Addition,
3087 (Expression) $1, (Expression) $3, lexer.Location);
3089 | additive_expression MINUS multiplicative_expression
3091 $$ = new Binary (Binary.Operator.Subtraction,
3092 (Expression) $1, (Expression) $3, lexer.Location);
3097 : additive_expression
3098 | shift_expression OP_SHIFT_LEFT additive_expression
3100 $$ = new Binary (Binary.Operator.LeftShift,
3101 (Expression) $1, (Expression) $3, lexer.Location);
3103 | shift_expression OP_SHIFT_RIGHT additive_expression
3105 $$ = new Binary (Binary.Operator.RightShift,
3106 (Expression) $1, (Expression) $3, lexer.Location);
3110 relational_expression
3112 | relational_expression OP_LT shift_expression
3114 $$ = new Binary (Binary.Operator.LessThan,
3115 (Expression) $1, (Expression) $3, lexer.Location);
3117 | relational_expression OP_GT shift_expression
3119 $$ = new Binary (Binary.Operator.GreaterThan,
3120 (Expression) $1, (Expression) $3, lexer.Location);
3122 | relational_expression OP_LE shift_expression
3124 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3125 (Expression) $1, (Expression) $3, lexer.Location);
3127 | relational_expression OP_GE shift_expression
3129 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3130 (Expression) $1, (Expression) $3, lexer.Location);
3132 | relational_expression IS type
3134 $$ = new Is ((Expression) $1, (Expression) $3, lexer.Location);
3136 | relational_expression AS type
3138 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3143 : relational_expression
3144 | equality_expression OP_EQ relational_expression
3146 $$ = new Binary (Binary.Operator.Equality,
3147 (Expression) $1, (Expression) $3, lexer.Location);
3149 | equality_expression OP_NE relational_expression
3151 $$ = new Binary (Binary.Operator.Inequality,
3152 (Expression) $1, (Expression) $3, lexer.Location);
3157 : equality_expression
3158 | and_expression BITWISE_AND equality_expression
3160 $$ = new Binary (Binary.Operator.BitwiseAnd,
3161 (Expression) $1, (Expression) $3, lexer.Location);
3165 exclusive_or_expression
3167 | exclusive_or_expression CARRET and_expression
3169 $$ = new Binary (Binary.Operator.ExclusiveOr,
3170 (Expression) $1, (Expression) $3, lexer.Location);
3174 inclusive_or_expression
3175 : exclusive_or_expression
3176 | inclusive_or_expression BITWISE_OR exclusive_or_expression
3178 $$ = new Binary (Binary.Operator.BitwiseOr,
3179 (Expression) $1, (Expression) $3, lexer.Location);
3183 conditional_and_expression
3184 : inclusive_or_expression
3185 | conditional_and_expression OP_AND inclusive_or_expression
3187 $$ = new Binary (Binary.Operator.LogicalAnd,
3188 (Expression) $1, (Expression) $3, lexer.Location);
3192 conditional_or_expression
3193 : conditional_and_expression
3194 | conditional_or_expression OP_OR conditional_and_expression
3196 $$ = new Binary (Binary.Operator.LogicalOr,
3197 (Expression) $1, (Expression) $3, lexer.Location);
3201 conditional_expression
3202 : conditional_or_expression
3203 | conditional_or_expression INTERR expression COLON expression
3205 $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5, lexer.Location);
3209 assignment_expression
3210 : prefixed_unary_expression ASSIGN expression
3212 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3214 | prefixed_unary_expression OP_MULT_ASSIGN expression
3216 Location l = lexer.Location;
3218 $$ = new CompoundAssign (
3219 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3221 | prefixed_unary_expression OP_DIV_ASSIGN expression
3223 Location l = lexer.Location;
3225 $$ = new CompoundAssign (
3226 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3228 | prefixed_unary_expression OP_MOD_ASSIGN expression
3230 Location l = lexer.Location;
3232 $$ = new CompoundAssign (
3233 Binary.Operator.Modulus, (Expression) $1, (Expression) $3, l);
3235 | prefixed_unary_expression OP_ADD_ASSIGN expression
3237 Location l = lexer.Location;
3239 $$ = new CompoundAssign (
3240 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3242 | prefixed_unary_expression OP_SUB_ASSIGN expression
3244 Location l = lexer.Location;
3246 $$ = new CompoundAssign (
3247 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3249 | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
3251 Location l = lexer.Location;
3253 $$ = new CompoundAssign (
3254 Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, l);
3256 | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
3258 Location l = lexer.Location;
3260 $$ = new CompoundAssign (
3261 Binary.Operator.RightShift, (Expression) $1, (Expression) $3, l);
3263 | prefixed_unary_expression OP_AND_ASSIGN expression
3265 Location l = lexer.Location;
3267 $$ = new CompoundAssign (
3268 Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, l);
3270 | prefixed_unary_expression OP_OR_ASSIGN expression
3272 Location l = lexer.Location;
3274 $$ = new CompoundAssign (
3275 Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, l);
3277 | prefixed_unary_expression OP_XOR_ASSIGN expression
3279 Location l = lexer.Location;
3281 $$ = new CompoundAssign (
3282 Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, l);
3287 : conditional_expression
3288 | assignment_expression
3308 MemberName name = MakeName ((MemberName) $5);
3309 bool partial = (bool) $3;
3310 int mod_flags = (int) $2;
3313 ClassPart part = PartialContainer.CreatePart (
3314 current_namespace, current_container, name, mod_flags,
3315 (Attributes) $1, Kind.Class, lexer.Location);
3317 current_container = part.PartialContainer;
3318 current_class = part;
3320 if ((mod_flags & Modifiers.STATIC) != 0) {
3321 current_class = new StaticClass (
3322 current_namespace, current_container, name,
3323 mod_flags, (Attributes) $1, lexer.Location);
3325 current_class = new Class (
3326 current_namespace, current_container, name,
3327 mod_flags, (Attributes) $1, lexer.Location);
3330 current_container = current_class;
3331 RootContext.Tree.RecordDecl (name.GetName (true), current_class);
3337 if (current_class.Name == "System.Object") {
3338 Report.Error (537, current_class.Location,
3339 "The class System.Object cannot have a base " +
3340 "class or implement an interface.");
3342 current_class.Bases = (ArrayList) $7;
3345 if (RootContext.Documentation != null) {
3346 current_class.DocComment = Lexer.consume_doc_comment ();
3347 Lexer.doc_state = XmlCommentState.Allowed;
3350 current_class.Register ();
3354 if (RootContext.Documentation != null)
3355 Lexer.doc_state = XmlCommentState.Allowed;
3361 current_container = current_container.Parent;
3362 current_class = current_container;
3368 { $$ = (bool) false; }
3370 { $$ = (bool) true; }
3374 : /* empty */ { $$ = (int) 0; }
3380 | modifiers modifier
3385 if ((m1 & m2) != 0) {
3386 Location l = lexer.Location;
3387 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
3389 $$ = (int) (m1 | m2);
3394 : NEW { $$ = Modifiers.NEW; }
3395 | PUBLIC { $$ = Modifiers.PUBLIC; }
3396 | PROTECTED { $$ = Modifiers.PROTECTED; }
3397 | INTERNAL { $$ = Modifiers.INTERNAL; }
3398 | PRIVATE { $$ = Modifiers.PRIVATE; }
3399 | ABSTRACT { $$ = Modifiers.ABSTRACT; }
3400 | SEALED { $$ = Modifiers.SEALED; }
3401 | STATIC { $$ = Modifiers.STATIC; }
3402 | READONLY { $$ = Modifiers.READONLY; }
3403 | VIRTUAL { $$ = Modifiers.VIRTUAL; }
3404 | OVERRIDE { $$ = Modifiers.OVERRIDE; }
3405 | EXTERN { $$ = Modifiers.EXTERN; }
3406 | VOLATILE { $$ = Modifiers.VOLATILE; }
3407 | UNSAFE { $$ = Modifiers.UNSAFE; }
3411 : /* empty */ { $$ = null; }
3412 | class_base { $$ = $1; }
3416 : COLON type_list { $$ = $2; }
3424 // A block is "contained" on the following places:
3426 // property_declaration as part of the accessor body (get/set)
3427 // operator_declaration
3428 // constructor_declaration
3429 // destructor_declaration
3430 // event_declaration as part of add_accessor_declaration or remove_accessor_declaration
3435 if (current_block == null){
3436 current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
3437 top_current_block = current_block;
3439 current_block = new Block (current_block, current_local_parameters,
3440 lexer.Location, Location.Null);
3443 opt_statement_list CLOSE_BRACE
3445 while (current_block.Implicit)
3446 current_block = current_block.Parent;
3448 current_block.SetEndLocation (lexer.Location);
3449 current_block = current_block.Parent;
3450 if (current_block == null)
3451 top_current_block = null;
3462 | statement_list statement
3466 : declaration_statement
3468 if ($1 != null && (Block) $1 != current_block){
3469 current_block.AddStatement ((Statement) $1);
3470 current_block = (Block) $1;
3473 | valid_declaration_statement
3475 current_block.AddStatement ((Statement) $1);
3480 valid_declaration_statement
3483 | expression_statement
3484 | selection_statement
3485 | iteration_statement
3489 | unchecked_statement
3497 : valid_declaration_statement
3498 | declaration_statement
3500 Report.Error (1023, lexer.Location, "An embedded statement may not be a declaration.");
3505 Report.Error (1023, lexer.Location, "An embedded statement may not be a labeled statement.");
3513 $$ = EmptyStatement.Value;
3520 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
3522 if (current_block.AddLabel ((string) $1, labeled, lexer.Location))
3523 current_block.AddStatement (labeled);
3528 declaration_statement
3529 : local_variable_declaration SEMICOLON
3532 DictionaryEntry de = (DictionaryEntry) $1;
3534 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
3538 | local_constant_declaration SEMICOLON
3541 DictionaryEntry de = (DictionaryEntry) $1;
3543 $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
3549 * The following is from Rhys' grammar:
3550 * > Types in local variable declarations must be recognized as
3551 * > expressions to prevent reduce/reduce errors in the grammar.
3552 * > The expressions are converted into types during semantic analysis.
3555 : primary_expression opt_rank_specifier
3557 // FIXME: Do something smart here regarding the composition of the type.
3559 // Ok, the above "primary_expression" is there to get rid of
3560 // both reduce/reduce and shift/reduces in the grammar, it should
3561 // really just be "type_name". If you use type_name, a reduce/reduce
3562 // creeps up. If you use namespace_or_type_name (which is all we need
3563 // really) two shift/reduces appear.
3566 // So the super-trick is that primary_expression
3567 // can only be either a SimpleName or a MemberAccess.
3568 // The MemberAccess case arises when you have a fully qualified type-name like :
3570 // SimpleName is when you have
3573 Expression expr = (Expression) $1;
3574 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
3575 Error_ExpectingTypeName (lexer.Location, expr);
3579 // So we extract the string corresponding to the SimpleName
3583 if ((string) $2 == "")
3586 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3589 | builtin_types opt_rank_specifier
3591 if ((string) $2 == "")
3594 $$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3598 local_variable_pointer_type
3599 : primary_expression STAR
3601 Expression expr = (Expression) $1;
3602 Location l = lexer.Location;
3604 if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
3605 Error_ExpectingTypeName (l, expr);
3609 $$ = new ComposedCast ((Expression) $1, "*", l);
3611 | builtin_types STAR
3613 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);;
3617 $$ = new ComposedCast (TypeManager.system_void_expr, "*", lexer.Location);;
3619 | local_variable_pointer_type STAR
3621 $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
3625 local_variable_declaration
3626 : local_variable_type variable_declarators
3629 $$ = new DictionaryEntry ($1, $2);
3633 | local_variable_pointer_type opt_rank_specifier variable_declarators
3638 if ((string) $2 == "")
3639 t = (Expression) $1;
3641 t = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
3642 $$ = new DictionaryEntry (t, $3);
3648 local_constant_declaration
3649 : CONST local_variable_type constant_declarators
3652 $$ = new DictionaryEntry ($2, $3);
3658 expression_statement
3659 : statement_expression SEMICOLON
3666 // We have to do the wrapping here and not in the case above,
3667 // because statement_expression is used for example in for_statement
3669 statement_expression
3670 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3671 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3672 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3673 | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3674 | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3675 | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3676 | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
3678 Report.Error (1002, lexer.Location, "Expecting `;'");
3683 object_creation_expression
3684 : object_or_delegate_creation_expression
3685 { note ("complain if this is a delegate maybe?"); }
3694 : IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS
3697 Location l = (Location) $3;
3699 $$ = new If ((Expression) $4, (Statement) $6, l);
3701 if (RootContext.WarningLevel >= 4){
3702 if ($6 == EmptyStatement.Value)
3703 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3707 | IF OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS
3708 embedded_statement ELSE embedded_statement
3710 Location l = (Location) $3;
3712 $$ = new If ((Expression) $4, (Statement) $6, (Statement) $8, l);
3717 : SWITCH OPEN_PARENS _mark_
3719 switch_stack.Push (current_block);
3721 expression CLOSE_PARENS
3724 $$ = new Switch ((Expression) $5, (ArrayList) $7, (Location) $3);
3725 current_block = (Block) switch_stack.Pop ();
3741 Report.Error (1522, lexer.Location, "Empty switch block");
3749 ArrayList sections = new ArrayList (4);
3754 | switch_sections switch_section
3756 ArrayList sections = (ArrayList) $1;
3766 current_block = current_block.CreateSwitchBlock (lexer.Location);
3770 Block topmost = current_block;
3772 while (topmost.Implicit)
3773 topmost = topmost.Parent;
3774 $$ = new SwitchSection ((ArrayList) $1, topmost);
3781 ArrayList labels = new ArrayList (4);
3786 | switch_labels switch_label
3788 ArrayList labels = (ArrayList) ($1);
3796 : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, lexer.Location); }
3797 | DEFAULT COLON { $$ = new SwitchLabel (null, lexer.Location); }
3800 1523, lexer.Location,
3801 "The keyword case or default must precede code in switch block");
3813 : WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS embedded_statement
3815 Location l = (Location) $3;
3816 $$ = new While ((Expression) $4, (Statement) $6, l);
3818 if (RootContext.WarningLevel >= 4){
3819 if ($6 == EmptyStatement.Value)
3820 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3826 : DO embedded_statement
3827 WHILE OPEN_PARENS _mark_ boolean_expression CLOSE_PARENS SEMICOLON
3829 Location l = (Location) $5;
3831 $$ = new Do ((Statement) $2, (Expression) $6, l);
3837 opt_for_initializer SEMICOLON _mark_
3839 Block assign_block = new Block (current_block);
3840 current_block = assign_block;
3842 if ($3 is DictionaryEntry){
3843 DictionaryEntry de = (DictionaryEntry) $3;
3845 Expression type = (Expression) de.Key;
3846 ArrayList var_declarators = (ArrayList) de.Value;
3848 foreach (VariableDeclaration decl in var_declarators){
3852 vi = current_block.AddVariable (
3853 type, decl.identifier, current_local_parameters, decl.Location);
3857 Location l = lexer.Location;
3859 if (decl.expression_or_array_initializer is Expression){
3860 expr = (Expression) decl.expression_or_array_initializer;
3861 } else if (decl.expression_or_array_initializer == null) {
3864 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3865 expr = new ArrayCreation (type, "", init, decl.Location);
3868 LocalVariableReference var;
3869 var = new LocalVariableReference (assign_block, decl.identifier, l);
3872 Assign a = new Assign (var, expr, decl.Location);
3874 assign_block.AddStatement (new StatementExpression (a, lexer.Location));
3878 // Note: the $$ below refers to the value of this code block, not of the LHS non-terminal.
3879 // This can be referred to as $6 below.
3885 opt_for_condition SEMICOLON
3886 opt_for_iterator CLOSE_PARENS
3889 Location l = (Location) $5;
3891 For f = new For ((Statement) $6, (Expression) $7, (Statement) $9, (Statement) $11, l);
3893 if (RootContext.WarningLevel >= 4){
3894 if ($11 == EmptyStatement.Value)
3895 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
3898 current_block.AddStatement (f);
3899 while (current_block.Implicit)
3900 current_block = current_block.Parent;
3902 current_block = current_block.Parent;
3907 : /* empty */ { $$ = EmptyStatement.Value; }
3912 : local_variable_declaration
3913 | statement_expression_list
3917 : /* empty */ { $$ = null; }
3918 | boolean_expression
3922 : /* empty */ { $$ = EmptyStatement.Value; }
3927 : statement_expression_list
3930 statement_expression_list
3931 : statement_expression
3933 // CHANGE: was `null'
3934 Block b = new Block (current_block, Block.Flags.Implicit);
3936 b.AddStatement ((Statement) $1);
3939 | statement_expression_list COMMA statement_expression
3941 Block b = (Block) $1;
3943 b.AddStatement ((Statement) $3);
3949 : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS
3951 Report.Error (230, lexer.Location, "Type and identifier are both required in a foreach statement");
3954 | FOREACH OPEN_PARENS type IDENTIFIER IN _mark_
3955 expression CLOSE_PARENS
3957 Block foreach_block = new Block (current_block);
3958 current_block = foreach_block;
3960 Location l = lexer.Location;
3963 vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
3967 // Get a writable reference to this read-only variable.
3969 // Note that the $$ here refers to the value of _this_ code block,
3970 // not the value of the LHS non-terminal. This can be referred to as $9 below.
3971 $$ = new LocalVariableReference (foreach_block, (string) $4, l, vi, false);
3978 LocalVariableReference v = (LocalVariableReference) $9;
3979 Location l = (Location) $6;
3982 Foreach f = new Foreach ((Expression) $3, v, (Expression) $7, (Statement) $10, l);
3983 current_block.AddStatement (f);
3986 while (current_block.Implicit)
3987 current_block = current_block.Parent;
3989 current_block = current_block.Parent;
3995 | continue_statement
4005 $$ = new Break (lexer.Location);
4010 : CONTINUE SEMICOLON
4012 $$ = new Continue (lexer.Location);
4017 : GOTO IDENTIFIER SEMICOLON
4019 $$ = new Goto (current_block, (string) $2, lexer.Location);
4021 | GOTO CASE constant_expression SEMICOLON
4023 $$ = new GotoCase ((Expression) $3, lexer.Location);
4025 | GOTO DEFAULT SEMICOLON
4027 $$ = new GotoDefault (lexer.Location);
4032 : RETURN opt_expression SEMICOLON
4034 $$ = new Return ((Expression) $2, lexer.Location);
4039 : THROW opt_expression SEMICOLON
4041 $$ = new Throw ((Expression) $2, lexer.Location);
4046 : IDENTIFIER RETURN expression SEMICOLON
4048 string s = (string) $1;
4050 Report.Error (1003, lexer.Location, "; expected");
4053 if (RootContext.Version == LanguageVersion.ISO_1){
4054 Report.FeatureIsNotStandardized (lexer.Location, "yield statement");
4057 if (iterator_container == null){
4058 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
4061 iterator_container.SetYields ();
4062 $$ = new Yield ((Expression) $3, lexer.Location);
4065 | IDENTIFIER BREAK SEMICOLON
4067 string s = (string) $1;
4069 Report.Error (1003, lexer.Location, "; expected");
4072 if (RootContext.Version == LanguageVersion.ISO_1){
4073 Report.FeatureIsNotStandardized (lexer.Location, "yield statement");
4076 if (iterator_container == null){
4077 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
4080 iterator_container.SetYields ();
4081 $$ = new YieldBreak (lexer.Location);
4092 : TRY block catch_clauses
4096 ArrayList c = (ArrayList)$3;
4097 for (int i = 0; i < c.Count; ++i) {
4098 Catch cc = (Catch) c [i];
4100 if (i != c.Count - 1)
4101 Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks");
4108 // Now s contains the list of specific catch clauses
4109 // and g contains the general one.
4111 $$ = new Try ((Block) $2, c, g, null, ((Block) $2).loc);
4113 | TRY block opt_catch_clauses FINALLY block
4116 ArrayList s = new ArrayList (4);
4117 ArrayList catch_list = (ArrayList) $3;
4119 if (catch_list != null){
4120 foreach (Catch cc in catch_list) {
4128 $$ = new Try ((Block) $2, s, g, (Block) $5, ((Block) $2).loc);
4132 Report.Error (1524, lexer.Location, "Expected catch or finally");
4137 : /* empty */ { $$ = null; }
4144 ArrayList l = new ArrayList (4);
4149 | catch_clauses catch_clause
4151 ArrayList l = (ArrayList) $1;
4159 : /* empty */ { $$ = null; }
4164 : CATCH opt_catch_args
4166 Expression type = null;
4170 DictionaryEntry cc = (DictionaryEntry) $2;
4171 type = (Expression) cc.Key;
4172 id = (string) cc.Value;
4175 ArrayList one = new ArrayList (4);
4176 Location loc = lexer.Location;
4178 one.Add (new VariableDeclaration (id, null, loc));
4180 current_block = new Block (current_block);
4181 Block b = declare_local_variables (type, one, loc);
4186 Expression type = null;
4190 DictionaryEntry cc = (DictionaryEntry) $2;
4191 type = (Expression) cc.Key;
4192 id = (string) cc.Value;
4195 while (current_block.Implicit)
4196 current_block = current_block.Parent;
4197 current_block = current_block.Parent;
4201 $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc);
4206 : /* empty */ { $$ = null; }
4211 : OPEN_PARENS type opt_identifier CLOSE_PARENS
4213 $$ = new DictionaryEntry ($2, $3);
4220 $$ = new Checked ((Block) $2);
4227 $$ = new Unchecked ((Block) $2);
4234 if (!RootContext.Unsafe){
4235 Report.Error (227, lexer.Location,
4236 "Unsafe code can only be used if --unsafe is used");
4239 $$ = new Unsafe ((Block) $3);
4245 type fixed_pointer_declarators
4248 ArrayList list = (ArrayList) $4;
4249 Expression type = (Expression) $3;
4250 Location l = lexer.Location;
4251 int top = list.Count;
4253 Block assign_block = new Block (current_block);
4254 current_block = assign_block;
4256 for (int i = 0; i < top; i++){
4257 Pair p = (Pair) list [i];
4260 v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
4272 Location l = (Location) $6;
4274 Fixed f = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $8, l);
4276 if (RootContext.WarningLevel >= 4){
4277 if ($8 == EmptyStatement.Value)
4278 Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
4281 current_block.AddStatement (f);
4282 while (current_block.Implicit)
4283 current_block = current_block.Parent;
4285 current_block = current_block.Parent;
4289 fixed_pointer_declarators
4290 : fixed_pointer_declarator {
4291 ArrayList declarators = new ArrayList (4);
4293 declarators.Add ($1);
4296 | fixed_pointer_declarators COMMA fixed_pointer_declarator
4298 ArrayList declarators = (ArrayList) $1;
4300 declarators.Add ($3);
4305 fixed_pointer_declarator
4306 : IDENTIFIER ASSIGN expression
4308 $$ = new Pair ($1, $3);
4312 Report.Error (210, lexer.Location, "You must provide an initializer in a fixed or using statement declaration");
4318 : LOCK OPEN_PARENS expression CLOSE_PARENS
4324 $$ = new Lock ((Expression) $3, (Statement) $6, lexer.Location);
4329 : USING OPEN_PARENS resource_acquisition CLOSE_PARENS _mark_
4331 Block assign_block = new Block (current_block);
4332 current_block = assign_block;
4334 if ($3 is DictionaryEntry){
4335 DictionaryEntry de = (DictionaryEntry) $3;
4336 Location l = lexer.Location;
4338 Expression type = (Expression) de.Key;
4339 ArrayList var_declarators = (ArrayList) de.Value;
4341 ArrayList vars = new ArrayList (4);
4343 foreach (VariableDeclaration decl in var_declarators){
4345 LocalInfo vi = current_block.AddVariable (
4346 type, decl.identifier,
4347 current_local_parameters, decl.Location);
4353 if (decl.expression_or_array_initializer is Expression){
4354 expr = (Expression) decl.expression_or_array_initializer;
4356 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4358 Report.Error (210, l, "You must provide an initializer in a fixed or using statement declaration");
4361 expr = new ArrayCreation (type, "", init, decl.Location);
4364 LocalVariableReference var;
4366 // Get a writable reference to this read-only variable.
4367 var = new LocalVariableReference (assign_block, decl.identifier, l, vi, false);
4369 // This is so that it is not a warning on using variables
4372 vars.Add (new DictionaryEntry (var, expr));
4374 // Assign a = new Assign (var, expr, decl.Location);
4375 // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
4378 // Note: the $$ here refers to the value of this code block and not of the LHS non-terminal.
4379 // It can be referred to as $6 below.
4380 $$ = new DictionaryEntry (type, vars);
4387 Using u = new Using ($6, (Statement) $7, (Location) $5);
4388 current_block.AddStatement (u);
4389 while (current_block.Implicit)
4390 current_block = current_block.Parent;
4392 current_block = current_block.Parent;
4396 resource_acquisition
4397 : local_variable_declaration
4401 // Utility rule to save location information
4404 { $$ = lexer.Location; }
4409 // A class used to pass around variable declarations and constants
4411 public class VariableDeclaration {
4412 public string identifier;
4413 public object expression_or_array_initializer;
4414 public Location Location;
4415 public Attributes OptAttributes;
4416 public string DocComment;
4418 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
4420 this.identifier = id;
4421 this.expression_or_array_initializer = eoai;
4423 this.OptAttributes = opt_attrs;
4426 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4432 /// Used to pass around interface property information
4434 public class InterfaceAccessorInfo {
4436 public readonly Accessor Get, Set;
4438 public InterfaceAccessorInfo (bool has_get, bool has_set,
4439 Attributes get_attrs, Attributes set_attrs, int get_mod, int set_mod, Location get_loc, Location set_loc)
4442 Report.Error (275, get_loc, "Accessibility modifiers can not be used on accessors in interfaces");
4444 Report.Error (275, set_loc, "Accessibility modifiers can not be used on accessors in interfaces");
4447 Get = new Accessor (null, 0, get_attrs, get_loc);
4449 Set = new Accessor (null, 0, set_attrs, set_loc);
4456 // A class used to hold info about an indexer declarator
4458 public class IndexerDeclaration {
4459 public Expression type;
4460 public MemberName interface_type;
4461 public Parameters param_list;
4463 public IndexerDeclaration (Expression type, MemberName interface_type,
4464 Parameters param_list)
4467 this.interface_type = interface_type;
4468 this.param_list = param_list;
4473 // We use this when we do not have an object in advance that is an IIteratorContainer
4475 public class SimpleIteratorContainer : IIteratorContainer {
4478 public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
4483 public static SimpleIteratorContainer GetSimple () {
4484 Simple.Yields = false;
4488 public void SetYields () { Yields = true; }
4492 // A class used to hold info about an operator declarator
4494 public class OperatorDeclaration {
4495 public Operator.OpType optype;
4496 public Expression ret_type, arg1type, arg2type;
4497 public string arg1name, arg2name;
4498 public Location location;
4500 public OperatorDeclaration (Operator.OpType op, Expression ret_type,
4501 Expression arg1type, string arg1name,
4502 Expression arg2type, string arg2name, Location location)
4505 this.ret_type = ret_type;
4506 this.arg1type = arg1type;
4507 this.arg1name = arg1name;
4508 this.arg2type = arg2type;
4509 this.arg2name = arg2name;
4510 this.location = location;
4515 void Error_ExpectingTypeName (Location l, Expression expr)
4517 if (expr is Invocation){
4518 Report.Error (1002, l, "; expected");
4520 Report.Error (-1, l, "Invalid Type definition");
4525 // Given the @class_name name, it creates a fully qualified name
4526 // based on the containing declaration space
4529 MakeName (MemberName class_name)
4531 string ns = current_namespace.FullName;
4533 if (current_container.Name == ""){
4535 return new MemberName (new MemberName (ns), class_name);
4539 return new MemberName (current_container.MemberName, class_name);
4543 Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
4545 Block implicit_block;
4546 ArrayList inits = null;
4549 // We use the `Used' property to check whether statements
4550 // have been added to the current block. If so, we need
4551 // to create another block to contain the new declaration
4552 // otherwise, as an optimization, we use the same block to
4553 // add the declaration.
4555 // FIXME: A further optimization is to check if the statements
4556 // that were added were added as part of the initialization
4557 // below. In which case, no other statements have been executed
4558 // and we might be able to reduce the number of blocks for
4559 // situations like this:
4561 // int j = 1; int k = j + 1;
4563 if (current_block.Used)
4564 implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
4566 implicit_block = current_block;
4568 foreach (VariableDeclaration decl in variable_declarators){
4570 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
4571 if (decl.expression_or_array_initializer != null){
4573 inits = new ArrayList (4);
4580 return implicit_block;
4582 foreach (VariableDeclaration decl in inits){
4586 if (decl.expression_or_array_initializer is Expression){
4587 expr = (Expression) decl.expression_or_array_initializer;
4590 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4592 expr = new ArrayCreation (type, "", init, decl.Location);
4595 LocalVariableReference var;
4596 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4598 assign = new Assign (var, expr, decl.Location);
4600 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4603 return implicit_block;
4606 Block declare_local_constants (Expression type, ArrayList declarators)
4608 Block implicit_block;
4610 if (current_block.Used)
4611 implicit_block = new Block (current_block, Block.Flags.Implicit);
4613 implicit_block = current_block;
4615 foreach (VariableDeclaration decl in declarators){
4616 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4617 current_local_parameters, decl.Location);
4620 return implicit_block;
4623 void CheckAttributeTarget (string a)
4627 case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
4631 Location l = lexer.Location;
4632 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4638 void CheckUnaryOperator (Operator.OpType op)
4642 case Operator.OpType.LogicalNot:
4643 case Operator.OpType.OnesComplement:
4644 case Operator.OpType.Increment:
4645 case Operator.OpType.Decrement:
4646 case Operator.OpType.True:
4647 case Operator.OpType.False:
4648 case Operator.OpType.Addition:
4649 case Operator.OpType.Subtraction:
4654 Location l = lexer.Location;
4655 Report.Error (1019, l, "Overloadable unary operator expected");
4661 void CheckBinaryOperator (Operator.OpType op)
4665 case Operator.OpType.Addition:
4666 case Operator.OpType.Subtraction:
4667 case Operator.OpType.Multiply:
4668 case Operator.OpType.Division:
4669 case Operator.OpType.Modulus:
4670 case Operator.OpType.BitwiseAnd:
4671 case Operator.OpType.BitwiseOr:
4672 case Operator.OpType.ExclusiveOr:
4673 case Operator.OpType.LeftShift:
4674 case Operator.OpType.RightShift:
4675 case Operator.OpType.Equality:
4676 case Operator.OpType.Inequality:
4677 case Operator.OpType.GreaterThan:
4678 case Operator.OpType.LessThan:
4679 case Operator.OpType.GreaterThanOrEqual:
4680 case Operator.OpType.LessThanOrEqual:
4684 Location l = lexer.Location;
4685 Report.Error (1020, l, "Overloadable binary operator expected");
4691 void syntax_error (Location l, string msg)
4693 Report.Error (1003, l, "Syntax error, " + msg);
4696 void output (string s)
4698 Console.WriteLine (s);
4701 void note (string s)
4703 // Used to put annotations
4708 public Tokenizer Lexer {
4714 public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
4716 current_namespace = new NamespaceEntry (null, file, null, Location.Null);
4717 this.name = file.Name;
4719 current_container = RootContext.Tree.Types;
4720 current_container.NamespaceEntry = current_namespace;
4721 oob_stack = new Stack ();
4722 switch_stack = new Stack ();
4724 lexer = new Tokenizer (reader, file, defines);
4727 public void parse ()
4730 if (yacc_verbose_flag > 1)
4731 yyparse (lexer, new yydebug.yyDebugSimple ());
4734 Tokenizer tokenizer = lexer as Tokenizer;
4735 tokenizer.cleanup ();
4736 } catch (Exception e){
4738 // Removed for production use, use parser verbose to get the output.
4740 // Console.WriteLine (e);
4741 Report.Error (-25, lexer.Location, "Parsing error");
4742 if (yacc_verbose_flag > 0)
4743 Console.WriteLine (e);
4747 void CheckToken (int error, int yyToken, string msg)
4749 if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){
4750 Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()));
4753 Report.Error (error, lexer.Location, msg);
4756 void CheckIdentifierToken (int yyToken)
4758 CheckToken (1041, yyToken, "Identifier expected");
4761 string ConsumeStoredComment ()
4763 string s = tmpComment;
4765 Lexer.doc_state = XmlCommentState.Allowed;