X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fcs-parser.jay;h=112788986c9d52bac6f08d7b0e8de11dfebd1320;hb=dd866d68820e0f66046256bb5d3f84e3988a8be0;hp=5f8be118e099e11af8bc545ce902a3a83dd67110;hpb=208af1a3a43ae61ec8567e8ea17f087f78918528;p=mono.git diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index 5f8be118e09..112788986c9 100755 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -35,48 +35,57 @@ namespace Mono.CSharp IIteratorContainer iterator_container; - // - // Current block is used to add statements as we find - // them. - // + /// + /// Current block is used to add statements as we find + /// them. + /// Block current_block; - // - // Current interface is used by the various declaration - // productions in the interface declaration to "add" - // the interfaces as we find them. - // + /// + /// If true, creates a toplevel block in the block production + /// This is flagged by the delegate creation + /// + bool create_toplevel_block; + + /// + /// + /// Current interface is used by the various declaration + /// productions in the interface declaration to "add" + /// the interfaces as we find them. + /// Interface current_interface; - // - // This is used by the unary_expression code to resolve - // a name against a parameter. - // + Delegate current_delegate; + + /// + /// This is used by the unary_expression code to resolve + /// a name against a parameter. + /// Parameters current_local_parameters; - // - // Using during property parsing to describe the implicit - // value parameter that is passed to the "set" and "get"accesor - // methods (properties and indexers). - // + /// + /// Using during property parsing to describe the implicit + /// value parameter that is passed to the "set" and "get"accesor + /// methods (properties and indexers). + /// Expression implicit_value_parameter_type; Parameters indexer_parameters; - // - // Used to determine if we are parsing the get/set pair - // of an indexer or a property - // + /// + /// Used to determine if we are parsing the get/set pair + /// of an indexer or a property + /// bool parsing_indexer; - // - // An out-of-band stack. - // + /// + /// An out-of-band stack. + /// Stack oob_stack; - // - // Switch stack. - // + /// + /// Switch stack. + /// Stack switch_stack; public bool yacc_verbose_flag; @@ -84,10 +93,17 @@ namespace Mono.CSharp // Name of the file we are parsing public string name; - // - // The current file. - // + /// + /// The current file. + /// SourceFile file; + + + /// Current attribute target + string current_attr_target; + + /// assembly and module attribute definition is enabled + bool global_attrs_enabled = true; %} %token EOF @@ -98,6 +114,7 @@ namespace Mono.CSharp /* *These are the C# keywords */ +%token FIRST_KEYWORD %token ABSTRACT %token AS %token ADD @@ -179,14 +196,14 @@ namespace Mono.CSharp %token VOLATILE %token WHERE %token WHILE - -/* v2 tokens */ -%token YIELD +%token ARGLIST /* C# keywords which are not really keywords */ %token GET "get" %token SET "set" +%left LAST_KEYWORD + /* C# single character operators/punctuation. */ %token OPEN_BRACE "{" %token CLOSE_BRACE "}" @@ -207,6 +224,7 @@ namespace Mono.CSharp %token OP_LT "<" %token OP_GENERICS_LT "<" %token OP_GT ">" +%token OP_GENERICS_GT ">" %token BITWISE_AND "&" %token BITWISE_OR "|" %token STAR "*" @@ -247,6 +265,11 @@ namespace Mono.CSharp %token LITERAL_STRING "string literal" %token IDENTIFIER +%token CLOSE_PARENS_CAST +%token CLOSE_PARENS_NO_CAST +%token CLOSE_PARENS_OPEN_PARENS +%token CLOSE_PARENS_MINUS +%token DEFAULT_OPEN_PARENS /* Add precedence rules to solve dangling else s/r conflict */ %nonassoc LOWPREC @@ -272,8 +295,8 @@ namespace Mono.CSharp compilation_unit : outer_declarations opt_EOF - | outer_declarations attribute_sections opt_EOF - | attribute_sections opt_EOF + | outer_declarations global_attributes opt_EOF + | global_attributes opt_EOF | opt_EOF /* allow empty files */ ; @@ -306,7 +329,10 @@ using_alias_directive : USING IDENTIFIER ASSIGN namespace_or_type_name SEMICOLON { - current_namespace.UsingAlias ((string) $2, (string) $4, lexer.Location); + current_namespace.UsingAlias ((string) $2, (MemberName) $4, lexer.Location); + } + | USING error { + CheckIdentifierToken (yyToken); } ; @@ -323,21 +349,14 @@ using_namespace_directive // detach them // namespace_declaration - : opt_attributes NAMESPACE qualified_identifier + : opt_attributes NAMESPACE namespace_name { - Attributes attrs = (Attributes) $1; - - if (attrs != null) { - foreach (AttributeSection asec in attrs.AttributeSections) - if (asec.Target == "assembly") - RootContext.AddGlobalAttributeSection (current_container, asec); - else - Report.Error(1518, Lexer.Location, - "Attributes cannot be applied to namespaces." + if ($1 != null) { + Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces." + " Expected class, delegate, enum, interface, or struct"); } - current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3); + current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3, lexer.Location); } namespace_body opt_semicolon { @@ -355,15 +374,15 @@ opt_comma | COMMA ; -qualified_identifier - : IDENTIFIER - | qualified_identifier DOT IDENTIFIER { - $$ = (($1).ToString ()) + "." + ($3.ToString ()); } - ; +namespace_name + : namespace_or_type_name { + MemberName name = (MemberName) $1; + if (name.TypeArguments != null) + syntax_error (lexer.Location, "namespace name expected"); -namespace_name - : qualified_identifier + $$ = name.GetName (); + } ; namespace_body @@ -418,6 +437,13 @@ namespace_member_declaration | namespace_declaration { current_namespace.DeclarationFound = true; } + + | field_declaration { + Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations"); + } + | method_declaration { + Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations"); + } ; type_declaration @@ -430,6 +456,7 @@ type_declaration // Enable this when we have handled all errors, because this acts as a generic fallback // // | error { +// Console.WriteLine ("Token=" + yyToken); // Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate"); // } ; @@ -438,58 +465,93 @@ type_declaration // Attributes 17.2 // +global_attributes + : attribute_sections +{ + if ($1 != null) + CodeGen.Assembly.AddAttributes (((Attributes)$1).Attrs); + + $$ = $1; +} + opt_attributes : /* empty */ - | attribute_sections { $$ = $1; } + { + global_attrs_enabled = false; + $$ = null; + } + | attribute_sections + { + global_attrs_enabled = false; + $$ = $1; + } ; + attribute_sections : attribute_section { - AttributeSection sect = (AttributeSection) $1; + ArrayList sect = (ArrayList) $1; - if (sect.Target == "assembly") - RootContext.AddGlobalAttributeSection (current_container, sect); - - - $$ = new Attributes ((AttributeSection) $1); + if (global_attrs_enabled) { + if (current_attr_target == "module") { + CodeGen.Module.AddAttributes (sect); + $$ = null; + } else if (current_attr_target == "assembly") { + CodeGen.Assembly.AddAttributes (sect); + $$ = null; + } else { + $$ = new Attributes (sect); + } + } else { + $$ = new Attributes (sect); } + current_attr_target = null; + } | attribute_sections attribute_section { - Attributes attrs = null; - AttributeSection sect = (AttributeSection) $2; - - if (sect.Target == "assembly") - RootContext.AddGlobalAttributeSection (current_container, sect); + Attributes attrs = $1 as Attributes; + ArrayList sect = (ArrayList) $2; - if ($1 != null) { - attrs = (Attributes) $1; - attrs.AddAttributeSection (sect); + if (global_attrs_enabled) { + if (current_attr_target == "module") { + CodeGen.Module.AddAttributes (sect); + $$ = null; + } else if (current_attr_target == "assembly") { + CodeGen.Assembly.AddAttributes (sect); + $$ = null; + } else { + if (attrs == null) + attrs = new Attributes (sect); + else + attrs.AddAttributes (sect); + } + } else { + if (attrs == null) + attrs = new Attributes (sect); + else + attrs.AddAttributes (sect); } - $$ = attrs; + current_attr_target = null; } ; attribute_section : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET { - string target = null; - - if ($2 != null) - target = (string) $2; - - $$ = new AttributeSection (target, (ArrayList) $3); + $$ = $3; } | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET { - $$ = new AttributeSection (null, (ArrayList) $2); + $$ = $2; } ; attribute_target_specifier : attribute_target COLON { + current_attr_target = (string)$1; $$ = $1; } ; @@ -529,15 +591,24 @@ attribute } opt_attribute_arguments { - // - // Attributes need a string, not an expression: generic types will fail here. - // - $$ = new Attribute (((Expression) $1).ToString (), (ArrayList) $3, (Location) $2); + MemberName mname = (MemberName) $1; + if (mname.IsGeneric) { + Report.Error (404, lexer.Location, + "'<' unexpected: attributes cannot be generic"); + } + + string name = mname.GetName (); + if (current_attr_target == "assembly" || current_attr_target == "module") + $$ = new GlobalAttribute (current_container, current_attr_target, + name, (ArrayList) $3, (Location) $2); + else + $$ = new Attribute (current_attr_target, name, (ArrayList) $3, + (Location) $2); } ; attribute_name - : type_name { /* reserved attribute name or identifier: 17.4 */ } + : namespace_or_type_name { /* reserved attribute name or identifier: 17.4 */ } ; opt_attribute_arguments @@ -660,23 +731,29 @@ class_member_declaration struct_declaration : opt_attributes opt_modifiers - STRUCT IDENTIFIER + STRUCT member_name { Struct new_struct; - string full_struct_name = MakeName ((string) $4); + MemberName full_struct_name = MakeName ((MemberName) $4); - new_struct = new Struct (current_container, full_struct_name, (int) $2, - (Attributes) $1, lexer.Location); + new_struct = new Struct (current_namespace, current_container, full_struct_name, + (int) $2, (Attributes) $1, lexer.Location); current_container = new_struct; - current_container.Namespace = current_namespace; - RootContext.Tree.RecordDecl (full_struct_name, new_struct); + RootContext.Tree.RecordDecl (full_struct_name.GetName (true), new_struct); + lexer.ConstraintsParsing = true; } opt_class_base + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + } struct_body opt_semicolon { Struct new_struct = (Struct) current_container; + CheckDef (new_struct.SetParameterInfo ((ArrayList) $7), new_struct.Name, new_struct.Location); + if ($6 != null) new_struct.Bases = (ArrayList) $6; @@ -684,6 +761,9 @@ struct_declaration CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location); $$ = new_struct; } + | opt_attributes opt_modifiers STRUCT error { + CheckIdentifierToken (yyToken); + } ; struct_body @@ -885,12 +965,36 @@ opt_error_modifier method_header : opt_attributes opt_modifiers - type - member_name + type namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { - Method method = new Method ((Expression) $3, (int) $2, (string) $4, - (Parameters) $6, (Attributes) $1, lexer.Location); + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + + MemberName name = (MemberName) $4; + + if ($9 != null && name.TypeArguments == null) + Report.Error (80, lexer.Location, + "Contraints are not allowed on non-generic declarations"); + + Method method; + + GenericMethod generic = null; + if (name.TypeArguments != null) { + generic = new GenericMethod (current_namespace, current_container, + name, lexer.Location); + + CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + + method = new Method (generic, (Expression) $3, (int) $2, false, name, + (Parameters) $6, (Attributes) $1, lexer.Location); + } else + method = new Method (current_container, (Expression) $3, (int) $2, + false, name, (Parameters) $6, (Attributes) $1, + lexer.Location); current_local_parameters = (Parameters) $6; @@ -898,12 +1002,55 @@ method_header } | opt_attributes opt_modifiers - VOID - member_name + VOID namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { - Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4, - (Parameters) $6, (Attributes) $1, lexer.Location); + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + + MemberName name = (MemberName) $4; + + if ($9 != null && name.TypeArguments == null) + Report.Error (80, lexer.Location, + "Contraints are not allowed on non-generic declarations"); + + Method method; + GenericMethod generic = null; + if (name.TypeArguments != null) { + generic = new GenericMethod (current_namespace, current_container, + name, lexer.Location); + + + CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + + method = new Method (generic, TypeManager.system_void_expr, (int) $2, + false, name, (Parameters) $6, (Attributes) $1, + lexer.Location); + } else + method = new Method (current_container, TypeManager.system_void_expr, + (int) $2, false, name, (Parameters) $6, + (Attributes) $1, lexer.Location); + + current_local_parameters = (Parameters) $6; + + $$ = method; + } + | opt_attributes + opt_modifiers + type + modifiers namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + { + Report.Error (1585, lexer.Location, + String.Format ("Modifier {0} should appear before type", + Modifiers.Name ((int) $4))); + MemberName name = (MemberName) $4; + + Method method = new Method (current_container, TypeManager.system_void_expr, + 0, false, name, (Parameters) $6, (Attributes) $1, + lexer.Location); current_local_parameters = (Parameters) $6; $$ = method; @@ -939,10 +1086,23 @@ formal_parameter_list $$ = new Parameters (pars, (Parameter) $3, lexer.Location); } + | fixed_parameters COMMA ARGLIST + { + ArrayList pars_list = (ArrayList) $1; + + Parameter [] pars = new Parameter [pars_list.Count]; + pars_list.CopyTo (pars); + + $$ = new Parameters (pars, true, lexer.Location); + } | parameter_array { $$ = new Parameters (null, (Parameter) $1, lexer.Location); } + | ARGLIST + { + $$ = new Parameters (null, true, lexer.Location); + } ; fixed_parameters @@ -970,6 +1130,13 @@ fixed_parameter { $$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1); } + | opt_attributes + opt_parameter_modifier + type + error { + CheckIdentifierToken (yyToken); + $$ = null; + } ; opt_parameter_modifier @@ -988,16 +1155,16 @@ parameter_array $$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1); note ("type must be a single-dimension array type"); } - ; - -member_name - : qualified_identifier + | opt_attributes PARAMS type error { + CheckIdentifierToken (yyToken); + $$ = null; + } ; property_declaration : opt_attributes opt_modifiers - type member_name + type namespace_or_type_name OPEN_BRACE { implicit_value_parameter_type = (Expression) $3; @@ -1005,6 +1172,8 @@ property_declaration lexer.PropertyParsing = true; $$ = lexer.Location; + + iterator_container = SimpleIteratorContainer.GetSimple (); } accessor_declarations { @@ -1017,12 +1186,19 @@ property_declaration Accessor get_block = (Accessor) pair.First; Accessor set_block = (Accessor) pair.Second; + MemberName name = (MemberName) $4; + if (name.TypeArguments != null) + syntax_error (lexer.Location, "a property can't have type arguments"); + Location loc = (Location) $6; - prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block, - (Attributes) $1, loc); + prop = new Property (current_container, (Expression) $3, (int) $2, false, + name, (Attributes) $1, get_block, set_block, loc); + if (SimpleIteratorContainer.Simple.Yields) + prop.SetYields (); CheckDef (current_container.AddProperty (prop), prop.Name, loc); implicit_value_parameter_type = null; + iterator_container = null; } ; @@ -1111,57 +1287,43 @@ accessor_body interface_declaration : opt_attributes opt_modifiers - INTERFACE IDENTIFIER + INTERFACE member_name { Interface new_interface; - string full_interface_name = MakeName ((string) $4); + MemberName full_interface_name = MakeName ((MemberName) $4); - new_interface = new Interface (current_container, full_interface_name, (int) $2, - (Attributes) $1, lexer.Location); + new_interface = new Interface (current_namespace, current_container, full_interface_name, + (int) $2, (Attributes) $1, lexer.Location); if (current_interface != null) { Location l = lexer.Location; Report.Error (-2, l, "Internal compiler error: interface inside interface"); } current_interface = new_interface; - new_interface.Namespace = current_namespace; - RootContext.Tree.RecordDecl (full_interface_name, new_interface); + current_container = new_interface; + RootContext.Tree.RecordDecl ( + full_interface_name.GetName (true), new_interface); + lexer.ConstraintsParsing = true; + } + opt_class_base + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; } - opt_interface_base interface_body opt_semicolon { Interface new_interface = (Interface) current_interface; + CheckDef (new_interface.SetParameterInfo ((ArrayList) $7), new_interface.Name, new_interface.Location); if ($6 != null) new_interface.Bases = (ArrayList) $6; current_interface = null; + current_container = current_container.Parent; CheckDef (current_container.AddInterface (new_interface), new_interface.Name, new_interface.Location); } - ; - -opt_interface_base - : /* empty */ { $$ = null; } - | interface_base - ; - -interface_base - : COLON interface_type_list { $$ = $2; } - ; - -interface_type_list - : interface_type - { - ArrayList interfaces = new ArrayList (4); - - interfaces.Add ($1); - $$ = interfaces; - } - | interface_type_list COMMA interface_type - { - ArrayList interfaces = (ArrayList) $1; - interfaces.Add ($3); - $$ = interfaces; + | opt_attributes opt_modifiers INTERFACE error { + CheckIdentifierToken (yyToken); } ; @@ -1184,50 +1346,101 @@ interface_member_declarations interface_member_declaration : interface_method_declaration { - InterfaceMethod m = (InterfaceMethod) $1; + Method m = (Method) $1; CheckDef (current_interface.AddMethod (m), m.Name, m.Location); } | interface_property_declaration { - InterfaceProperty p = (InterfaceProperty) $1; + Property p = (Property) $1; CheckDef (current_interface.AddProperty (p), p.Name, p.Location); } | interface_event_declaration { - InterfaceEvent e = (InterfaceEvent) $1; - - CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location); + if ($1 != null){ + Event e = (Event) $1; + CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location); + } } | interface_indexer_declaration { - InterfaceIndexer i = (InterfaceIndexer) $1; + Indexer i = (Indexer) $1; - CheckDef (current_interface.AddIndexer (i), "indexer", i.Location); + current_interface.AddIndexer (i); } ; opt_new - : /* empty */ { $$ = false; } - | NEW { $$ = true; } + : opt_modifiers + { + int val = (int) $1; + val = Modifiers.Check (Modifiers.NEW | Modifiers.UNSAFE, val, 0, lexer.Location); + $$ = val; + } ; interface_method_declaration - : opt_attributes opt_new type IDENTIFIER + : opt_attributes opt_new type namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + { + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses SEMICOLON { - $$ = new InterfaceMethod ((Expression) $3, (string) $4, (bool) $2, - (Parameters) $6, (Attributes) $1, lexer.Location); + lexer.ConstraintsParsing = false; + + MemberName name = (MemberName) $4; + + if ($9 != null && name.TypeArguments == null) + Report.Error (80, lexer.Location, + "Contraints are not allowed on non-generic declarations"); + + GenericMethod generic = null; + if (name.TypeArguments != null) { + generic = new GenericMethod (current_namespace, current_container, + name, lexer.Location); + + CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + + $$ = new Method (generic, (Expression) $3, (int) $2, true, name, + (Parameters) $6, (Attributes) $1, lexer.Location); + } else + $$ = new Method (current_container, (Expression) $3, (int) $2, true, + name, (Parameters) $6, (Attributes) $1, + lexer.Location); } - | opt_attributes opt_new VOID IDENTIFIER + | opt_attributes opt_new VOID namespace_or_type_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + { + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses SEMICOLON { - $$ = new InterfaceMethod ( - TypeManager.system_void_expr, (string) $4, (bool) $2, (Parameters) $6, - (Attributes) $1, lexer.Location); + lexer.ConstraintsParsing = false; + + MemberName name = (MemberName) $4; + + if ($9 != null && name.TypeArguments == null) + Report.Error (80, lexer.Location, + "Contraints are not allowed on non-generic declarations"); + + GenericMethod generic = null; + if (name.TypeArguments != null) { + generic = new GenericMethod (current_namespace, current_container, + name, lexer.Location); + + CheckDef (generic.SetParameterInfo ((ArrayList) $9), name.Name, lexer.Location); + + $$ = new Method (generic, TypeManager.system_void_expr, (int) $2, + true, name, (Parameters) $6, (Attributes) $1, + lexer.Location); + } else + $$ = new Method (current_container, TypeManager.system_void_expr, + (int) $2, true, name, (Parameters) $6, + (Attributes) $1, lexer.Location); } ; @@ -1237,33 +1450,52 @@ interface_property_declaration type IDENTIFIER OPEN_BRACE { lexer.PropertyParsing = true; } - interface_accesors + interface_accessors { lexer.PropertyParsing = false; } CLOSE_BRACE { - int gs = (int) $7; + InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7; - $$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2, - (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1, - lexer.Location); + $$ = new Property (current_container, (Expression) $3, (int) $2, true, + new MemberName ((string) $4), (Attributes) $1, + pinfo.Get, pinfo.Set, lexer.Location); + } + | opt_attributes + opt_new + type error { + CheckIdentifierToken (yyToken); + $$ = null; } ; -interface_accesors - : opt_attributes GET SEMICOLON { $$ = 1; } - | opt_attributes SET SEMICOLON { $$ = 2; } +interface_accessors + : opt_attributes GET SEMICOLON { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null); } + | opt_attributes SET SEMICOLON { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1); } | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON - { $$ = 3; } + { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3); } | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON - { $$ = 3; } + { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1); } ; interface_event_declaration : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON { - $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1, - lexer.Location); + $$ = new EventField (current_container, (Expression) $4, (int) $2, true, + new MemberName ((string) $5), null, + (Attributes) $1, lexer.Location); + } + | opt_attributes opt_new EVENT type error { + CheckIdentifierToken (yyToken); + $$ = null; } + | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN { + Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized."); + $$ = null; + } + | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE { + Report.Error (69, lexer.Location, "Event accessors not valid on interfaces"); + $$ = null; + } ; interface_indexer_declaration @@ -1271,32 +1503,38 @@ interface_indexer_declaration OPEN_BRACKET formal_parameter_list CLOSE_BRACKET OPEN_BRACE { lexer.PropertyParsing = true; } - interface_accesors + interface_accessors { lexer.PropertyParsing = false; } CLOSE_BRACE { - int a_flags = (int) $10; + InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10; - bool do_get = (a_flags & 1) == 1; - bool do_set = (a_flags & 2) == 2; - - $$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set, - (bool) $2, (Attributes) $1, lexer.Location); + $$ = new Indexer (current_container, (Expression) $3, (int) $2, true, + MemberName.Null, (Parameters) $6, (Attributes) $1, + info.Get, info.Set, lexer.Location); } ; operator_declaration - : opt_attributes opt_modifiers operator_declarator operator_body + : opt_attributes opt_modifiers operator_declarator + { + iterator_container = SimpleIteratorContainer.GetSimple (); + } + operator_body { OperatorDeclaration decl = (OperatorDeclaration) $3; Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name, - decl.arg2type, decl.arg2name, (Block) $4, (Attributes) $1, decl.location); + decl.arg2type, decl.arg2name, (Block) $5, (Attributes) $1, decl.location); + + if (SimpleIteratorContainer.Simple.Yields) + op.SetYields (); // Note again, checking is done in semantic analysis current_container.AddOperator (op); current_local_parameters = null; + iterator_container = null; } ; @@ -1467,7 +1705,8 @@ constructor_declarator opt_constructor_initializer { Location l = (Location) oob_stack.Pop (); - $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $6, l); + $$ = new Constructor (current_container, (string) $1, 0, (Parameters) $3, + (ConstructorInitializer) $6, l); } ; @@ -1521,19 +1760,27 @@ destructor_declaration if ((m & Modifiers.UNSAFE) != 0){ if (!RootContext.Unsafe){ Report.Error (227, l, - "Unsafe code requires the --unsafe command " + + "Unsafe code requires the -unsafe command " + "line option to be specified"); } } - Method d = new Method ( - TypeManager.system_void_expr, m, "Finalize", + Method d = new Destructor ( + current_container, TypeManager.system_void_expr, m, "Finalize", new Parameters (null, null, l), (Attributes) $1, l); d.Block = (Block) $7; CheckDef (current_container.AddMethod (d), d.Name, d.Location); } } + | opt_attributes opt_modifiers EVENT type member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS block { + string mn = (string) $5; + + if (mn.IndexOf ('.') != -1) + Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax"); + else + Report.Error (71, lexer.Location, "Event declaration should use property syntax"); + } ; event_declaration @@ -1543,9 +1790,12 @@ event_declaration { foreach (VariableDeclaration var in (ArrayList) $5) { - Event e = new Event ((Expression) $4, var.identifier, - var.expression_or_array_initializer, - (int) $2, null, null, (Attributes) $1, lexer.Location); + MemberName name = new MemberName (var.identifier); + + Event e = new EventField (current_container, (Expression) $4, (int) $2, + false, name, + var.expression_or_array_initializer, + (Attributes) $1, lexer.Location); CheckDef (current_container.AddEvent (e), e.Name, e.Location); @@ -1553,7 +1803,7 @@ event_declaration } | opt_attributes opt_modifiers - EVENT type member_name + EVENT type namespace_or_type_name OPEN_BRACE { implicit_value_parameter_type = (Expression) $4; @@ -1568,21 +1818,25 @@ event_declaration { Location loc = (Location) oob_stack.Pop (); + if ($8 == null){ + Report.Error (65, lexer.Location, "Event must have both add and remove accesors"); + $$ = null; + } else { Pair pair = (Pair) $8; - Accessor add_accessor = null; - Accessor rem_accessor = null; - if (pair.First != null) - add_accessor = (Accessor) pair.First; - if (pair.Second != null) - rem_accessor = (Accessor) pair.Second; - - Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor, - (Attributes) $1, loc); + MemberName name = (MemberName) $5; + if (name.TypeArguments != null) + syntax_error (lexer.Location, "an event can't have type arguments"); + + Event e = new EventProperty (current_container, (Expression) $4, (int) $2, + false, name, null, (Attributes) $1, + (Accessor) pair.First, (Accessor) pair.Second, + loc); CheckDef (current_container.AddEvent (e), e.Name, loc); implicit_value_parameter_type = null; } + } ; event_accessor_declarations @@ -1594,6 +1848,8 @@ event_accessor_declarations { $$ = new Pair ($2, $1); } + | add_accessor_declaration { $$ = null; } + | remove_accessor_declaration { $$ = null; } ; add_accessor_declaration @@ -1674,8 +1930,15 @@ indexer_declaration Accessor get_block = (Accessor) pair.First; Accessor set_block = (Accessor) pair.Second; - indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list, - get_block, set_block, (Attributes) $1, loc); + MemberName name; + if (decl.interface_type != null) + name = new MemberName (decl.interface_type, "", null); + else + name = MemberName.Null; + + indexer = new Indexer (current_container, decl.type, (int) $2, false, + name, decl.param_list, (Attributes) $1, + get_block, set_block, loc); // Note that there is no equivalent of CheckDef for this case // We shall handle this in semantic analysis @@ -1699,14 +1962,18 @@ indexer_declarator $$ = new IndexerDeclaration ((Expression) $1, null, pars); } - | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET + | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET { Parameters pars = (Parameters) $6; if (pars.FixedParameters == null && pars.ArrayParameter == null){ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter"); } - $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars); + MemberName name = (MemberName) $2; + if (name.TypeArguments != null) + syntax_error (lexer.Location, "an indexer can't have type arguments"); + + $$ = new IndexerDeclaration ((Expression) $1, name, pars); } ; @@ -1720,9 +1987,9 @@ enum_declaration { Location enum_location = lexer.Location; - string full_name = MakeName ((string) $4); - Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name, - (Attributes) $1, enum_location); + MemberName full_name = MakeName (new MemberName ((string) $4)); + Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2, + full_name, (Attributes) $1, enum_location); foreach (VariableDeclaration ev in (ArrayList) $6) { Location loc = (Location) ev.Location; @@ -1733,10 +2000,9 @@ enum_declaration ev.identifier, loc); } - e.Namespace = current_namespace; - - CheckDef (current_container.AddEnum (e), full_name, enum_location); - RootContext.Tree.RecordDecl (full_name, e); + string name = full_name.GetName (false); + CheckDef (current_container.AddEnum (e), name, enum_location); + RootContext.Tree.RecordDecl (name, e); } ; @@ -1794,74 +2060,83 @@ enum_member_declaration delegate_declaration : opt_attributes opt_modifiers - DELEGATE type - IDENTIFIER OPEN_PARENS - opt_formal_parameter_list - CLOSE_PARENS - SEMICOLON + DELEGATE type member_name + OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { Location l = lexer.Location; - Delegate del = new Delegate (current_container, (Expression) $4, (int) $2, - MakeName ((string) $5), (Parameters) $7, - (Attributes) $1, l); + Delegate del = new Delegate ( + current_namespace, current_container, (Expression) $4, (int) $2, + MakeName ((MemberName) $5), (Parameters) $7, (Attributes) $1, l); - del.Namespace = current_namespace; CheckDef (current_container.AddDelegate (del), del.Name, l); - } + + current_delegate = del; + + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + } + SEMICOLON + { + CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location); + + current_delegate = null; + } | opt_attributes opt_modifiers - DELEGATE VOID - IDENTIFIER OPEN_PARENS - opt_formal_parameter_list - CLOSE_PARENS - SEMICOLON + DELEGATE VOID member_name + OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { Location l = lexer.Location; Delegate del = new Delegate ( - current_container, - TypeManager.system_void_expr, (int) $2, MakeName ((string) $5), + current_namespace, current_container, + TypeManager.system_void_expr, (int) $2, MakeName ((MemberName) $5), (Parameters) $7, (Attributes) $1, l); - del.Namespace = current_namespace; CheckDef (current_container.AddDelegate (del), del.Name, l); + + current_delegate = del; + + lexer.ConstraintsParsing = true; } - ; + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + } + SEMICOLON + { + CheckDef (current_delegate.SetParameterInfo ((ArrayList) $9), current_delegate.Name, current_delegate.Location); -type_name - : namespace_or_type_name + current_delegate = null; + } ; namespace_or_type_name - : IDENTIFIER opt_type_argument_list { - if ($2 == null) - $$ = new SimpleName ((string) $1, lexer.Location); - else - $$ = new ConstructedType ((string) $1, (TypeArguments) $2, lexer.Location); + : member_name + | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list { + $$ = new MemberName ((MemberName) $1, (string) $3, (TypeArguments) $4); } - | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list - { - Expression right; + ; - // - // Third argument will become an Expression, when we have sorted out - // the issues with SimpleName first - // - $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location); +member_name + : IDENTIFIER opt_type_argument_list { + $$ = new MemberName ((string) $1, (TypeArguments) $2); } ; -// -// TODO: -// Figure out what to do with the list -// opt_type_argument_list : /* empty */ { $$ = null; } - | OP_GENERICS_LT type_arguments OP_GT { $$ = $2; } + | OP_GENERICS_LT type_arguments OP_GENERICS_GT + { + $$ = $2; + } ; type_arguments : type { - TypeArguments type_args = new TypeArguments (); + TypeArguments type_args = new TypeArguments (lexer.Location); type_args.Add ((Expression) $1); $$ = type_args; } @@ -1879,7 +2154,9 @@ type_arguments * gets rid of a shift/reduce couple */ type - : type_name { /* class_type */ + : namespace_or_type_name + { + $$ = ((MemberName) $1).GetTypeExpression (lexer.Location); } | builtin_types | array_type @@ -1976,10 +2253,6 @@ integral_type | VOID { $$ = TypeManager.system_void_expr; } ; -interface_type - : type_name - ; - array_type : type rank_specifiers { @@ -1996,14 +2269,12 @@ primary_expression // 7.5.1: Literals } - | qualified_identifier + | member_name { - string name = (string) $1; - - $$ = null; - $$ = DecomposeQI (name, lexer.Location); + $$ = ((MemberName) $1).GetTypeExpression (lexer.Location); } | parenthesized_expression + | default_value_expression | member_access | invocation_expression | element_access @@ -2039,9 +2310,16 @@ integer_literal : LITERAL_INTEGER { object v = lexer.Value; - if (v is int) - $$ = new IntLiteral ((Int32) v); - else if (v is uint) + if (v is int){ + int i = (int) v; + + if (i == 0) + $$ = IntLiteral.Zero; + else if (i == 1) + $$ = IntLiteral.One; + else + $$ = new IntLiteral (i); + } else if (v is uint) $$ = new UIntLiteral ((UInt32) v); else if (v is long) $$ = new LongLiteral ((Int64) v); @@ -2057,19 +2335,41 @@ boolean_literal | FALSE { $$ = new BoolLiteral (false); } ; -parenthesized_expression +parenthesized_expression_0 : OPEN_PARENS expression CLOSE_PARENS - { $$ = $2; } + { + $$ = $2; + lexer.Deambiguate_CloseParens (); + // After this, the next token returned is one of + // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS + // or CLOSE_PARENS_MINUS. + } ; +parenthesized_expression + : parenthesized_expression_0 CLOSE_PARENS_NO_CAST + { + $$ = $1; + } + | parenthesized_expression_0 CLOSE_PARENS_MINUS + { + // If a parenthesized expression is followed by a minus, we need to wrap + // the expression inside a ParenthesizedExpression for the CS0075 check + // in Binary.DoResolve(). + $$ = new ParenthesizedExpression ((Expression) $1, lexer.Location); + } + ;; + member_access - : primary_expression DOT IDENTIFIER + : primary_expression DOT IDENTIFIER opt_type_argument_list { - $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location); + $$ = new MemberAccess ((Expression) $1, (string) $3, + (TypeArguments) $4, lexer.Location); } - | predefined_type DOT IDENTIFIER + | predefined_type DOT IDENTIFIER opt_type_argument_list { - $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location); + $$ = new MemberAccess ((Expression) $1, (string) $3, + (TypeArguments) $4, lexer.Location); } ; @@ -2086,9 +2386,13 @@ invocation_expression } $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location); } - | OPEN_PARENS expression CLOSE_PARENS unary_expression + | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS + { + $$ = new Invocation ((Expression) $1, new ArrayList (), lexer.Location); + } + | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression { - $$ = new InvocationOrCast ((Expression) $2, (Expression) $4, lexer.Location); + $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location); } ; @@ -2110,6 +2414,9 @@ argument_list list.Add ($3); $$ = list; } + | argument_list error { + CheckToken (1026, yyToken, ", or ) expected"); + } ; argument @@ -2125,6 +2432,19 @@ argument { $$ = new Argument ((Expression) $2, Argument.AType.Out); } + | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS + { + ArrayList list = (ArrayList) $3; + Argument[] args = new Argument [list.Count]; + list.CopyTo (args, 0); + + Expression expr = new Arglist (args, lexer.Location); + $$ = new Argument (expr, Argument.AType.Expression); + } + | ARGLIST + { + $$ = new Argument (new ArglistAccess (lexer.Location), Argument.AType.ArgList); + } ; variable_reference @@ -2144,11 +2464,11 @@ element_access // Foo.Bar.Blah i; // SimpleName is when you have // Blah i; - + Expression expr = (Expression) $1; if (expr is ComposedCast){ $$ = new ComposedCast (expr, (string) $2, lexer.Location); - } else if (!(expr is SimpleName || expr is MemberAccess)){ + } else if (!(expr is SimpleName || expr is MemberAccess || expr is ConstructedType)){ Error_ExpectingTypeName (lexer.Location, expr); $$ = TypeManager.system_object_expr; } else { @@ -2192,6 +2512,10 @@ base_access { $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location); } + | BASE error { + Report.Error (175, "Use of keyword `base' is not valid in this context"); + $$ = null; + } ; post_increment_expression @@ -2369,13 +2693,21 @@ anonymous_method_expression : DELEGATE opt_anonymous_method_signature { oob_stack.Push (current_local_parameters); current_local_parameters = (Parameters)$2; + create_toplevel_block = true; } block { - if (!RootContext.V2){ - Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2"); + if (true){ + Report.Error (-213, lexer.Location, "Anonymous methods are not supported in this branch"); $$ = null; - } else - $$ = new AnonymousMethod ((Parameters) $2, (Block) $3, lexer.Location); - current_local_parameters = (Parameters) oob_stack.Pop (); + } else { + create_toplevel_block = false; + Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2"); + if (!RootContext.V2){ + Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2"); + $$ = null; + } else + $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location); + current_local_parameters = (Parameters) oob_stack.Pop (); + } } ; @@ -2424,6 +2756,13 @@ anonymous_method_parameter } ; +default_value_expression + : DEFAULT_OPEN_PARENS type CLOSE_PARENS + { + $$ = new DefaultValueExpression ((Expression) $2, lexer.Location); + } + ; + unary_expression : primary_expression | BANG prefixed_unary_expression @@ -2437,10 +2776,22 @@ unary_expression | cast_expression ; +cast_list + : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression + { + $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location); + } + | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression + { + $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location); + } + ; + cast_expression - : OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression + : cast_list + | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression { - $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location); + $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location); } ; @@ -2736,49 +3087,42 @@ boolean_expression class_declaration : opt_attributes opt_modifiers - CLASS IDENTIFIER + CLASS member_name { Class new_class; - string name; - name = MakeName ((string) $4); + MemberName name = MakeName ((MemberName) $4); - new_class = new Class (current_container, name, (int) $2, + new_class = new Class (current_namespace, current_container, name, (int) $2, (Attributes) $1, lexer.Location); current_container = new_class; - current_container.Namespace = current_namespace; - RootContext.Tree.RecordDecl (name, new_class); + RootContext.Tree.RecordDecl (name.GetName (true), new_class); + + lexer.ConstraintsParsing = true; } - opt_type_parameter_list opt_class_base opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + } class_body opt_semicolon { Class new_class = (Class) current_container; - if ($8 != null && $6 == null) - Report.Error (-200, new_class.Location, - "Type parameter constraints only valid if there is a type parameter list"); + CheckDef (new_class.SetParameterInfo ((ArrayList) $7), new_class.Name, new_class.Location); + if ($6 != null) { + if (new_class.Name == "System.Object") { + Report.Error (537, new_class.Location, "The class System.Object cannot have a base class or implement an interface."); + } - if ($6 != null) - CheckDef (new_class.SetParameterInfo ((ArrayList) $6, $8), new_class.Name, new_class.Location); - if ($7 != null) - new_class.Bases = (ArrayList) $7; + new_class.Bases = (ArrayList) $6; + } current_container = current_container.Parent; CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location); $$ = new_class; } - | opt_attributes - opt_modifiers - CLASS IDENTIFIER - WHERE { - Report.Error (-200, lexer.Location, - "Type parameter constraints only valid if there is a type parameter list"); - yyErrorFlag = 0; - $$ = null; - } ; opt_modifiers @@ -2827,37 +3171,6 @@ class_base : COLON type_list { $$ = $2; } ; -opt_type_parameter_list - : /* empty */ { $$ = null; } - | type_parameter_list { $$ = $1; } - ; - -type_parameter_list - : OP_LT type_parameters OP_GT { $$ = $2; } - ; - -type_parameters - : type_parameter { - // - // Do some profiling to find the optimal size, for now we - // assume most people will be generic on one type (saves space - // - ArrayList type_parameters = new ArrayList (1); - type_parameters.Add ($1); - $$ = type_parameters; - } - | type_parameters COMMA type_parameter { - ArrayList type_parameters = (ArrayList) $1; - - type_parameters.Add ($3); - $$ = type_parameters; - } - ; - -type_parameter - : IDENTIFIER - ; - opt_type_parameter_constraints_clauses : /* empty */ { $$ = null; } | type_parameter_constraints_clauses @@ -2865,35 +3178,52 @@ opt_type_parameter_constraints_clauses ; type_parameter_constraints_clauses - : type_parameter_constraints_clause - | type_parameter_constraints_clauses type_parameter_constraints_clause + : type_parameter_constraints_clause { + ArrayList constraints = new ArrayList (1); + constraints.Add ($1); + $$ = constraints; + } + | type_parameter_constraints_clauses type_parameter_constraints_clause { + ArrayList constraints = (ArrayList) $1; + + constraints.Add ($2); + $$ = constraints; + } ; type_parameter_constraints_clause - : WHERE type_parameter COLON type_parameter_constraints { - $$ = new Constraints ((string) $2, (ArrayList) $4); + : WHERE IDENTIFIER COLON type_parameter_constraints { + $$ = new Constraints ((string) $2, (ArrayList) $4, lexer.Location); } ; type_parameter_constraints - : type { + : type_parameter_constraint { ArrayList constraints = new ArrayList (1); constraints.Add ($1); $$ = constraints; } - | NEW OPEN_PARENS CLOSE_PARENS { - ArrayList constraints = new ArrayList (1); - constraints.Add (true); - $$ = constraints; - } - | type_parameter_constraints COMMA type { + | type_parameter_constraints COMMA type_parameter_constraint { ArrayList constraints = (ArrayList) $1; constraints.Add ($3); $$ = constraints; - } + } ; - + +type_parameter_constraint + : type + | NEW OPEN_PARENS CLOSE_PARENS { + $$ = SpecialConstraint.Constructor; + } + | CLASS { + $$ = SpecialConstraint.ReferenceType; + } + | STRUCT { + $$ = SpecialConstraint.ValueType; + } + ; + // // Statements (8.2) // @@ -2910,8 +3240,12 @@ type_parameter_constraints block : OPEN_BRACE { + if (current_block == null || create_toplevel_block){ + current_block = new ToplevelBlock (current_local_parameters, lexer.Location); + } else { current_block = new Block (current_block, current_local_parameters, lexer.Location, Location.Null); + } } opt_statement_list CLOSE_BRACE { @@ -2941,17 +3275,14 @@ statement current_block = (Block) $1; } } - | embedded_statement + | valid_declaration_statement { - Statement s = (Statement) $1; - - current_block.AddStatement ((Statement) $1); } | labeled_statement ; -embedded_statement +valid_declaration_statement : block | empty_statement | expression_statement @@ -2967,10 +3298,24 @@ embedded_statement | fixed_statement ; +embedded_statement + : valid_declaration_statement + | declaration_statement + { + Report.Error (1023, lexer.Location, "An embedded statement may not be a declaration."); + $$ = null; + } + | labeled_statement + { + Report.Error (1023, lexer.Location, "An embedded statement may not be a labeled statement."); + $$ = null; + } + ; + empty_statement : SEMICOLON { - $$ = new EmptyStatement (); + $$ = EmptyStatement.Value; } ; @@ -2979,11 +3324,8 @@ labeled_statement { LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location); - if (!current_block.AddLabel ((string) $1, labeled)){ - Location l = lexer.Location; - Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate"); - } - current_block.AddStatement (labeled); + if (current_block.AddLabel ((string) $1, labeled, lexer.Location)) + current_block.AddStatement (labeled); } statement ; @@ -3003,7 +3345,7 @@ declaration_statement if ($1 != null){ DictionaryEntry de = (DictionaryEntry) $1; - $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value); + $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value); } } ; @@ -3022,7 +3364,7 @@ local_variable_type // Ok, the above "primary_expression" is there to get rid of // both reduce/reduce and shift/reduces in the grammar, it should // really just be "type_name". If you use type_name, a reduce/reduce - // creeps up. If you use qualified_identifier (which is all we need + // creeps up. If you use namespace_or_type_name (which is all we need // really) two shift/reduces appear. // @@ -3034,7 +3376,7 @@ local_variable_type // Blah i; Expression expr = (Expression) $1; - if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) { + if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) { Error_ExpectingTypeName (lexer.Location, expr); $$ = null; } else { @@ -3064,7 +3406,7 @@ local_variable_pointer_type Expression expr = (Expression) $1; Location l = lexer.Location; - if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) { + if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast || expr is ConstructedType)) { Error_ExpectingTypeName (l, expr); $$ = null; @@ -3109,7 +3451,7 @@ local_variable_declaration ; local_constant_declaration - : CONST local_variable_type constant_declarator + : CONST local_variable_type constant_declarators { if ($2 != null) $$ = new DictionaryEntry ($2, $3); @@ -3176,7 +3518,7 @@ if_statement_rest $$ = new If ((Expression) $1, (Statement) $3, l); if (RootContext.WarningLevel >= 3){ - if ($3 is EmptyStatement) + if ($3 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); } @@ -3298,7 +3640,7 @@ while_statement $$ = new While ((Expression) $4, (Statement) $6, l); if (RootContext.WarningLevel >= 3){ - if ($6 is EmptyStatement) + if ($6 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); } } @@ -3373,7 +3715,7 @@ for_statement For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l); if (RootContext.WarningLevel >= 3){ - if ($10 is EmptyStatement) + if ($10 == EmptyStatement.Value) Report.Warning (642, lexer.Location, "Possibly mistaken empty statement"); } @@ -3386,7 +3728,7 @@ for_statement ; opt_for_initializer - : /* empty */ { $$ = new EmptyStatement (); } + : /* empty */ { $$ = EmptyStatement.Value; } | for_initializer ; @@ -3401,7 +3743,7 @@ opt_for_condition ; opt_for_iterator - : /* empty */ { $$ = new EmptyStatement (); } + : /* empty */ { $$ = EmptyStatement.Value; } | for_iterator ; @@ -3436,7 +3778,7 @@ foreach_statement { oob_stack.Push (current_block); - Block foreach_block = new Block (current_block, Block.Flags.Implicit); + Block foreach_block = new Block (current_block); LocalVariableReference v = null; Location l = lexer.Location; LocalInfo vi; @@ -3524,18 +3866,36 @@ throw_statement ; yield_statement - : YIELD expression SEMICOLON + : IDENTIFIER RETURN expression SEMICOLON { + string s = (string) $1; + if (s != "yield"){ + Report.Error (1003, lexer.Location, "; expected"); + $$ = null; + } + if (!RootContext.V2){ + Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode"); + $$ = null; + } if (iterator_container == null){ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property"); $$ = null; } else { iterator_container.SetYields (); - $$ = new Yield ((Expression) $2, lexer.Location); + $$ = new Yield ((Expression) $3, lexer.Location); } } - | YIELD BREAK SEMICOLON + | IDENTIFIER BREAK SEMICOLON { + string s = (string) $1; + if (s != "yield"){ + Report.Error (1003, lexer.Location, "; expected"); + $$ = null; + } + if (!RootContext.V2){ + Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode"); + $$ = null; + } if (iterator_container == null){ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property"); $$ = null; @@ -3733,10 +4093,7 @@ fixed_statement embedded_statement { Location l = (Location) oob_stack.Pop (); - Block assign_block = (Block) oob_stack.Pop (); - - ArrayList list = (ArrayList) $4; - int top = list.Count; + oob_stack.Pop (); $$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l); } @@ -3865,16 +4222,34 @@ public class VariableDeclaration { } } +/// +/// Used to pass around interface property information +/// +public class InterfaceAccessorInfo { + + public readonly Accessor Get, Set; + + public InterfaceAccessorInfo (bool has_get, bool has_set, + Attributes get_attrs, Attributes set_attrs) + { + if (has_get) + Get = new Accessor (null, get_attrs); + if (has_set) + Set = new Accessor (null, set_attrs); + } +} + + // // A class used to hold info about an indexer declarator // - public class IndexerDeclaration { public Expression type; - public string interface_type; + public MemberName interface_type; public Parameters param_list; - public IndexerDeclaration (Expression type, string interface_type, Parameters param_list) + public IndexerDeclaration (Expression type, MemberName interface_type, + Parameters param_list) { this.type = type; this.interface_type = interface_type; @@ -3882,10 +4257,28 @@ public class IndexerDeclaration { } } +// +// We use this when we do not have an object in advance that is an IIteratorContainer +// +public class SimpleIteratorContainer : IIteratorContainer { + public bool Yields; + + public static SimpleIteratorContainer Simple = new SimpleIteratorContainer (); + + // + // Reset and return + // + public static SimpleIteratorContainer GetSimple () { + Simple.Yields = false; + return Simple; + } + + public void SetYields () { Yields = true; } +} + // // A class used to hold info about an operator declarator // - public class OperatorDeclaration { public Operator.OpType optype; public Expression ret_type, arg1type, arg2type; @@ -3920,19 +4313,19 @@ void Error_ExpectingTypeName (Location l, Expression expr) // Given the @class_name name, it creates a fully qualified name // based on the containing declaration space // -string -MakeName (string class_name) +MemberName +MakeName (MemberName class_name) { - string ns = current_namespace.Name; - string container_name = current_container.Name; + string ns = current_namespace.FullName; - if (container_name == ""){ + if (current_container.Name == ""){ if (ns != "") - return ns + "." + class_name; + return new MemberName (new MemberName (ns), class_name); else return class_name; - } else - return container_name + "." + class_name; + } else { + return new MemberName (current_container.MemberName, class_name); + } } // @@ -3940,13 +4333,13 @@ MakeName (string class_name) // in the current declaration space // void -CheckDef (AdditionResult result, string name, Location l) +CheckDef (DeclSpace.AdditionResult result, string name, Location l) { - if (result == AdditionResult.Success) + if (result == DeclSpace.AdditionResult.Success) return; switch (result){ - case AdditionResult.NameExists: + case DeclSpace.AdditionResult.NameExists: Report.Error (102, l, "The container `" + current_container.Name + "' already contains a definition for `"+ name + "'"); @@ -3957,22 +4350,22 @@ CheckDef (AdditionResult result, string name, Location l) // This is handled only for static Constructors, because // in reality we handle these by the semantic analysis later // - case AdditionResult.MethodExists: + case DeclSpace.AdditionResult.MethodExists: Report.Error ( 111, l, "Class `"+current_container.Name+ "' already defines a member called '" + name + "' with the same parameter types (more than one default constructor)"); break; - case AdditionResult.EnclosingClash: + case DeclSpace.AdditionResult.EnclosingClash: Report.Error (542, l, "Member names cannot be the same as their enclosing type"); break; - case AdditionResult.NotAConstructor: + case DeclSpace.AdditionResult.NotAConstructor: Report.Error (1520, l, "Class, struct, or interface method must have a return type"); break; - case AdditionResult.Error: + case DeclSpace.AdditionResult.Error: // Error has already been reported. break; } @@ -3983,24 +4376,7 @@ CheckDef (bool result, string name, Location l) { if (result) return; - CheckDef (AdditionResult.NameExists, name, l); -} - -Expression DecomposeQI (string name, Location loc) -{ - Expression o; - - if (name.IndexOf ('.') == -1){ - return new SimpleName (name, loc); - } else { - int pos = name.LastIndexOf ("."); - string left = name.Substring (0, pos); - string right = name.Substring (pos + 1); - - o = DecomposeQI (left, loc); - - return new MemberAccess (o, right, loc); - } + CheckDef (DeclSpace.AdditionResult.NameExists, name, l); } Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc) @@ -4023,10 +4399,9 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, // // int j = 1; int k = j + 1; // - if (current_block.Used) { + if (current_block.Used) implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null); - implicit_block.AddChildVariableNames (current_block); - } else + else implicit_block = current_block; foreach (VariableDeclaration decl in variable_declarators){ @@ -4067,7 +4442,7 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, return implicit_block; } -Block declare_local_constant (Expression type, VariableDeclaration decl) +Block declare_local_constants (Expression type, ArrayList declarators) { Block implicit_block; @@ -4076,8 +4451,9 @@ Block declare_local_constant (Expression type, VariableDeclaration decl) else implicit_block = current_block; - if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, - current_local_parameters, decl.Location))){ + foreach (VariableDeclaration decl in declarators){ + implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer, + current_local_parameters, decl.Location); } return implicit_block; @@ -4087,7 +4463,7 @@ void CheckAttributeTarget (string a) { switch (a) { - case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" : + case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" : return; default : @@ -4174,13 +4550,13 @@ public Tokenizer Lexer { } } -public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines) +public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines) { - current_namespace = new NamespaceEntry (null, file, null); + current_namespace = new NamespaceEntry (null, file, null, Location.Null); this.name = file.Name; this.file = file; current_container = RootContext.Tree.Types; - current_container.Namespace = current_namespace; + current_container.NamespaceEntry = current_namespace; oob_stack = new Stack (); switch_stack = new Stack (); @@ -4200,10 +4576,26 @@ public void parse () // Please do not remove this, it is used during debugging // of the grammar // - Report.Error (-25, lexer.Location, ": Parsing error "); Console.WriteLine (e); + Report.Error (-25, lexer.Location, "Parsing error"); + if (Driver.parser_verbose) + Console.WriteLine (e); } } +void CheckToken (int error, int yyToken, string msg) +{ + if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){ + Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ())); + return; + } + Report.Error (error, lexer.Location, msg); +} + +void CheckIdentifierToken (int yyToken) +{ + CheckToken (1041, yyToken, "Identifier expected"); +} + /* end end end */ }