X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=b30fc6224fb72f9df45ced19615d85b20bd2c59c;hb=0c2bb8157f43826a57c39b863a1d67e3aef1b7b2;hp=84a2f5b3d13c87047b4a607a157af2ae11ea53b6;hpb=9e47982d145cecbca7ff7b563e14e9cb859797b8;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 84a2f5b3d13..b30fc6224fb 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -55,7 +55,7 @@ namespace Mono.CSharp // FIXME: This is very ugly and it's very hard to reset it correctly // on all places, especially when some parameters are autogenerated. - Parameters current_local_parameters; + ParametersCompiled current_local_parameters; /// /// Using during property parsing to describe the implicit @@ -63,7 +63,7 @@ namespace Mono.CSharp /// methods (properties and indexers). /// FullNamedExpression implicit_value_parameter_type; - Parameters indexer_parameters; + ParametersCompiled indexer_parameters; /// /// Hack to help create non-typed array initializer @@ -119,9 +119,9 @@ namespace Mono.CSharp bool global_attrs_enabled = true; bool has_get, has_set; bool parameter_modifiers_not_allowed; - bool params_modifiers_not_allowed; + bool complex_parameters_modifiers_not_allowed; bool arglist_allowed; - + bool default_parameter_used; /// When using the interactive parser, this holds the /// resulting expression @@ -131,6 +131,9 @@ namespace Mono.CSharp // Keeps track of global data changes to undo on parser error // public Undo undo; + + // Stack + Stack linq_clause_blocks; // A counter to create new class names in interactive mode static int class_count; @@ -148,7 +151,6 @@ namespace Mono.CSharp %token ABSTRACT %token AS %token ADD -%token ASSEMBLY %token BASE %token BOOL %token BREAK @@ -229,8 +231,8 @@ namespace Mono.CSharp %token ARGLIST %token PARTIAL %token ARROW -%token QUERY_FIRST_TOKEN %token FROM +%token FROM_FIRST %token JOIN %token ON %token EQUALS @@ -242,83 +244,84 @@ namespace Mono.CSharp %token ASCENDING %token DESCENDING %token INTO -%token QUERY_LAST_TOKEN +%token INTERR_NULLABLE +%token EXTERN_ALIAS + +/* Generics <,> tokens */ +%token OP_GENERICS_LT +%token OP_GENERICS_LT_DECL +%token OP_GENERICS_GT /* C# keywords which are not really keywords */ -%token GET "get" -%token SET "set" +%token GET +%token SET %left LAST_KEYWORD /* C# single character operators/punctuation. */ -%token OPEN_BRACE "{" -%token CLOSE_BRACE "}" -%token OPEN_BRACKET "[" -%token CLOSE_BRACKET "]" -%token OPEN_PARENS "(" -%token CLOSE_PARENS ")" -%token DOT "." -%token COMMA "," -%token COLON ":" -%token SEMICOLON ";" -%token TILDE "~" - -%token PLUS "+" -%token MINUS "-" -%token BANG "!" -%token ASSIGN "=" -%token OP_LT "<" -%token OP_GENERICS_LT "<" -%token OP_GT ">" -%token OP_GENERICS_GT ">" -%token BITWISE_AND "&" -%token BITWISE_OR "|" -%token STAR "*" -%token PERCENT "%" -%token DIV "/" -%token CARRET "^" -%token INTERR "?" +%token OPEN_BRACE +%token CLOSE_BRACE +%token OPEN_BRACKET +%token CLOSE_BRACKET +%token OPEN_PARENS +%token CLOSE_PARENS + +%token DOT +%token COMMA +%token COLON +%token SEMICOLON +%token TILDE + +%token PLUS +%token MINUS +%token BANG +%token ASSIGN +%token OP_LT +%token OP_GT +%token BITWISE_AND +%token BITWISE_OR +%token STAR +%token PERCENT +%token DIV +%token CARRET +%token INTERR /* C# multi-character operators. */ -%token DOUBLE_COLON "::" -%token OP_INC "++" -%token OP_DEC "--" -%token OP_SHIFT_LEFT "<<" -%token OP_SHIFT_RIGHT ">>" -%token OP_LE "<=" -%token OP_GE ">=" -%token OP_EQ "==" -%token OP_NE "!=" -%token OP_AND "&&" -%token OP_OR "||" -%token OP_MULT_ASSIGN "*=" -%token OP_DIV_ASSIGN "/=" -%token OP_MOD_ASSIGN "%=" -%token OP_ADD_ASSIGN "+=" -%token OP_SUB_ASSIGN "-=" -%token OP_SHIFT_LEFT_ASSIGN "<<=" -%token OP_SHIFT_RIGHT_ASSIGN ">>=" -%token OP_AND_ASSIGN "&=" -%token OP_XOR_ASSIGN "^=" -%token OP_OR_ASSIGN "|=" -%token OP_PTR "->" -%token OP_COALESCING "??" +%token DOUBLE_COLON +%token OP_INC +%token OP_DEC +%token OP_SHIFT_LEFT +%token OP_SHIFT_RIGHT +%token OP_LE +%token OP_GE +%token OP_EQ +%token OP_NE +%token OP_AND +%token OP_OR +%token OP_MULT_ASSIGN +%token OP_DIV_ASSIGN +%token OP_MOD_ASSIGN +%token OP_ADD_ASSIGN +%token OP_SUB_ASSIGN +%token OP_SHIFT_LEFT_ASSIGN +%token OP_SHIFT_RIGHT_ASSIGN +%token OP_AND_ASSIGN +%token OP_XOR_ASSIGN +%token OP_OR_ASSIGN +%token OP_PTR +%token OP_COALESCING /* Numbers */ -%token LITERAL_INTEGER "int literal" -%token LITERAL_FLOAT "float literal" -%token LITERAL_DOUBLE "double literal" -%token LITERAL_DECIMAL "decimal literal" -%token LITERAL_CHARACTER "character literal" -%token LITERAL_STRING "string literal" +%token LITERAL_INTEGER +%token LITERAL_FLOAT +%token LITERAL_DOUBLE +%token LITERAL_DECIMAL +%token LITERAL_CHARACTER +%token LITERAL_STRING %token IDENTIFIER %token OPEN_PARENS_LAMBDA -%token CLOSE_PARENS_CAST -%token CLOSE_PARENS_NO_CAST -%token CLOSE_PARENS_OPEN_PARENS -%token CLOSE_PARENS_MINUS -%token DEFAULT_OPEN_PARENS +%token OPEN_PARENS_CAST %token GENERIC_DIMENSION %token DEFAULT_COLON @@ -327,11 +330,25 @@ namespace Mono.CSharp %token EVAL_COMPILATION_UNIT_PARSER %token EVAL_USING_DECLARATIONS_UNIT_PARSER +// +// This token is generated to trigger the completion engine at this point +// +%token GENERATE_COMPLETION + +// +// This token is return repeatedly after the first GENERATE_COMPLETION +// token is produced and before the final EOF +// +%token COMPLETE_COMPLETION + /* Add precedence rules to solve dangling else s/r conflict */ -%nonassoc LOWPREC %nonassoc IF %nonassoc ELSE + +/* Define the operator tokens and their precedences */ %right ASSIGN +%right OP_COALESCING +%right INTERR %left OP_OR %left OP_AND %left BITWISE_OR @@ -344,7 +361,6 @@ namespace Mono.CSharp %left OPEN_PARENS %left OPEN_BRACKET OPEN_BRACE %left DOT -%nonassoc HIGHPREC %start compilation_unit %% @@ -354,7 +370,7 @@ compilation_unit | outer_declarations global_attributes opt_EOF | global_attributes opt_EOF | opt_EOF /* allow empty files */ - | interactive_parsing opt_EOF + | interactive_parsing { Lexer.CompleteOnEOF = false; } opt_EOF ; opt_EOF @@ -369,27 +385,28 @@ opt_EOF ; outer_declarations - : outer_declaration - | outer_declarations outer_declaration - ; + : outer_declaration + | outer_declarations outer_declaration + ; outer_declaration : extern_alias_directive - | using_directive - | namespace_member_declaration - ; + | using_directive + | namespace_member_declaration + ; extern_alias_directives : extern_alias_directive - | extern_alias_directives extern_alias_directive; + | extern_alias_directives extern_alias_directive + ; extern_alias_directive - : EXTERN IDENTIFIER IDENTIFIER SEMICOLON + : EXTERN_ALIAS IDENTIFIER IDENTIFIER SEMICOLON { LocatedToken lt = (LocatedToken) $2; string s = lt.Value; if (s != "alias"){ - Report.Error (1003, lt.Location, "'alias' expected"); + syntax_error (lt.Location, "`alias' expected"); } else if (RootContext.Version == LanguageVersion.ISO_1) { Report.FeatureIsNotAvailable (lt.Location, "external alias"); } else { @@ -397,6 +414,10 @@ extern_alias_directive current_namespace.AddUsingExternalAlias (lt.Value, lt.Location); } } + | EXTERN_ALIAS error + { + syntax_error (GetLocation ($1), "`alias' expected"); // TODO: better + } ; using_directives @@ -418,8 +439,7 @@ using_directive ; using_alias_directive - : USING IDENTIFIER ASSIGN - namespace_or_type_name SEMICOLON + : USING IDENTIFIER ASSIGN namespace_or_type_name SEMICOLON { LocatedToken lt = (LocatedToken) $2; current_namespace.AddUsingAlias (lt.Value, (MemberName) $4, (Location) $1); @@ -492,7 +512,8 @@ opt_comma ; namespace_name - : namespace_or_type_name { + : namespace_or_type_name + { MemberName name = (MemberName) $1; if (name.TypeArguments != null) @@ -526,7 +547,7 @@ namespace_body_body opt_namespace_member_declarations EOF { - Report.Error (1513, lexer.Location, "} expected"); + Report.Error (1513, lexer.Location, "Expected `}'"); } ; @@ -577,8 +598,8 @@ namespace_member_declaration type_declaration : class_declaration - | struct_declaration - | interface_declaration + | struct_declaration + | interface_declaration | enum_declaration | delegate_declaration // @@ -596,20 +617,20 @@ type_declaration global_attributes : attribute_sections -{ - if ($1 != null) { - Attributes attrs = (Attributes)$1; - if (global_attrs_enabled) { - CodeGen.Assembly.AddAttributes (attrs.Attrs); - } else { - foreach (Attribute a in attrs.Attrs) { - Report.Error (1730, a.Location, "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations"); + { + if ($1 != null) { + Attributes attrs = (Attributes)$1; + if (global_attrs_enabled) { + CodeGen.Assembly.AddAttributes (attrs.Attrs); + } else { + foreach (Attribute a in attrs.Attrs) { + Report.Error (1730, a.Location, "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations"); + } } } - } - - $$ = $1; -} + $$ = $1; + } + ; opt_attributes : /* empty */ @@ -633,7 +654,7 @@ attribute_sections if (global_attrs_enabled) { if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); + current_container.Module.AddAttributes (sect); $$ = null; } else if (current_attr_target != null && current_attr_target.Length > 0) { CodeGen.Assembly.AddAttributes (sect); @@ -664,7 +685,7 @@ attribute_sections if (global_attrs_enabled) { if (current_attr_target == "module") { - CodeGen.Module.AddAttributes (sect); + current_container.Module.AddAttributes (sect); $$ = null; } else if (current_attr_target == "assembly") { CodeGen.Assembly.AddAttributes (sect); @@ -694,7 +715,7 @@ attribute_section { $$ = $3; } - | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET + | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET { $$ = $2; } @@ -718,7 +739,7 @@ attribute_target | RETURN { $$ = "return"; } | error { - string name = yyNames [yyToken].ToLower (); + string name = GetTokenName (yyToken); $$ = CheckAttributeTarget (name, GetLocation ($1)); } ; @@ -742,15 +763,20 @@ attribute_list ; attribute - : attribute_name opt_attribute_arguments + : attribute_name + { + ++lexer.parsing_block; + } + opt_attribute_arguments { + --lexer.parsing_block; MemberName mname = (MemberName) $1; if (mname.IsGeneric) { Report.Error (404, lexer.Location, "'<' unexpected: attributes cannot be generic"); } - object [] arguments = (object []) $2; + object [] arguments = (object []) $3; MemberName left = mname.Left; string identifier = mname.Name; @@ -837,12 +863,12 @@ named_argument_list $$ = args; } - | named_argument_list COMMA expression - { - Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected"); - $$ = null; - } - ; + | named_argument_list COMMA expression + { + Report.Error (1016, ((Expression) $3).Location, "Named attribute argument expected"); + $$ = null; + } + ; named_argument : IDENTIFIER ASSIGN expression @@ -881,6 +907,13 @@ class_member_declaration | constructor_declaration // done | destructor_declaration // done | type_declaration + | error + { + Report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration", + GetSymbolName (yyToken)); + $$ = null; + lexer.parsing_generic_declaration = false; + } ; struct_declaration @@ -891,7 +924,7 @@ struct_declaration { lexer.ConstraintsParsing = true; } - type_name + type_declaration_name { MemberName name = MakeName ((MemberName) $6); push_current_class (new Struct (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); @@ -908,6 +941,7 @@ struct_declaration } struct_body { + --lexer.parsing_declaration; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; } @@ -1005,9 +1039,14 @@ constant_declarators ; constant_declarator - : IDENTIFIER ASSIGN constant_expression + : IDENTIFIER ASSIGN { - $$ = new VariableDeclaration ((LocatedToken) $1, $3); + ++lexer.parsing_block; + } + constant_initializer + { + --lexer.parsing_block; + $$ = new VariableDeclaration ((LocatedToken) $1, $4); } | IDENTIFIER { @@ -1016,22 +1055,29 @@ constant_declarator $$ = null; } ; + +constant_initializer + : constant_expression + | array_initializer + ; field_declaration : opt_attributes opt_modifiers - type + member_type variable_declarators SEMICOLON { FullNamedExpression type = (FullNamedExpression) $3; + if (type == TypeManager.system_void_expr) + Report.Error (670, GetLocation ($3), "Fields cannot have void type"); + int mod = (int) $2; current_array_type = null; - foreach (VariableDeclaration var in (ArrayList) $4){ - Field field = new Field (current_class, type, mod, var.identifier, - (Attributes) $1, var.Location); + foreach (VariableMemberDeclaration var in (ArrayList) $4){ + Field field = new Field (current_class, type, mod, var.MemberName, (Attributes) $1); field.Initializer = var.expression_or_array_initializer; @@ -1046,11 +1092,12 @@ field_declaration | opt_attributes opt_modifiers FIXED - type + member_type fixed_variable_declarators SEMICOLON { FullNamedExpression type = (FullNamedExpression) $4; + int mod = (int) $2; current_array_type = null; @@ -1070,19 +1117,11 @@ field_declaration | opt_attributes opt_modifiers FIXED - type + member_type error { Report.Error (1641, GetLocation ($4), "A fixed size buffer field must have the array size specifier after the field name"); } - | opt_attributes - opt_modifiers - VOID - variable_declarators - SEMICOLON { - current_array_type = null; - Report.Error (670, (Location) $3, "Fields cannot have void type"); - } ; fixed_variable_declarators @@ -1111,25 +1150,26 @@ fixed_variable_declarator $$ = new VariableDeclaration ((LocatedToken) $1, null); } ; - -variable_declarators - : variable_declarator + + +local_variable_declarators + : local_variable_declarator { ArrayList decl = new ArrayList (4); if ($1 != null) decl.Add ($1); $$ = decl; } - | variable_declarators COMMA variable_declarator + | local_variable_declarators COMMA local_variable_declarator { ArrayList decls = (ArrayList) $1; decls.Add ($3); $$ = $1; } ; - -variable_declarator - : IDENTIFIER ASSIGN variable_initializer + +local_variable_declarator + : IDENTIFIER ASSIGN local_variable_initializer { $$ = new VariableDeclaration ((LocatedToken) $1, $3); } @@ -1137,24 +1177,16 @@ variable_declarator { $$ = new VariableDeclaration ((LocatedToken) $1, null); } - | IDENTIFIER OPEN_BRACKET opt_expression CLOSE_BRACKET + | IDENTIFIER variable_bad_array { - Report.Error (650, ((LocatedToken) $1).Location, "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " + - "To declare a fixed size buffer field, use the fixed keyword before the field type"); $$ = null; } ; -variable_initializer +local_variable_initializer : expression - { - $$ = $1; - } | array_initializer - { - $$ = $1; - } - | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET + | STACKALLOC simple_type OPEN_BRACKET expression CLOSE_BRACKET { $$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1); } @@ -1162,13 +1194,65 @@ variable_initializer { $$ = new ArglistAccess ((Location) $1); } - | STACKALLOC type + | STACKALLOC simple_type { Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type"); - $$ = null; + $$ = new StackAlloc ((Expression) $2, null, (Location) $1); + } + ; + +variable_declarators + : variable_declarator + { + ArrayList decl = new ArrayList (4); + if ($1 != null) + decl.Add ($1); + $$ = decl; + } + | variable_declarators COMMA variable_declarator + { + ArrayList decls = (ArrayList) $1; + decls.Add ($3); + $$ = $1; + } + ; + +variable_declarator + : member_declaration_name ASSIGN + { + ++lexer.parsing_block; + lexer.parsing_generic_declaration = false; + } + variable_initializer + { + --lexer.parsing_block; + $$ = new VariableMemberDeclaration ((MemberName) $1, $4); + } + | member_declaration_name + { + lexer.parsing_generic_declaration = false; + $$ = new VariableMemberDeclaration ((MemberName) $1, null); + } + | member_declaration_name variable_bad_array + { + lexer.parsing_generic_declaration = false; + $$ = null; + } + ; + +variable_bad_array + : OPEN_BRACKET opt_expression CLOSE_BRACKET + { + Report.Error (650, GetLocation ($1), "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. " + + "To declare a fixed size buffer field, use the fixed keyword before the field type"); } ; +variable_initializer + : expression + | array_initializer + ; + method_declaration : method_header { if (RootContext.Documentation != null) @@ -1192,30 +1276,11 @@ method_declaration } ; -opt_error_modifier - : /* empty */ - | modifiers - { - int m = (int) $1; - int i = 1; - - while (m != 0){ - if ((i & m) != 0){ - Report.Error (1585, lexer.Location, - "Member modifier `{0}' must precede the member type and name", - Modifiers.Name (i)); - } - m &= ~i; - i = i << 1; - } - } - ; - method_header : opt_attributes opt_modifiers - type member_name - OPEN_PARENS + member_type + method_declaration_name OPEN_PARENS { arglist_allowed = true; } @@ -1228,7 +1293,7 @@ method_header lexer.ConstraintsParsing = false; arglist_allowed = false; MemberName name = (MemberName) $4; - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $7; if ($10 != null && name.TypeArguments == null) Report.Error (80, lexer.Location, @@ -1256,62 +1321,25 @@ method_header } | opt_attributes opt_modifiers - VOID member_name + PARTIAL + VOID method_declaration_name OPEN_PARENS { - arglist_allowed = true; - } - opt_formal_parameter_list CLOSE_PARENS - { - lexer.ConstraintsParsing = true; + arglist_allowed = true; } - opt_type_parameter_constraints_clauses - { - lexer.ConstraintsParsing = false; - arglist_allowed = false; - - MemberName name = (MemberName) $4; - current_local_parameters = (Parameters) $7; - - if ($10 != null && name.TypeArguments == null) - Report.Error (80, lexer.Location, - "Constraints are not allowed on non-generic declarations"); - - Method method; - GenericMethod generic = null; - if (name.TypeArguments != null) { - generic = new GenericMethod (current_namespace, current_class, name, - TypeManager.system_void_expr, current_local_parameters); - - generic.SetParameterInfo ((ArrayList) $10); - } - - method = new Method (current_class, generic, TypeManager.system_void_expr, - (int) $2, name, current_local_parameters, (Attributes) $1); - - current_generic_method = generic; - - if (RootContext.Documentation != null) - method.DocComment = Lexer.consume_doc_comment (); - - $$ = method; - } - | opt_attributes - opt_modifiers - PARTIAL - VOID member_name - OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + opt_formal_parameter_list CLOSE_PARENS { lexer.ConstraintsParsing = true; } opt_type_parameter_constraints_clauses { lexer.ConstraintsParsing = false; + arglist_allowed = false; MemberName name = (MemberName) $5; - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $8; - if ($9 != null && name.TypeArguments == null) + if ($10 != null && name.TypeArguments == null) Report.Error (80, lexer.Location, "Constraints are not allowed on non-generic declarations"); @@ -1321,7 +1349,7 @@ method_header generic = new GenericMethod (current_namespace, current_class, name, TypeManager.system_void_expr, current_local_parameters); - generic.SetParameterInfo ((ArrayList) $10); + generic.SetParameterInfo ((ArrayList) $11); } int modifiers = (int) $2; @@ -1340,7 +1368,7 @@ method_header Report.Error (751, name.Location, "A partial method must be declared within a " + "partial class or partial struct"); } - + modifiers |= Modifiers.PARTIAL | Modifiers.PRIVATE; method = new Method (current_class, generic, TypeManager.system_void_expr, @@ -1355,17 +1383,17 @@ method_header } | opt_attributes opt_modifiers - type - modifiers member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS + member_type + modifiers method_declaration_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { MemberName name = (MemberName) $5; Report.Error (1585, name.Location, "Member modifier `{0}' must precede the member type and name", Modifiers.Name ((int) $4)); Method method = new Method (current_class, null, TypeManager.system_void_expr, - 0, name, (Parameters) $7, (Attributes) $1); + 0, name, (ParametersCompiled) $7, (Attributes) $1); - current_local_parameters = (Parameters) $7; + current_local_parameters = (ParametersCompiled) $7; if (RootContext.Documentation != null) method.DocComment = Lexer.consume_doc_comment (); @@ -1380,12 +1408,12 @@ method_body ; opt_formal_parameter_list - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | formal_parameter_list ; opt_parameter_list_no_mod - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | { parameter_modifiers_not_allowed = true; @@ -1398,14 +1426,14 @@ opt_parameter_list_no_mod ; formal_parameter_list - : fixed_parameters + : fixed_parameters { ArrayList pars_list = (ArrayList) $1; Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars); + $$ = new ParametersCompiled (pars); } | fixed_parameters COMMA parameter_array { @@ -1415,7 +1443,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars); + $$ = new ParametersCompiled (pars); } | fixed_parameters COMMA arglist_modifier { @@ -1425,7 +1453,7 @@ formal_parameter_list Parameter [] pars = new Parameter [pars_list.Count]; pars_list.CopyTo (pars); - $$ = new Parameters (pars, true); + $$ = new ParametersCompiled (pars, true); } | parameter_array COMMA error { @@ -1451,11 +1479,11 @@ formal_parameter_list } | parameter_array { - $$ = new Parameters (new Parameter[] { (Parameter) $1 } ); + $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } ); } | arglist_modifier { - $$ = new Parameters (new Parameter [] { new ArglistParameter ((Location) $1) }, true); + $$ = new ParametersCompiled (new Parameter [] { new ArglistParameter ((Location) $1) }, true); } ; @@ -1463,17 +1491,23 @@ fixed_parameters : fixed_parameter { ArrayList pars = new ArrayList (4); - - pars.Add ($1); + Parameter p = (Parameter) $1; + pars.Add (p); + + default_parameter_used = p.HasDefaultValue; $$ = pars; } | fixed_parameters COMMA fixed_parameter { ArrayList pars = (ArrayList) $1; - Parameter p = (Parameter)$3; + Parameter p = (Parameter) $3; if (p != null) { if (p.HasExtensionMethodModifier) Report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter"); + else if (!p.HasDefaultValue && default_parameter_used) + Report.Error (1737, p.Location, "Optional parameter cannot precede required parameters"); + + default_parameter_used |= p.HasDefaultValue; pars.Add (p); } $$ = $1; @@ -1501,16 +1535,11 @@ fixed_parameter | opt_attributes opt_parameter_modifier type + error { - Report.Error (1001, GetLocation ($3), "Identifier expected"); - $$ = null; - } - | opt_attributes - opt_parameter_modifier - type - error { - CheckIdentifierToken (yyToken, GetLocation ($4)); - $$ = null; + Location l = GetLocation ($4); + CheckIdentifierToken (yyToken, l); + $$ = new Parameter ((FullNamedExpression) $3, "NeedSomeGeneratorHere", (Parameter.Modifier) $2, (Attributes) $1, l); } | opt_attributes opt_parameter_modifier @@ -1518,11 +1547,39 @@ fixed_parameter IDENTIFIER ASSIGN constant_expression - { + { + if (RootContext.Version <= LanguageVersion.V_3) { + Report.FeatureIsNotAvailable (GetLocation ($5), "optional parameter"); + } + + Parameter.Modifier mod = (Parameter.Modifier) $2; + if (mod != Parameter.Modifier.NONE) { + switch (mod) { + case Parameter.Modifier.REF: + case Parameter.Modifier.OUT: + Report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + + case Parameter.Modifier.This: + Report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter", + Parameter.GetModifierSignature (mod)); + break; + default: + throw new NotImplementedException (mod.ToString ()); + } + + mod = Parameter.Modifier.NONE; + } + + if (complex_parameters_modifiers_not_allowed) + Report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context"); + LocatedToken lt = (LocatedToken) $4; - Report.Error (241, lt.Location, "Default parameter specifiers are not permitted"); - $$ = null; - } + $$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location); + if ($6 != null) + ((Parameter) $$).DefaultValue = (Expression) $6; + } ; opt_parameter_modifier @@ -1587,10 +1644,17 @@ parameter_modifier parameter_array : opt_attributes params_modifier type IDENTIFIER - { + { LocatedToken lt = (LocatedToken) $4; $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); } + | opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression + { + Report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array"); + + LocatedToken lt = (LocatedToken) $4; + $$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location); + } | opt_attributes params_modifier type error { CheckIdentifierToken (yyToken, GetLocation ($4)); $$ = null; @@ -1600,7 +1664,7 @@ parameter_array params_modifier : PARAMS { - if (params_modifiers_not_allowed) + if (complex_parameters_modifiers_not_allowed) Report.Error (1670, ((Location) $1), "The `params' modifier is not allowed in current context"); } | PARAMS parameter_modifier @@ -1629,8 +1693,8 @@ arglist_modifier property_declaration : opt_attributes opt_modifiers - type - namespace_or_type_name + member_type + member_declaration_name { if (RootContext.Documentation != null) tmpComment = Lexer.consume_doc_comment (); @@ -1638,7 +1702,6 @@ property_declaration OPEN_BRACE { implicit_value_parameter_type = (FullNamedExpression) $3; - lexer.PropertyParsing = true; } accessor_declarations @@ -1657,14 +1720,11 @@ property_declaration MemberName name = (MemberName) $4; FullNamedExpression ptype = (FullNamedExpression) $3; - if (name.TypeArguments != null) - syntax_error (lexer.Location, "a property can't have type arguments"); - prop = new Property (current_class, ptype, (int) $2, name, (Attributes) $1, get_block, set_block, order, current_block); if (ptype == TypeManager.system_void_expr) - Report.Error (547, ptype.Location, "`{0}': property return type cannot be `void'", prop.GetSignatureForError ()); + Report.Error (547, name.Location, "`{0}': property or indexer cannot have void type", prop.GetSignatureForError ()); if (accessors == null) Report.Error (548, prop.Location, "`{0}': property or indexer must have at least one accessor", prop.GetSignatureForError ()); @@ -1685,7 +1745,7 @@ property_declaration } ; - + accessor_declarations : get_accessor_declaration { @@ -1710,8 +1770,16 @@ accessor_declarations } | error { - Report.Error (1014, GetLocation ($1), "A get or set accessor expected"); - $$ = null; + if (yyToken == Token.CLOSE_BRACE) { + $$ = null; + } else { + if (yyToken == Token.SEMICOLON) + Report.Error (1597, lexer.Location, "Semicolon after method or accessor block is not valid"); + else + Report.Error (1014, GetLocation ($1), "A get or set accessor expected"); + + $$ = new Accessors (null, null); + } } ; @@ -1721,7 +1789,7 @@ get_accessor_declaration // If this is not the case, then current_local_parameters has already // been set in indexer_declaration if (parsing_indexer == false) - current_local_parameters = null; + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; else current_local_parameters = indexer_parameters; lexer.PropertyParsing = false; @@ -1729,7 +1797,7 @@ get_accessor_declaration accessor_body { if (has_get) { - Report.Error (1007, (Location) $3, "Property accessor already defined"); + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); break; } Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); @@ -1753,9 +1821,9 @@ set_accessor_declaration Parameter.Modifier.NONE, null, (Location) $3); if (!parsing_indexer) { - current_local_parameters = new Parameters (new Parameter [] { implicit_value_parameter }); + current_local_parameters = new ParametersCompiled (new Parameter [] { implicit_value_parameter }); } else { - current_local_parameters = Parameters.MergeGenerated ( + current_local_parameters = ParametersCompiled.MergeGenerated ( indexer_parameters, true, implicit_value_parameter, null); } @@ -1764,7 +1832,7 @@ set_accessor_declaration accessor_body { if (has_set) { - Report.Error (1007, ((LocatedToken) $3).Location, "Property accessor already defined"); + Report.Error (1007, GetLocation ($3), "Property accessor already defined"); break; } Accessor accessor = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, current_local_parameters, (Location) $3); @@ -1782,7 +1850,15 @@ set_accessor_declaration accessor_body : block - | SEMICOLON { $$ = null; } + | SEMICOLON + { + $$ = null; + } + | error + { + Error_SyntaxError (1043, yyToken); + $$ = null; + } ; interface_declaration @@ -1793,7 +1869,7 @@ interface_declaration { lexer.ConstraintsParsing = true; } - type_name + type_declaration_name { MemberName name = MakeName ((MemberName) $6); push_current_class (new Interface (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); @@ -1812,6 +1888,7 @@ interface_declaration } interface_body { + --lexer.parsing_declaration; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; } @@ -1899,18 +1976,27 @@ operator_body | SEMICOLON { $$ = null; } ; +operator_type + : type_expression_or_array + | VOID + { + Report.Error (590, lexer.Location, "User-defined operators cannot return void"); + $$ = TypeManager.system_void_expr; + } + ; + operator_declarator - : type OPERATOR overloadable_operator OPEN_PARENS + : operator_type OPERATOR overloadable_operator OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; Operator.OpType op = (Operator.OpType) $3; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; int p_count = current_local_parameters.Count; if (p_count == 1) { @@ -1977,14 +2063,14 @@ overloadable_operator conversion_operator_declarator : IMPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -1995,14 +2081,14 @@ conversion_operator_declarator } | EXPLICIT OPERATOR type OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_parameter_list_no_mod CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; Location loc = (Location) $2; - current_local_parameters = (Parameters)$6; + current_local_parameters = (ParametersCompiled)$6; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); @@ -2013,43 +2099,26 @@ conversion_operator_declarator } | IMPLICIT error { - syntax_error ((Location) $1, "'operator' expected"); + Error_SyntaxError (yyToken); + $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1)); } | EXPLICIT error { - syntax_error ((Location) $1, "'operator' expected"); + Error_SyntaxError (yyToken); + $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1)); } ; constructor_declaration - : opt_attributes - opt_modifiers - constructor_declarator + : constructor_declarator constructor_body { - Constructor c = (Constructor) $3; - c.Block = (ToplevelBlock) $4; - c.OptAttributes = (Attributes) $1; - int mods = (int) $2; + Constructor c = (Constructor) $1; + c.Block = (ToplevelBlock) $2; if (RootContext.Documentation != null) c.DocComment = ConsumeStoredComment (); - if ((mods & Modifiers.STATIC) != 0 && c.Name == current_container.MemberName.Name) { - if ((mods & Modifiers.Accessibility) != 0){ - Report.Error (515, c.Location, - "`{0}': static constructor cannot have an access modifier", - c.GetSignatureForError ()); - } - - if (c.Initializer != null){ - Report.Error (514, c.Location, - "`{0}': static constructor cannot have an explicit `this' or `base' constructor call", - c.GetSignatureForError ()); - } - } - - c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, mods, Modifiers.PRIVATE, c.Location); current_container.AddConstructor (c); current_local_parameters = null; @@ -2059,34 +2128,54 @@ constructor_declaration ; constructor_declarator - : constructor_header - { - $$ = $1; - } - | constructor_header constructor_initializer - { - ((Constructor)$1).Initializer = (ConstructorInitializer) $2; - $$ = $1; - } - ; - -constructor_header - : IDENTIFIER + : opt_attributes + opt_modifiers + IDENTIFIER { if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.Allowed; } + arglist_allowed = true; } OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { - LocatedToken lt = (LocatedToken) $1; - current_local_parameters = (Parameters) $4; - current_block = new ToplevelBlock (null, current_local_parameters, null, lt.Location); - - $$ = new Constructor (current_class, lt.Value, 0, current_local_parameters, - null, lt.Location); - } + arglist_allowed = false; + current_local_parameters = (ParametersCompiled) $6; + + // + // start block here, so possible anonymous methods inside + // constructor initializer can get correct parent block + // + start_block (lexer.Location); + } + opt_constructor_initializer + { + LocatedToken lt = (LocatedToken) $3; + int mods = (int) $2; + ConstructorInitializer ci = (ConstructorInitializer) $9; + + Constructor c = new Constructor (current_class, lt.Value, mods, + (Attributes) $1, current_local_parameters, ci, lt.Location); + + if (lt.Value != current_container.MemberName.Name) { + Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type"); + } else if ((mods & Modifiers.STATIC) != 0) { + if ((mods & Modifiers.Accessibility) != 0){ + Report.Error (515, c.Location, + "`{0}': static constructor cannot have an access modifier", + c.GetSignatureForError ()); + } + if (ci != null) { + Report.Error (514, c.Location, + "`{0}': static constructor cannot have an explicit `this' or `base' constructor call", + c.GetSignatureForError ()); + + } + } + + $$ = c; + } ; constructor_body @@ -2094,17 +2183,32 @@ constructor_body | SEMICOLON { current_block = null; $$ = null; } ; +opt_constructor_initializer + : /* Empty */ + | constructor_initializer + ; + constructor_initializer - : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS + : COLON BASE OPEN_PARENS + { + ++lexer.parsing_block; + } + opt_argument_list CLOSE_PARENS + { + --lexer.parsing_block; + $$ = new ConstructorBaseInitializer ((ArrayList) $5, (Location) $2); + } + | COLON THIS OPEN_PARENS { - $$ = new ConstructorBaseInitializer ((ArrayList) $4, (Location) $2); + ++lexer.parsing_block; } - | COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS + opt_argument_list CLOSE_PARENS { - $$ = new ConstructorThisInitializer ((ArrayList) $4, (Location) $2); + --lexer.parsing_block; + $$ = new ConstructorThisInitializer ((ArrayList) $5, (Location) $2); } | COLON error { - Report.Error (1018, (Location) $1, "Keyword this or base expected"); + Report.Error (1018, GetLocation ($1), "Keyword `this' or `base' expected"); $$ = null; } ; @@ -2116,8 +2220,10 @@ destructor_declaration tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; } + + current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters; } - IDENTIFIER OPEN_PARENS CLOSE_PARENS block + IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body { LocatedToken lt = (LocatedToken) $5; if (lt.Value != current_container.MemberName.Name){ @@ -2125,15 +2231,16 @@ destructor_declaration } else if (current_container.Kind != Kind.Class){ Report.Error (575, lt.Location, "Only class types can contain destructor"); } else { - Method d = new Destructor ( - current_class, TypeManager.system_void_expr, (int) $2, "Finalize", - Parameters.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); + Destructor d = new Destructor (current_class, (int) $2, + ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location); if (RootContext.Documentation != null) d.DocComment = ConsumeStoredComment (); d.Block = (ToplevelBlock) $8; current_container.AddMethod (d); } + + current_local_parameters = null; } ; @@ -2143,14 +2250,10 @@ event_declaration EVENT type variable_declarators SEMICOLON { current_array_type = null; - foreach (VariableDeclaration var in (ArrayList) $5) { - - MemberName name = new MemberName (var.identifier, - var.Location); + foreach (VariableMemberDeclaration var in (ArrayList) $5) { EventField e = new EventField ( - current_class, (FullNamedExpression) $4, (int) $2, name, - (Attributes) $1); + current_class, (FullNamedExpression) $4, (int) $2, var.MemberName, (Attributes) $1); if (var.expression_or_array_initializer != null) { if (current_container.Kind == Kind.Interface) { @@ -2159,6 +2262,12 @@ event_declaration e.Initializer = var.expression_or_array_initializer; } + + if (var.MemberName.Left != null) { + Report.Error (71, e.Location, + "`{0}': An explicit interface implementation of an event must use property syntax", + e.GetSignatureForError ()); + } current_container.AddEvent (e); @@ -2170,11 +2279,11 @@ event_declaration } | opt_attributes opt_modifiers - EVENT type namespace_or_type_name + EVENT type member_declaration_name OPEN_BRACE { implicit_value_parameter_type = (FullNamedExpression) $4; - current_local_parameters = new Parameters ( + current_local_parameters = new ParametersCompiled ( new Parameter (implicit_value_parameter_type, "value", Parameter.Modifier.NONE, null, GetLocation ($3))); @@ -2199,9 +2308,6 @@ event_declaration } else { Accessors accessors = (Accessors) $8; - if (name.TypeArguments != null) - syntax_error (lexer.Location, "an event can't have type arguments"); - if (accessors.get_or_add == null || accessors.set_or_remove == null) // CS0073 is already reported, so no CS0065 here. $$ = null; @@ -2220,16 +2326,17 @@ event_declaration } current_local_parameters = null; } - | opt_attributes opt_modifiers EVENT type namespace_or_type_name error { + | opt_attributes opt_modifiers EVENT type member_declaration_name error + { MemberName mn = (MemberName) $5; - if (mn.Left != null) Report.Error (71, mn.Location, "An explicit interface implementation of an event must use property syntax"); - else - Report.Error (71, mn.Location, "Event declaration should use property syntax"); if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; + + Error_SyntaxError (yyToken); + $$ = null; } ; @@ -2296,19 +2403,31 @@ remove_accessor_declaration ; indexer_declaration - : opt_attributes opt_modifiers indexer_declarator + : opt_attributes opt_modifiers + member_type indexer_declaration_name OPEN_BRACKET opt_parameter_list_no_mod CLOSE_BRACKET OPEN_BRACE { - IndexerDeclaration decl = (IndexerDeclaration) $3; - - implicit_value_parameter_type = decl.type; + implicit_value_parameter_type = (FullNamedExpression) $3; + indexer_parameters = (ParametersCompiled) $6; + if (indexer_parameters.IsEmpty) { + Report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter"); + } else if (indexer_parameters.Count == 1) { + Parameter p = indexer_parameters [0]; + if (p.HasDefaultValue) + p.Warning_UselessOptionalParameter (); + } + + if (RootContext.Documentation != null) { + tmpComment = Lexer.consume_doc_comment (); + Lexer.doc_state = XmlCommentState.Allowed; + } + lexer.PropertyParsing = true; parsing_indexer = true; - indexer_parameters = decl.param_list; } - accessor_declarations + accessor_declarations { lexer.PropertyParsing = false; has_get = has_set = false; @@ -2316,28 +2435,17 @@ indexer_declaration } CLOSE_BRACE { - // The signature is computed from the signature of the indexer. Look - // at section 3.6 on the spec - Indexer indexer; - IndexerDeclaration decl = (IndexerDeclaration) $3; - Location loc = decl.location; - Accessors accessors = (Accessors) $6; + Accessors accessors = (Accessors) $10; Accessor get_block = accessors != null ? accessors.get_or_add : null; Accessor set_block = accessors != null ? accessors.set_or_remove : null; bool order = accessors != null ? accessors.declared_in_reverse : false; - MemberName name; - if (decl.interface_type != null) - name = new MemberName (decl.interface_type, TypeContainer.DefaultIndexerName, loc); - else - name = new MemberName (TypeContainer.DefaultIndexerName, loc); - - indexer = new Indexer (current_class, decl.type, name, - (int) $2, decl.param_list, (Attributes) $1, - get_block, set_block, order); + Indexer indexer = new Indexer (current_class, (FullNamedExpression) $3, + (MemberName)$4, (int) $2, (ParametersCompiled) $6, (Attributes) $1, + get_block, set_block, order); - if (decl.type == TypeManager.system_void_expr) - Report.Error (620, loc, "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); + if ($3 == TypeManager.system_void_expr) + Report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); if (accessors == null) Report.Error (548, indexer.Location, "`{0}': property or indexer must have at least one accessor", indexer.GetSignatureForError ()); @@ -2361,41 +2469,10 @@ indexer_declaration } ; -indexer_declarator - : type THIS OPEN_BRACKET opt_parameter_list_no_mod CLOSE_BRACKET - { - Parameters pars = (Parameters) $4; - if (pars.IsEmpty){ - Report.Error (1551, (Location) $2, "Indexers must have at least one parameter"); - } - if (RootContext.Documentation != null) { - tmpComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - - $$ = new IndexerDeclaration ((FullNamedExpression) $1, null, pars, (Location) $2); - } - | type namespace_or_type_name DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET - { - Parameters pars = (Parameters) $6; - if (pars.IsEmpty){ - Report.Error (1551, (Location) $4, "Indexers must have at least one parameter"); - } - - MemberName name = (MemberName) $2; - $$ = new IndexerDeclaration ((FullNamedExpression) $1, name, pars, (Location) $4); - - if (RootContext.Documentation != null) { - tmpComment = Lexer.consume_doc_comment (); - Lexer.doc_state = XmlCommentState.Allowed; - } - } - ; - enum_declaration : opt_attributes opt_modifiers - ENUM type_name + ENUM type_declaration_name opt_enum_base { if (RootContext.Documentation != null) enumTypeComment = Lexer.consume_doc_comment (); @@ -2511,6 +2588,7 @@ enum_member_declaration } | opt_attributes IDENTIFIER { + ++lexer.parsing_block; if (RootContext.Documentation != null) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2518,6 +2596,7 @@ enum_member_declaration } ASSIGN constant_expression { + --lexer.parsing_block; VariableDeclaration vd = new VariableDeclaration ( (LocatedToken) $2, $5, (Attributes) $1); @@ -2532,11 +2611,11 @@ delegate_declaration : opt_attributes opt_modifiers DELEGATE - type type_name + member_type type_declaration_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { MemberName name = MakeName ((MemberName) $5); - Parameters p = (Parameters) $7; + ParametersCompiled p = (ParametersCompiled) $7; Delegate del = new Delegate (current_namespace, current_class, (FullNamedExpression) $4, (int) $2, name, p, (Attributes) $1); @@ -2566,47 +2645,33 @@ delegate_declaration opt_nullable : /* empty */ { - lexer.CheckNullable (false); - $$ = false; + $$ = null; } - | INTERR + | INTERR_NULLABLE { - // FIXME: A hack with parsing conditional operator as nullable type - //if (RootContext.Version < LanguageVersion.ISO_2) - // Report.FeatureIsNotAvailable (lexer.Location, "nullable types"); - - lexer.CheckNullable (true); - $$ = true; + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "nullable types"); + else if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (lexer.Location, "nullable types"); + + $$ = this; } ; namespace_or_type_name - : IDENTIFIER opt_type_argument_list + : member_name + | qualified_alias_member IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $1; - $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location); - } - | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list { LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $3; - if (RootContext.Version == LanguageVersion.ISO_1) - Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier"); + LocatedToken lt2 = (LocatedToken) $2; - $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location); - } - | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list { - LocatedToken lt = (LocatedToken) $3; - $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); + $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } ; member_name - : IDENTIFIER opt_type_parameter_list - { - LocatedToken lt = (LocatedToken) $1; - $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location); - } - | namespace_or_type_name DOT IDENTIFIER opt_type_parameter_list + : type_name + | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $3; $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); @@ -2614,22 +2679,23 @@ member_name ; type_name - : IDENTIFIER opt_type_parameter_list + : IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $1; $$ = new MemberName (lt.Value, (TypeArguments)$2, lt.Location); } ; - + // // Generics arguments (any type, without attributes) // - opt_type_argument_list : /* empty */ { $$ = null; } | OP_GENERICS_LT type_arguments OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; @@ -2637,91 +2703,207 @@ opt_type_argument_list | OP_GENERICS_LT error { Error_TypeExpected (lexer.Location); + $$ = new TypeArguments (); } ; +type_arguments + : type + { + TypeArguments type_args = new TypeArguments (); + type_args.Add ((FullNamedExpression) $1); + $$ = type_args; + } + | type_arguments COMMA type + { + TypeArguments type_args = (TypeArguments) $1; + type_args.Add ((FullNamedExpression) $3); + $$ = type_args; + } + ; + // -// Generics parameters (identifiers only, with attributes), used in type, method declarations +// Generics parameters (identifiers only, with attributes), used in type or method declarations // +type_declaration_name + : IDENTIFIER + { + lexer.parsing_generic_declaration = true; + } + opt_type_parameter_list + { + lexer.parsing_generic_declaration = false; + LocatedToken lt = (LocatedToken) $1; + $$ = new MemberName (lt.Value, (TypeArguments)$3, lt.Location); + } + ; + +member_declaration_name + : method_declaration_name + { + MemberName mn = (MemberName)$1; + if (mn.TypeArguments != null) + syntax_error (mn.Location, string.Format ("Member `{0}' cannot declare type arguments", + mn.GetSignatureForError ())); + } + ; + +method_declaration_name + : type_declaration_name + | explicit_interface IDENTIFIER opt_type_parameter_list + { + lexer.parsing_generic_declaration = false; + LocatedToken lt = (LocatedToken) $2; + $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location); + } + ; + +indexer_declaration_name + : THIS + { + lexer.parsing_generic_declaration = false; + $$ = new MemberName (TypeContainer.DefaultIndexerName, GetLocation ($1)); + } + | explicit_interface THIS + { + lexer.parsing_generic_declaration = false; + $$ = new MemberName ((MemberName) $1, TypeContainer.DefaultIndexerName, null, GetLocation ($1)); + } + ; +explicit_interface + : IDENTIFIER opt_type_argument_list DOT + { + LocatedToken lt = (LocatedToken) $1; + $$ = new MemberName (lt.Value, (TypeArguments) $2, lt.Location); + } + | qualified_alias_member IDENTIFIER opt_type_argument_list DOT + { + LocatedToken lt1 = (LocatedToken) $1; + LocatedToken lt2 = (LocatedToken) $2; + + $$ = new MemberName (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); + } + | explicit_interface IDENTIFIER opt_type_argument_list DOT + { + LocatedToken lt = (LocatedToken) $2; + $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $3, lt.Location); + } + ; + opt_type_parameter_list : /* empty */ { $$ = null; } - | OP_GENERICS_LT type_arguments OP_GENERICS_GT + | OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT { - if (RootContext.Version < LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "generics"); $$ = $2; } - | OP_GENERICS_LT error - { - Error_TypeExpected (lexer.Location); - } ; -type_arguments - : type_argument +type_parameters + : type_parameter { - TypeArguments type_args = new TypeArguments (lexer.Location); - type_args.Add ((Expression) $1); + TypeArguments type_args = new TypeArguments (); + type_args.Add ((FullNamedExpression)$1); $$ = type_args; } - | type_arguments COMMA type_argument + | type_parameters COMMA type_parameter { TypeArguments type_args = (TypeArguments) $1; - type_args.Add ((Expression) $3); + type_args.Add ((FullNamedExpression)$3); $$ = type_args; } ; -type_argument - : type +type_parameter + : opt_attributes opt_type_parameter_variance IDENTIFIER { - $$ = $1; + LocatedToken lt = (LocatedToken)$3; + $$ = new TypeParameterName (lt.Value, (Attributes)$1, (Variance) $2, lt.Location); } - | attribute_sections type + | error { - SimpleName sn = $2 as SimpleName; - if (sn == null) - Error_TypeExpected (GetLocation ($2)); + if (GetTokenName (yyToken) == "type") + Report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type"); else - $2 = new TypeParameterName (sn.Name, (Attributes) $1, lexer.Location); - $$ = $2; + Error_SyntaxError (yyToken); + + $$ = new TypeParameterName ("", null, lexer.Location); } ; + +// +// All types where void is allowed +// +type_and_void + : type_expression_or_array + | VOID + { + $$ = TypeManager.system_void_expr; + } + ; -/* - * Before you think of adding a return_type, notice that we have been - * using two rules in the places where it matters (one rule using type - * and another identical one that uses VOID as the return type). This - * gets rid of a shift/reduce couple - */ +member_type + : type_and_void + { + lexer.parsing_generic_declaration = true; + } + ; + +// +// A type which does not allow `void' to be used +// type + : type_expression_or_array + | VOID + { + Expression.Error_VoidInvalidInTheContext (lexer.Location); + $$ = TypeManager.system_void_expr; + } + ; + +simple_type + : type_expression + | VOID + { + Expression.Error_VoidInvalidInTheContext (lexer.Location); + $$ = TypeManager.system_void_expr; + } + ; + +type_expression_or_array + : type_expression + | type_expression rank_specifiers + { + string rank_specifiers = (string) $2; + $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank_specifiers); + } + ; + +type_expression : namespace_or_type_name opt_nullable { MemberName name = (MemberName) $1; - if ((bool) $2) { + if ($2 != null) { $$ = new ComposedCast (name.GetTypeExpression (), "?", lexer.Location); } else { - if (name.Left == null && name.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) - $$ = new VarExpr (name.Location); + if (name.Left == null && name.Name == "var" && RootContext.Version > LanguageVersion.ISO_2) + $$ = current_array_type = new VarExpr (name.Location); else $$ = name.GetTypeExpression (); } } | builtin_types opt_nullable { - if ((bool) $2) + if ($2 != null) $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); } - | array_type - | pointer_type - ; - -pointer_type - : type STAR + | type_expression STAR { // // Note that here only unmanaged types are allowed but we @@ -2733,42 +2915,7 @@ pointer_type | VOID STAR { $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1); - } - ; - -non_expression_type - : builtin_types opt_nullable - { - if ((bool) $2) - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); - } - | non_expression_type rank_specifier - { - Location loc = GetLocation ($1); - if (loc.IsNull) - loc = lexer.Location; - $$ = new ComposedCast ((FullNamedExpression) $1, (string) $2, loc); - } - | non_expression_type STAR - { - Location loc = GetLocation ($1); - if (loc.IsNull) - loc = lexer.Location; - $$ = new ComposedCast ((FullNamedExpression) $1, "*", loc); - } - - // - // We need this because the parser will happily go and reduce IDENTIFIER STAR - // through this different path - // - | multiplicative_expression STAR - { - FullNamedExpression e = $1 as FullNamedExpression; - if (e != null) - $$ = new ComposedCast (e, "*"); - else - Error_TypeExpected (GetLocation ($1)); - } + } ; type_list @@ -2801,7 +2948,7 @@ base_type_name /* * replaces all the productions for isolating the various - * simple types, but we need this to reuse it easily in local_variable_type + * simple types, but we need this to reuse it easily in variable_type */ builtin_types : OBJECT { $$ = TypeManager.system_object_expr; } @@ -2810,7 +2957,6 @@ builtin_types | DECIMAL { $$ = TypeManager.system_decimal_expr; } | FLOAT { $$ = TypeManager.system_single_expr; } | DOUBLE { $$ = TypeManager.system_double_expr; } - | VOID { $$ = TypeManager.system_void_expr; } | integral_type ; @@ -2826,35 +2972,34 @@ integral_type | CHAR { $$ = TypeManager.system_char_expr; } ; -array_type - : type rank_specifiers +predefined_type + : builtin_types + | VOID { - string rank_specifiers = (string) $2; - $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank_specifiers); + $$ = TypeManager.system_void_expr; } ; // // Expressions, section 7.5 // + + primary_expression + : primary_expression_no_array_creation + | array_creation_expression + ; + +primary_expression_no_array_creation : literal + | IDENTIFIER opt_type_argument_list { - // 7.5.1: Literals - } - | type_name - { - MemberName mn = (MemberName) $1; - $$ = mn.GetTypeExpression (); + LocatedToken lt = (LocatedToken) $1; + $$ = new SimpleName (MemberName.MakeName (lt.Value, (TypeArguments)$2), (TypeArguments)$2, lt.Location); } - | IDENTIFIER DOUBLE_COLON IDENTIFIER opt_type_argument_list - { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $3; - if (RootContext.Version == LanguageVersion.ISO_1) - Report.FeatureIsNotAvailable (lt1.Location, "namespace alias qualifier"); - - $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $4, lt1.Location); + | IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $1; + $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location); } | parenthesized_expression | default_value_expression @@ -2865,7 +3010,8 @@ primary_expression | base_access | post_increment_expression | post_decrement_expression - | new_expression + | object_or_delegate_creation_expression + | anonymous_type_expression | typeof_expression | sizeof_expression | checked_expression @@ -2911,36 +3057,29 @@ boolean_literal | FALSE { $$ = new BoolLiteral (false, lexer.Location); } ; -parenthesized_expression_0 - : OPEN_PARENS expression CLOSE_PARENS - { - $$ = $2; - lexer.Deambiguate_CloseParens ($$); - // After this, the next token returned is one of - // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST (CLOSE_PARENS), CLOSE_PARENS_OPEN_PARENS - // or CLOSE_PARENS_MINUS. - } - | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); } + +// +// Here is the trick, tokenizer may think that parens is a special but +// parser is interested in open parens only, so we merge them. +// Consider: if (a)foo (); +// +open_parens_any + : OPEN_PARENS + | OPEN_PARENS_CAST + | OPEN_PARENS_LAMBDA ; parenthesized_expression - : parenthesized_expression_0 CLOSE_PARENS_NO_CAST - { - $$ = $1; - } - | parenthesized_expression_0 CLOSE_PARENS + : OPEN_PARENS expression CLOSE_PARENS { - $$ = $1; - } - | parenthesized_expression_0 CLOSE_PARENS_MINUS + $$ = new ParenthesizedExpression ((Expression) $2); + } + | OPEN_PARENS expression COMPLETE_COMPLETION { - // 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); + $$ = new ParenthesizedExpression ((Expression) $2); } ; - + member_access : primary_expression DOT IDENTIFIER opt_type_argument_list { @@ -2953,39 +3092,35 @@ member_access // TODO: Location is wrong as some predefined types doesn't hold a location $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); } - ; - -predefined_type - : builtin_types - ; - -invocation_expression - : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS + | qualified_alias_member IDENTIFIER opt_type_argument_list { - if ($1 == null) - Report.Error (1, (Location) $2, "Parse error"); - else - $$ = new Invocation ((Expression) $1, (ArrayList) $3); + LocatedToken lt1 = (LocatedToken) $1; + LocatedToken lt2 = (LocatedToken) $2; + + $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS - { - $$ = new Invocation ((Expression) $1, new ArrayList ()); + | primary_expression DOT GENERATE_COMPLETION { + $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3)); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression - { - $$ = new InvocationOrCast ((Expression) $1, (Expression) $3); + | primary_expression DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS non_simple_argument CLOSE_PARENS + | predefined_type DOT GENERATE_COMPLETION { - ArrayList args = new ArrayList (1); - args.Add ($4); - $$ = new Invocation ((Expression) $1, args); + // TODO: Location is wrong as some predefined types doesn't hold a location + $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS argument_list COMMA argument CLOSE_PARENS + | predefined_type DOT IDENTIFIER GENERATE_COMPLETION { + LocatedToken lt = (LocatedToken) $3; + $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location); + } + ; + +invocation_expression + : primary_expression open_parens_any opt_argument_list CLOSE_PARENS { - ArrayList args = ((ArrayList) $4); - args.Add ($6); - $$ = new Invocation ((Expression) $1, args); + $$ = new Invocation ((Expression) $1, (ArrayList) $3); } ; @@ -2995,12 +3130,12 @@ opt_object_or_collection_initializer ; object_or_collection_initializer - : OPEN_BRACE opt_member_initializer_list CLOSE_BRACE + : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { if ($2 == null) - $$ = CollectionOrObjectInitializers.Empty; + $$ = CollectionOrObjectInitializers.Empty; else - $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); + $$ = new CollectionOrObjectInitializers ((ArrayList) $2, GetLocation ($1)); } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { @@ -3017,7 +3152,7 @@ opt_member_initializer_list ; member_initializer_list - : member_initializer + : member_initializer { ArrayList a = new ArrayList (); a.Add ($1); @@ -3037,9 +3172,16 @@ member_initializer LocatedToken lt = $1 as LocatedToken; $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); } - | non_assignment_expression + | GENERATE_COMPLETION { - $$ = new CollectionElementInitializer ((Expression)$1); + $$ = new CompletionElementInitializer (null, GetLocation ($1)); + } + | non_assignment_expression opt_COMPLETE_COMPLETION { + CompletionSimpleName csn = $1 as CompletionSimpleName; + if (csn == null) + $$ = new CollectionElementInitializer ((Expression)$1); + else + $$ = new CompletionElementInitializer (csn.Prefix, csn.Location); } | OPEN_BRACE expression_list CLOSE_BRACE { @@ -3084,10 +3226,6 @@ argument_list Report.Error (839, GetLocation ($1), "An argument is missing"); $$ = null; } - | argument_list error { - CheckToken (1026, yyToken, "Expected `,' or `)'", GetLocation ($2)); - $$ = null; - } ; argument @@ -3110,7 +3248,7 @@ non_simple_argument { $$ = new Argument ((Expression) $2, Argument.AType.Out); } - | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS + | ARGLIST open_parens_any argument_list CLOSE_PARENS { ArrayList list = (ArrayList) $3; Argument[] args = new Argument [list.Count]; @@ -3119,7 +3257,7 @@ non_simple_argument Expression expr = new Arglist (args, (Location) $1); $$ = new Argument (expr, Argument.AType.Expression); } - | ARGLIST OPEN_PARENS CLOSE_PARENS + | ARGLIST open_parens_any CLOSE_PARENS { $$ = new Argument (new Arglist ((Location) $1), Argument.AType.Expression); } @@ -3134,11 +3272,16 @@ variable_reference ; element_access - : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET + : primary_expression_no_array_creation OPEN_BRACKET expression_list CLOSE_BRACKET { $$ = new ElementAccess ((Expression) $1, (ArrayList) $3); } - | primary_expression rank_specifiers + | array_creation_expression OPEN_BRACKET expression_list CLOSE_BRACKET + { + // LAMESPEC: Not allowed according to specification + $$ = new ElementAccess ((Expression) $1, (ArrayList) $3); + } + | primary_expression_no_array_creation rank_specifiers { // So the super-trick is that primary_expression // can only be either a SimpleName or a MemberAccess. @@ -3206,77 +3349,81 @@ base_access post_increment_expression : primary_expression OP_INC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, - (Expression) $1, (Location) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1); } ; post_decrement_expression : primary_expression OP_DEC { - $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, - (Expression) $1, (Location) $2); + $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1); } ; -new_expression - : object_or_delegate_creation_expression - | array_creation_expression - | anonymous_type_expression - ; - object_or_delegate_creation_expression - : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer + : new_expr_start open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer { - if ($6 != null) { + if ($5 != null) { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "object initializers"); - $$ = new NewInitialize ((Expression) $2, (ArrayList) $4, (CollectionOrObjectInitializers) $6, (Location) $1); + $$ = new NewInitialize ((Expression) $1, (ArrayList) $3, (CollectionOrObjectInitializers) $5, GetLocation ($1)); } else - $$ = new New ((Expression) $2, (ArrayList) $4, (Location) $1); + $$ = new New ((Expression) $1, (ArrayList) $3, GetLocation ($1)); } - | NEW type object_or_collection_initializer + | new_expr_start object_or_collection_initializer { if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "collection initializers"); - $$ = new NewInitialize ((Expression) $2, null, (CollectionOrObjectInitializers) $3, (Location) $1); + $$ = new NewInitialize ((Expression) $1, null, (CollectionOrObjectInitializers) $2, GetLocation ($1)); } ; array_creation_expression - : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET - opt_rank_specifier + : new_expr_start OPEN_BRACKET expression_list CLOSE_BRACKET + opt_rank_specifier // shift/reduce on OPEN_BRACE opt_array_initializer { - $$ = new ArrayCreation ((FullNamedExpression) $2, (ArrayList) $4, (string) $6, (ArrayList) $7, (Location) $1); + $$ = new ArrayCreation ((FullNamedExpression) $1, (ArrayList) $3, (string) $5, (ArrayList) $6, GetLocation ($1)); } - | NEW type rank_specifiers array_initializer + | new_expr_start rank_specifiers opt_array_initializer { - $$ = new ArrayCreation ((FullNamedExpression) $2, (string) $3, (ArrayList) $4, (Location) $1); + if ($3 == null) + Report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer"); + + $$ = new ArrayCreation ((FullNamedExpression) $1, (string) $2, (ArrayList) $3, GetLocation ($1)); } | NEW rank_specifiers array_initializer { - $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, (Location) $1); + $$ = new ImplicitlyTypedArrayCreation ((string) $2, (ArrayList) $3, GetLocation ($1)); } - | NEW error - { - Report.Error (1031, (Location) $1, "Type expected"); - $$ = null; - } - | NEW type error + | new_expr_start error { - Report.Error (1526, (Location) $1, "A new expression requires () or [] after type"); + Report.Error (1526, GetLocation ($1), "A new expression requires () or [] after type"); $$ = null; } ; +new_expr_start + : NEW + { + ++lexer.parsing_type; + } + simple_type + { + --lexer.parsing_type; + $$ = $3; + } + ; + anonymous_type_expression : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE { - if (RootContext.Version <= LanguageVersion.ISO_2) + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "anonymous types"); + else if (RootContext.Version <= LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($1), "anonymous types"); $$ = new AnonymousTypeDeclaration ((ArrayList) $3, current_container, GetLocation ($1)); @@ -3341,58 +3488,53 @@ anonymous_type_parameter opt_rank_specifier : /* empty */ { - $$ = ""; + $$ = ""; } | rank_specifiers { - $$ = $1; + $$ = $1; } ; opt_rank_specifier_or_nullable - : /* empty */ - { - $$ = string.Empty; - } - | INTERR + : opt_nullable { - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (lexer.Location, "nullable types"); - - $$ = "?"; + if ($1 != null) + $$ = "?"; + else + $$ = string.Empty; } | opt_nullable rank_specifiers { - if ((bool) $1) - $$ = "?" + $2; + if ($1 != null) + $$ = "?" + (string) $2; else $$ = $2; } ; rank_specifiers - : rank_specifier opt_rank_specifier + : rank_specifier + | rank_specifier rank_specifiers { - $$ = (string) $2 + (string) $1; + $$ = (string) $2 + (string) $1; } - ; + ; rank_specifier - : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET + : OPEN_BRACKET CLOSE_BRACKET { - $$ = "[" + (string) $2 + "]"; + $$ = "[]"; } - ; - -opt_dim_separators - : /* empty */ + | OPEN_BRACKET dim_separators CLOSE_BRACKET { - $$ = ""; + $$ = "[" + (string) $2 + "]"; } - | dim_separators + | OPEN_BRACKET error CLOSE_BRACKET { - $$ = $1; - } + ArrayCreation.Error_IncorrectArrayInitializer (GetLocation ($1)); + $$ = "[]"; + } ; dim_separators @@ -3411,7 +3553,7 @@ opt_array_initializer { $$ = null; } - | array_initializer + | array_initializer { $$ = $1; } @@ -3442,6 +3584,11 @@ variable_initializer_list list.Add ($3); $$ = list; } + | error + { + Error_SyntaxError (yyToken); + $$ = new ArrayList (); + } ; typeof_expression @@ -3450,7 +3597,7 @@ typeof_expression pushed_current_array_type = current_array_type; lexer.TypeOfParsing = true; } - OPEN_PARENS typeof_type_expression CLOSE_PARENS + open_parens_any typeof_type_expression CLOSE_PARENS { lexer.TypeOfParsing = false; Expression type = (Expression)$4; @@ -3463,75 +3610,88 @@ typeof_expression ; typeof_type_expression - : type - { - $$ = $1; - } + : type_and_void | unbound_type_name - { - $$ = new UnboundTypeExpression ((MemberName)$1, lexer.Location); - } | error { Error_TypeExpected (lexer.Location); + $$ = null; } ; unbound_type_name - : IDENTIFIER GENERIC_DIMENSION - { - if (RootContext.Version < LanguageVersion.ISO_2) - Report.FeatureIsNotAvailable (lexer.Location, "generics"); - + : IDENTIFIER generic_dimension + { LocatedToken lt = (LocatedToken) $1; - TypeArguments ta = new TypeArguments ((int)$2, lt.Location); - $$ = new MemberName (lt.Value, ta, lt.Location); + $$ = new SimpleName (MemberName.MakeName (lt.Value, (int)$2), lt.Location); } - | IDENTIFIER DOUBLE_COLON IDENTIFIER GENERIC_DIMENSION + | qualified_alias_member IDENTIFIER generic_dimension { - LocatedToken lt = (LocatedToken) $1; - MemberName left = new MemberName (lt.Value, lt.Location); - lt = (LocatedToken) $3; - TypeArguments ta = new TypeArguments ((int)$4, lt.Location); - - if (RootContext.Version == LanguageVersion.ISO_1) - Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier"); - - $$ = new MemberName (left, lt.Value, ta, lt.Location); + LocatedToken lt1 = (LocatedToken) $1; + LocatedToken lt2 = (LocatedToken) $2; + + $$ = new QualifiedAliasMember (lt1.Value, MemberName.MakeName (lt2.Value, (int) $3), lt1.Location); } - | unbound_type_name DOT IDENTIFIER GENERIC_DIMENSION + | unbound_type_name DOT IDENTIFIER { LocatedToken lt = (LocatedToken) $3; - TypeArguments ta = new TypeArguments ((int)$4, lt.Location); - $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location); + $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location); } - | namespace_or_type_name DOT IDENTIFIER GENERIC_DIMENSION + | unbound_type_name DOT IDENTIFIER generic_dimension { LocatedToken lt = (LocatedToken) $3; - TypeArguments ta = new TypeArguments ((int)$4, lt.Location); - $$ = new MemberName ((MemberName)$1, lt.Value, ta, lt.Location); + $$ = new MemberAccess ((Expression) $1, MemberName.MakeName (lt.Value, (int) $4), lt.Location); + } + | namespace_or_type_name DOT IDENTIFIER generic_dimension + { + LocatedToken lt = (LocatedToken) $3; + MemberName name = (MemberName) $1; + + $$ = new MemberAccess (name.GetTypeExpression (), MemberName.MakeName (lt.Value, (int) $4), lt.Location); + } + ; + +generic_dimension + : GENERIC_DIMENSION + { + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generics"); + else if (RootContext.Version < LanguageVersion.ISO_2) + Report.FeatureIsNotAvailable (lexer.Location, "generics"); + + $$ = $1; } ; + +qualified_alias_member + : IDENTIFIER DOUBLE_COLON + { + LocatedToken lt = (LocatedToken) $1; + if (RootContext.Version == LanguageVersion.ISO_1) + Report.FeatureIsNotAvailable (lt.Location, "namespace alias qualifier"); + $$ = lt; + } + ; sizeof_expression - : SIZEOF OPEN_PARENS type CLOSE_PARENS { + : SIZEOF open_parens_any type CLOSE_PARENS { $$ = new SizeOf ((Expression) $3, (Location) $1); } ; checked_expression - : CHECKED OPEN_PARENS expression CLOSE_PARENS + : CHECKED open_parens_any expression CLOSE_PARENS { $$ = new CheckedExpr ((Expression) $3, (Location) $1); } ; unchecked_expression - : UNCHECKED OPEN_PARENS expression CLOSE_PARENS + : UNCHECKED open_parens_any expression CLOSE_PARENS { $$ = new UnCheckedExpr ((Expression) $3, (Location) $1); } @@ -3551,38 +3711,41 @@ pointer_member_access anonymous_method_expression : DELEGATE opt_anonymous_method_signature { - start_anonymous (false, (Parameters) $2, (Location) $1); + start_anonymous (false, (ParametersCompiled) $2, (Location) $1); } block { - $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1); + $$ = end_anonymous ((ToplevelBlock) $4); } ; opt_anonymous_method_signature - : /* empty */ { $$ = null; } + : + { + $$ = ParametersCompiled.Undefined; + } | anonymous_method_signature ; anonymous_method_signature : OPEN_PARENS { - params_modifiers_not_allowed = true; + complex_parameters_modifiers_not_allowed = true; } opt_formal_parameter_list CLOSE_PARENS { - params_modifiers_not_allowed = false; + complex_parameters_modifiers_not_allowed = false; $$ = $3; } ; default_value_expression - : DEFAULT_OPEN_PARENS type CLOSE_PARENS + : DEFAULT open_parens_any type CLOSE_PARENS { if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (lexer.Location, "default value expression"); - $$ = new DefaultValueExpression ((Expression) $2, lexer.Location); + $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1)); } ; @@ -3590,36 +3753,23 @@ unary_expression : primary_expression | BANG prefixed_unary_expression { - $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2); } | TILDE prefixed_unary_expression { - $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2); } | cast_expression ; -cast_list - : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression - { - $$ = new Cast ((Expression) $1, (Expression) $3); - } - | parenthesized_expression_0 CLOSE_PARENS_NO_CAST default_value_expression +cast_expression + : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression { - $$ = new Cast ((Expression) $1, (Expression) $3); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } - | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression - { - $$ = new Cast ((Expression) $1, (Expression) $3); - } - ; - -cast_expression - : cast_list - | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression + | OPEN_PARENS predefined_type CLOSE_PARENS prefixed_unary_expression { - // TODO: wrong location - $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location); + $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1)); } ; @@ -3631,29 +3781,27 @@ prefixed_unary_expression : unary_expression | PLUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2); } | MINUS prefixed_unary_expression { - $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2); } | OP_INC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, - (Expression) $2, (Location) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2); } | OP_DEC prefixed_unary_expression { - $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, - (Expression) $2, (Location) $1); + $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2); } | STAR prefixed_unary_expression { - $$ = new Indirection ((Expression) $2, (Location) $1); + $$ = new Indirection ((Expression) $2, GetLocation ($1)); } | BITWISE_AND prefixed_unary_expression { - $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, (Location) $1); + $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2); } ; @@ -3685,9 +3833,21 @@ additive_expression } | additive_expression MINUS multiplicative_expression { - $$ = new Binary (Binary.Operator.Subtraction, - (Expression) $1, (Expression) $3); + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + } + | parenthesized_expression MINUS multiplicative_expression + { + // Shift/Reduce conflict + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3); + } + | additive_expression AS type + { + $$ = new As ((Expression) $1, (Expression) $3, (Location) $2); } + | additive_expression IS type + { + $$ = new Is ((Expression) $1, (Expression) $3, (Location) $2); + } ; shift_expression @@ -3704,28 +3864,6 @@ shift_expression } ; -opt_error - : /* empty */ - { - $$ = false; - } - | error - { - lexer.PutbackNullable (); - $$ = true; - } - ; - -nullable_type_or_conditional - : type opt_error - { - if (((bool) $2) && ($1 is ComposedCast)) - $$ = ((ComposedCast) $1).RemoveNullable (); - else - $$ = $1; - } - ; - relational_expression : shift_expression | relational_expression OP_LT shift_expression @@ -3748,20 +3886,6 @@ relational_expression $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3); } - | relational_expression IS - { - yyErrorFlag = 3; - } nullable_type_or_conditional - { - $$ = new Is ((Expression) $1, (Expression) $4, (Location) $2); - } - | relational_expression AS - { - yyErrorFlag = 3; - } nullable_type_or_conditional - { - $$ = new As ((Expression) $1, (Expression) $4, (Location) $2); - } ; equality_expression @@ -3822,25 +3946,23 @@ conditional_or_expression (Expression) $1, (Expression) $3); } ; - -conditional_expression + +null_coalescing_expression : conditional_or_expression - | conditional_or_expression INTERR expression COLON expression - { - $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); - } - | conditional_or_expression OP_COALESCING expression + | conditional_or_expression OP_COALESCING null_coalescing_expression { if (RootContext.Version < LanguageVersion.ISO_2) Report.FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator"); $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, lexer.Location); } - // We'll be resolved into a `parenthesized_expression_0' later on. - | conditional_or_expression INTERR CLOSE_PARENS + ; + +conditional_expression + : null_coalescing_expression + | null_coalescing_expression INTERR expression COLON expression { - $$ = new ComposedCast ((FullNamedExpression) $1, "?", lexer.Location); - lexer.PutbackCloseParens (); + $$ = new Conditional ((Expression) $1, (Expression) $3, (Expression) $5); } ; @@ -3943,10 +4065,10 @@ lambda_parameter ; opt_lambda_parameter_list - : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; } + : /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; } | lambda_parameter_list { ArrayList pars_list = (ArrayList) $1; - $$ = new Parameters ((Parameter[])pars_list.ToArray (typeof (Parameter))); + $$ = new ParametersCompiled ((Parameter[])pars_list.ToArray (typeof (Parameter))); } ; @@ -3970,25 +4092,25 @@ lambda_expression { LocatedToken lt = (LocatedToken) $1; Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); - start_anonymous (true, new Parameters (p), (Location) $2); + start_anonymous (true, new ParametersCompiled (p), GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2); + $$ = end_anonymous ((ToplevelBlock) $4); } | OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW { - start_anonymous (true, (Parameters) $2, (Location) $4); + start_anonymous (true, (ParametersCompiled) $2, GetLocation ($1)); } lambda_expression_body { - $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4); + $$ = end_anonymous ((ToplevelBlock) $6); } ; expression - : assignment_expression - | non_assignment_expression + : assignment_expression + | non_assignment_expression ; non_assignment_expression @@ -4016,7 +4138,7 @@ class_declaration { lexer.ConstraintsParsing = true; } - type_name + type_declaration_name { MemberName name = MakeName ((MemberName) $6); push_current_class (new Class (current_namespace, current_class, name, (int) $2, (Attributes) $1), $3); @@ -4035,6 +4157,7 @@ class_declaration } class_body { + --lexer.parsing_declaration; if (RootContext.Documentation != null) Lexer.doc_state = XmlCommentState.Allowed; } @@ -4072,7 +4195,12 @@ modifiers ; modifier - : NEW { $$ = Modifiers.NEW; } + : NEW + { + $$ = Modifiers.NEW; + if (current_container == RootContext.ToplevelTypes) + Report.Error (1530, lexer.Location, "Keyword `new' is not allowed on namespace elements"); + } | PUBLIC { $$ = Modifiers.PUBLIC; } | PROTECTED { $$ = Modifiers.PROTECTED; } | INTERNAL { $$ = Modifiers.INTERNAL; } @@ -4159,6 +4287,33 @@ type_parameter_constraint } ; +opt_type_parameter_variance + : /* empty */ + { + $$ = Variance.None; + } + | type_parameter_variance + { + if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2) + Report.FeatureIsNotSupported (lexer.Location, "generic type variance"); + else if (RootContext.Version <= LanguageVersion.V_3) + Report.FeatureIsNotAvailable (lexer.Location, "generic type variance"); + + $$ = $1; + } + ; + +type_parameter_variance + : OUT + { + $$ = Variance.Covariant; + } + | IN + { + $$ = Variance.Contravariant; + } + ; + // // Statements (8.2) // @@ -4178,17 +4333,31 @@ block ++lexer.parsing_block; start_block ((Location) $1); } - opt_statement_list CLOSE_BRACE + opt_statement_list block_end + { + $$ = $4; + } + ; + +block_end + : CLOSE_BRACE { --lexer.parsing_block; - $$ = end_block ((Location) $4); + $$ = end_block ((Location) $1); + } + | COMPLETE_COMPLETION + { + --lexer.parsing_block; + $$ = end_block (lexer.Location); } ; + block_prepared : OPEN_BRACE { ++lexer.parsing_block; + current_block.StartLocation = GetLocation ($1); } opt_statement_list CLOSE_BRACE { @@ -4342,8 +4511,8 @@ declaration_statement * > expressions to prevent reduce/reduce errors in the grammar. * > The expressions are converted into types during semantic analysis. */ -local_variable_type - : primary_expression opt_rank_specifier_or_nullable +variable_type + : primary_expression_no_array_creation opt_rank_specifier_or_nullable { // FIXME: Do something smart here regarding the composition of the type. @@ -4373,9 +4542,8 @@ local_variable_type // if (rank_or_nullable.Length == 0) { SimpleName sn = expr as SimpleName; - if (sn != null && sn.Name == "var" && - (RootContext.Version > LanguageVersion.ISO_2 || RootContext.Version == LanguageVersion.Default_MCS)) - $$ = new VarExpr (sn.Location); + if (sn != null && sn.Name == "var" && RootContext.Version > LanguageVersion.ISO_2) + $$ = current_array_type = new VarExpr (sn.Location); else $$ = $1; } else { @@ -4393,10 +4561,15 @@ local_variable_type else $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, (string) $2, lexer.Location); } - ; + | VOID opt_rank_specifier + { + Expression.Error_VoidInvalidInTheContext (lexer.Location); + $$ = TypeManager.system_void_expr; + } + ; local_variable_pointer_type - : primary_expression STAR + : primary_expression_no_array_creation STAR { ATypeNameExpression expr = $1 as ATypeNameExpression; @@ -4407,22 +4580,39 @@ local_variable_pointer_type $$ = expr; } } - | builtin_types STAR + | builtin_types STAR { - $$ = new ComposedCast ((FullNamedExpression) $1, "*", lexer.Location); + $$ = new ComposedCast ((FullNamedExpression) $1, "*", GetLocation ($1)); } - | VOID STAR + | VOID STAR { $$ = new ComposedCast (TypeManager.system_void_expr, "*", (Location) $1); } | local_variable_pointer_type STAR - { + { $$ = new ComposedCast ((FullNamedExpression) $1, "*"); } - ; + ; + +local_variable_type + : variable_type + | local_variable_pointer_type opt_rank_specifier + { + if ($1 != null){ + string rank = (string)$2; + + if (rank == "") + $$ = $1; + else + $$ = current_array_type = new ComposedCast ((FullNamedExpression) $1, rank); + } else { + $$ = null; + } + } + ; local_variable_declaration - : local_variable_type variable_declarators + : local_variable_type local_variable_declarators { if ($1 != null) { VarExpr ve = $1 as VarExpr; @@ -4433,23 +4623,10 @@ local_variable_declaration } else $$ = null; } - | local_variable_pointer_type opt_rank_specifier_or_nullable variable_declarators - { - if ($1 != null){ - Expression t; - - if ((string) $2 == "") - t = (Expression) $1; - else - t = new ComposedCast ((FullNamedExpression) $1, (string) $2); - $$ = new DictionaryEntry (t, $3); - } else - $$ = null; - } ; local_constant_declaration - : CONST local_variable_type constant_declarators + : CONST variable_type constant_declarators { if ($2 != null) $$ = new DictionaryEntry ($2, $3); @@ -4460,10 +4637,12 @@ local_constant_declaration expression_statement : statement_expression SEMICOLON { $$ = $1; } + | statement_expression COMPLETE_COMPLETION { $$ = $1; } ; interactive_expression_statement : interactive_statement_expression SEMICOLON { $$ = $1; } + | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; } ; // @@ -4473,21 +4652,17 @@ interactive_expression_statement statement_expression : expression { - Expression expr = (Expression) $1; - ExpressionStatement s; - - s = expr as ExpressionStatement; - + ExpressionStatement s = $1 as ExpressionStatement; if (s == null) { - expr.Error_InvalidExpressionStatement (); - $$ = null; - } + ((Expression) $1).Error_InvalidExpressionStatement (); + s = EmptyExpressionStatement.Instance; + } + $$ = new StatementExpression (s); } | error { - Report.ExtraInformation (GetLocation ($1), "(token is: " + yyToken + " in previous "); - Report.Error (1002, GetLocation ($1), "Expecting `;'"); + Error_SyntaxError (yyToken); $$ = null; } ; @@ -4503,7 +4678,7 @@ interactive_statement_expression } | error { - Report.Error (1002, GetLocation ($1), "Expecting `;' (token is: {0})", yyToken); + Error_SyntaxError (yyToken); $$ = null; } ; @@ -4514,7 +4689,7 @@ selection_statement ; if_statement - : IF OPEN_PARENS boolean_expression CLOSE_PARENS + : IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement { Location l = (Location) $1; @@ -4526,7 +4701,7 @@ if_statement Report.Warning (642, 3, l, "Possible mistaken empty statement"); } - | IF OPEN_PARENS boolean_expression CLOSE_PARENS + | IF open_parens_any boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement { Location l = (Location) $1; @@ -4542,7 +4717,7 @@ if_statement ; switch_statement - : SWITCH OPEN_PARENS + : SWITCH open_parens_any { if (switch_stack == null) switch_stack = new Stack (2); @@ -4620,12 +4795,13 @@ switch_labels ; switch_label - : CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, (Location) $1); } - | DEFAULT_COLON { $$ = new SwitchLabel (null, (Location) $1); } - | error { - Report.Error ( - 1523, GetLocation ($1), - "The keyword case or default must precede code in switch block"); + : CASE constant_expression COLON + { + $$ = new SwitchLabel ((Expression) $2, (Location) $1); + } + | DEFAULT_COLON + { + $$ = new SwitchLabel (null, (Location) $1); } ; @@ -4637,7 +4813,7 @@ iteration_statement ; while_statement - : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement + : WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement { Location l = (Location) $1; $$ = new While ((Expression) $3, (Statement) $5, l); @@ -4646,7 +4822,7 @@ while_statement do_statement : DO embedded_statement - WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON + WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON { Location l = (Location) $1; @@ -4655,8 +4831,7 @@ do_statement ; for_statement - : FOR OPEN_PARENS - opt_for_initializer SEMICOLON + : FOR open_parens_any opt_for_initializer SEMICOLON { Location l = lexer.Location; start_block (l); @@ -4753,12 +4928,12 @@ statement_expression_list ; foreach_statement - : FOREACH OPEN_PARENS type IN expression CLOSE_PARENS + : FOREACH open_parens_any type IN expression CLOSE_PARENS { Report.Error (230, (Location) $1, "Type and identifier are both required in a foreach statement"); $$ = null; } - | FOREACH OPEN_PARENS type IDENTIFIER IN + | FOREACH open_parens_any type IDENTIFIER IN expression CLOSE_PARENS { start_block (lexer.Location); @@ -4977,11 +5152,11 @@ opt_catch_args ; catch_args - : OPEN_PARENS type opt_identifier CLOSE_PARENS + : open_parens_any type opt_identifier CLOSE_PARENS { $$ = new DictionaryEntry ($2, $3); } - | OPEN_PARENS CLOSE_PARENS + | open_parens_any CLOSE_PARENS { Report.Error (1015, GetLocation ($1), "A type that derives from `System.Exception', `object', or `string' expected"); } @@ -5011,8 +5186,8 @@ unsafe_statement ; fixed_statement - : FIXED OPEN_PARENS - type fixed_pointer_declarators + : FIXED open_parens_any + type_and_void fixed_pointer_declarators CLOSE_PARENS { ArrayList list = (ArrayList) $4; @@ -5079,7 +5254,7 @@ fixed_pointer_declarator ; lock_statement - : LOCK OPEN_PARENS expression CLOSE_PARENS + : LOCK open_parens_any expression CLOSE_PARENS { // } @@ -5090,7 +5265,7 @@ lock_statement ; using_statement - : USING OPEN_PARENS local_variable_declaration CLOSE_PARENS + : USING open_parens_any local_variable_declaration CLOSE_PARENS { start_block (lexer.Location); Block assign_block = current_block; @@ -5145,7 +5320,7 @@ using_statement current_block.AddStatement (stmt); $$ = end_block (lexer.Location); } - | USING OPEN_PARENS expression CLOSE_PARENS + | USING open_parens_any expression CLOSE_PARENS { start_block (lexer.Location); } @@ -5160,18 +5335,23 @@ using_statement // LINQ query_expression - : first_from_clause + : first_from_clause query_body { - ++lexer.query_parsing; + lexer.query_parsing = false; + + Linq.AQueryClause from = $1 as Linq.AQueryClause; + + from.Tail.Next = (Linq.AQueryClause)$2; + $$ = from; + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } - query_body + | nested_from_clause query_body { - if (--lexer.query_parsing == 1) - lexer.query_parsing = 0; - Linq.AQueryClause from = $1 as Linq.AQueryClause; - from.Tail.Next = (Linq.AQueryClause)$3; + from.Tail.Next = (Linq.AQueryClause)$2; $$ = from; current_block.SetEndLocation (lexer.Location); @@ -5180,42 +5360,61 @@ query_expression ; first_from_clause + : FROM_FIRST IDENTIFIER IN expression + { + $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); + } + | FROM_FIRST type IDENTIFIER IN expression + { + $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); + } + ; + +nested_from_clause : FROM IDENTIFIER IN expression { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $2; - - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, lt.Value, lt.Location); - $$ = new Linq.QueryExpression (lt, new Linq.QueryStartClause ((Expression)$4)); + $$ = new Linq.QueryExpression (current_block, new Linq.QueryStartClause ((Expression)$4)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); } | FROM type IDENTIFIER IN expression { - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $3; - - Expression type = (Expression)$2; - current_block.AddVariable (type, lt.Value, lt.Location); - $$ = new Linq.QueryExpression (lt, new Linq.Cast (type, (Expression)$5)); + $$ = new Linq.QueryExpression (current_block, new Linq.Cast ((FullNamedExpression)$2, (Expression)$5)); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, GetLocation ($1)); } ; from_clause - : FROM IDENTIFIER IN expression + : FROM IDENTIFIER IN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + } + expression { LocatedToken lt = (LocatedToken) $2; + $$ = new Linq.SelectMany (current_block.Toplevel, lt, (Expression)$5); - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - - $$ = new Linq.SelectMany (lt, (Expression)$4); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + } + | FROM type IDENTIFIER IN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); } - | FROM type IDENTIFIER IN expression + expression { LocatedToken lt = (LocatedToken) $3; - - Expression type = (Expression)$2; - current_block.AddVariable (type, lt.Value, lt.Location); - $$ = new Linq.SelectMany (lt, new Linq.Cast (type, (Expression)$5)); + FullNamedExpression type = (FullNamedExpression)$2; + + $$ = new Linq.SelectMany (current_block.Toplevel, lt, new Linq.Cast (type, (FullNamedExpression)$6)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); } ; @@ -5238,13 +5437,38 @@ query_body ; select_or_group_clause - : SELECT expression + : SELECT + { + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + expression + { + $$ = new Linq.Select (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + } + | GROUP + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression { - $$ = new Linq.Select ((Expression)$2, GetLocation ($1)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); } - | GROUP expression BY expression + BY expression { - $$ = new Linq.GroupBy ((Expression)$2, (Expression)$4, GetLocation ($1)); + $$ = new Linq.GroupBy (current_block.Toplevel, (Expression)$3, (ToplevelBlock) linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } ; @@ -5271,54 +5495,130 @@ query_body_clause ; let_clause - : LET IDENTIFIER ASSIGN expression + : LET IDENTIFIER ASSIGN + { + current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); + } + expression { LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - $$ = new Linq.Let (lt, (Expression)$4, GetLocation ($1)); + $$ = new Linq.Let (current_block.Toplevel, current_container, lt, (Expression)$5); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); } ; where_clause - : WHERE boolean_expression + : WHERE { - $$ = new Linq.Where ((Expression)$2, GetLocation ($1)); + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + boolean_expression + { + $$ = new Linq.Where (current_block.Toplevel, (Expression)$3, GetLocation ($1)); + + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; } ; join_clause - : JOIN IDENTIFIER IN expression ON expression EQUALS expression opt_join_into + : JOIN IDENTIFIER IN + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression ON + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression EQUALS + { + current_block.AddStatement (new ContextualReturn ((Expression) $8)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, lexer.Location); + } + expression opt_join_into { - Location loc = GetLocation ($1); LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); - if ($9 == null) { - $$ = new Linq.Join (lt, (Expression)$4, (Expression)$6, - (Expression)$8, loc); + ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); + ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); + + if ($12 == null) { + $$ = new Linq.Join (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, GetLocation ($1)); } else { - LocatedToken lt_into = (LocatedToken) $9; - $$ = new Linq.GroupJoin (lt, (Expression)$4, (Expression)$6, - (Expression)$8, lt_into, loc); + $$ = new Linq.GroupJoin (block, lt, (Expression)$5, outer_selector, current_block.Toplevel, + (LocatedToken) $12, GetLocation ($1)); } + + current_block.AddStatement (new ContextualReturn ((Expression) $11)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + if ($12 == null) + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + else + ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $12); + } + | JOIN type IDENTIFIER IN + { + if (linq_clause_blocks == null) + linq_clause_blocks = new Stack (); + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression ON + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + linq_clause_blocks.Push (current_block); + } + expression EQUALS + { + current_block.AddStatement (new ContextualReturn ((Expression) $9)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $3, lexer.Location); } - | JOIN type IDENTIFIER IN expression ON expression EQUALS expression opt_join_into + expression opt_join_into { - Location loc = GetLocation ($1); LocatedToken lt = (LocatedToken) $3; - current_block.AddVariable ((Expression)$2, lt.Value, lt.Location); + ToplevelBlock outer_selector = (ToplevelBlock) linq_clause_blocks.Pop (); + ToplevelBlock block = (ToplevelBlock) linq_clause_blocks.Pop (); - Linq.Cast cast = new Linq.Cast ((Expression)$2, (Expression)$5); - if ($10 == null) { - $$ = new Linq.Join (lt, cast, (Expression)$7, - (Expression)$9, loc); + Linq.Cast cast = new Linq.Cast ((FullNamedExpression)$2, (Expression)$6); + if ($13 == null) { + $$ = new Linq.Join (block, lt, cast, outer_selector, current_block.Toplevel, GetLocation ($1)); } else { - LocatedToken lt_into = (LocatedToken) $10; - $$ = new Linq.GroupJoin (lt, cast, (Expression)$7, - (Expression)$9, lt_into, loc); + $$ = new Linq.GroupJoin (block, lt, cast, outer_selector, current_block.Toplevel, + (LocatedToken) $13, GetLocation ($1)); } + + current_block.AddStatement (new ContextualReturn ((Expression) $12)); + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + if ($13 == null) + ((Linq.QueryBlock)current_block).AddTransparentParameter (lt); + else + ((Linq.QueryBlock)current_block).AddTransparentParameter ((LocatedToken) $13); } ; @@ -5326,65 +5626,83 @@ opt_join_into : /* empty */ | INTO IDENTIFIER { - $$ = $2; + $$ = $2; } ; orderby_clause - : ORDERBY orderings + : ORDERBY { - $$ = $2; + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + orderings + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + $$ = $3; } ; orderings : order_by - | order_by COMMA orderings_then_by + | order_by COMMA + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + orderings_then_by { - ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$3; + ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4; $$ = $1; } ; orderings_then_by : then_by - { - $$ = $1; - } - | orderings_then_by COMMA then_by - { + | orderings_then_by COMMA + { + current_block.SetEndLocation (lexer.Location); + current_block = current_block.Parent; + + current_block = new Linq.QueryBlock (current_block, lexer.Location); + } + then_by + { ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$3; $$ = $1; - } + } ; order_by : expression { - $$ = new Linq.OrderByAscending ((Expression)$1); + $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.OrderByAscending ((Expression)$1); + $$ = new Linq.OrderByAscending (current_block.Toplevel, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.OrderByDescending ((Expression)$1); + $$ = new Linq.OrderByDescending (current_block.Toplevel, (Expression)$1); } ; then_by : expression { - $$ = new Linq.ThenByAscending ((Expression)$1); + $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); } | expression ASCENDING { - $$ = new Linq.ThenByAscending ((Expression)$1); + $$ = new Linq.ThenByAscending (current_block.Toplevel, (Expression)$1); } | expression DESCENDING { - $$ = new Linq.ThenByDescending ((Expression)$1); + $$ = new Linq.ThenByDescending (current_block.Toplevel, (Expression)$1); } ; @@ -5399,16 +5717,12 @@ opt_query_continuation current_block.SetEndLocation (GetLocation ($1)); current_block = current_block.Parent; - current_block = new Linq.QueryBlock (current_block, GetLocation ($1)); - LocatedToken lt = (LocatedToken) $2; - current_block.AddVariable (Linq.ImplicitQueryParameter.ImplicitType.Instance, - lt.Value, lt.Location); + current_block = new Linq.QueryBlock (current_block, (LocatedToken) $2, GetLocation ($1)); } query_body { - $$ = new Linq.QueryExpression ((LocatedToken) $2, - (Linq.AQueryClause)$4); + $$ = new Linq.QueryExpression (current_block, (Linq.AQueryClause)$4); } ; @@ -5429,20 +5743,20 @@ interactive_parsing : EVAL_STATEMENT_PARSER EOF | EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives | EVAL_STATEMENT_PARSER { - InteractiveShell.LoadAliases (current_namespace); + Evaluator.LoadAliases (current_namespace); push_current_class (new Class (current_namespace, current_class, new MemberName ("Class" + class_count++), Modifiers.PUBLIC, null), null); ArrayList baseclass_list = new ArrayList (); - baseclass_list.Add (new TypeExpression (typeof (InteractiveBase), lexer.Location)); + baseclass_list.Add (new TypeExpression (Evaluator.InteractiveBaseClass, lexer.Location)); current_container.AddBasesForPart (current_class, baseclass_list); // (ref object retval) Parameter [] mpar = new Parameter [1]; mpar [0] = new Parameter (TypeManager.system_object_expr, "$retval", Parameter.Modifier.REF, null, Location.Null); - Parameters pars = new Parameters (mpar); + ParametersCompiled pars = new ParametersCompiled (mpar); current_local_parameters = pars; Method method = new Method ( current_class, @@ -5457,7 +5771,7 @@ interactive_parsing ++lexer.parsing_block; start_block (lexer.Location); } - interactive_statement_list + interactive_statement_list opt_COMPLETE_COMPLETION { --lexer.parsing_block; Method method = (Method) oob_stack.Pop (); @@ -5465,13 +5779,31 @@ interactive_parsing method.Block = (ToplevelBlock) end_block(lexer.Location); current_container.AddMethod (method); + --lexer.parsing_declaration; InteractiveResult = pop_current_class (); current_local_parameters = null; } -// | EVAL_COMPILATION_UNIT_PARSER { -// InteractiveShell.LoadAliases (current_namespace); -// } -// compilation_unit + | EVAL_COMPILATION_UNIT_PARSER { + Evaluator.LoadAliases (current_namespace); + } + interactive_compilation_unit + ; + +interactive_compilation_unit + : outer_declarations + | outer_declarations global_attributes + | global_attributes + | /* nothing */ + ; + +opt_COMPLETE_COMPLETION + : /* nothing */ + | COMPLETE_COMPLETION + ; + +close_brace_or_complete_completion + : CLOSE_BRACE + | COMPLETE_COMPLETION ; %% @@ -5502,25 +5834,24 @@ public class VariableDeclaration { } } -// -// A class used to hold info about an indexer declarator -// -public class IndexerDeclaration { - public FullNamedExpression type; - public MemberName interface_type; - public Parameters param_list; - public Location location; - - public IndexerDeclaration (FullNamedExpression type, MemberName interface_type, - Parameters param_list, Location loc) +class VariableMemberDeclaration +{ + public readonly MemberName MemberName; + public Expression expression_or_array_initializer; + + public VariableMemberDeclaration (MemberName mn, object initializer) { - this.type = type; - this.interface_type = interface_type; - this.param_list = param_list; - this.location = loc; + MemberName = mn; + + if (initializer is ArrayList) { + this.expression_or_array_initializer = new ArrayCreation (CSharpParser.current_array_type, "", (ArrayList)initializer, mn.Location); + } else { + this.expression_or_array_initializer = (Expression)initializer; + } } } + // // A class used to hold info about an operator declarator // @@ -5575,7 +5906,7 @@ void push_current_class (TypeContainer tc, object partial_token) else current_container = current_container.AddTypeContainer (tc); - + ++lexer.parsing_declaration; current_class = tc; } @@ -5598,7 +5929,7 @@ MakeName (MemberName class_name) { Namespace ns = current_namespace.NS; - if (current_container.Name.Length == 0){ + if (current_container == RootContext.ToplevelTypes) { if (ns.Name.Length != 0) return new MemberName (ns.MemberName, class_name); else @@ -5646,11 +5977,12 @@ Block declare_local_variables (Expression type, ArrayList variable_declarators, assign = new SimpleAssign (new SimpleName (decl.identifier, decl.Location), var); current_block.AddStatement (new StatementExpression (assign)); } else { - Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC, decl.identifier, null, loc); + Field f = new Field (current_container, (FullNamedExpression) type, Modifiers.PUBLIC | Modifiers.STATIC, + new MemberName (decl.identifier, loc), null); current_container.AddField (f); // Register the field to be visible later as a global variable - InteractiveShell.QueueField (f); + Evaluator.QueueField (f); } } @@ -5817,7 +6149,7 @@ public void parse () static void CheckToken (int error, int yyToken, string msg, Location loc) { if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD) - Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()); + Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken)); else Report.Error (error, loc, msg); } @@ -5868,16 +6200,20 @@ end_block (Location loc) } void -start_anonymous (bool lambda, Parameters parameters, Location loc) +start_anonymous (bool lambda, ParametersCompiled parameters, Location loc) { + if (RootContext.Version == LanguageVersion.ISO_1){ + Report.FeatureIsNotAvailable (loc, "anonymous methods"); + } + oob_stack.Push (current_anonymous_method); oob_stack.Push (current_local_parameters); current_local_parameters = parameters; current_anonymous_method = lambda - ? new LambdaExpression (parameters, loc) - : new AnonymousMethodExpression (parameters, loc); + ? new LambdaExpression (loc) + : new AnonymousMethodExpression (loc); // Force the next block to be created as a ToplevelBlock parsing_anonymous_method = true; @@ -5887,19 +6223,14 @@ start_anonymous (bool lambda, Parameters parameters, Location loc) * Completes the anonymous method processing, if lambda_expr is null, this * means that we have a Statement instead of an Expression embedded */ -AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block, Location loc) +AnonymousMethodExpression end_anonymous (ToplevelBlock anon_block) { AnonymousMethodExpression retval; - if (RootContext.Version == LanguageVersion.ISO_1){ - Report.FeatureIsNotAvailable (loc, "anonymous methods"); - retval = null; - } else { - current_anonymous_method.Block = anon_block; - retval = current_anonymous_method; - } + current_anonymous_method.Block = anon_block; + retval = current_anonymous_method; - current_local_parameters = (Parameters) oob_stack.Pop (); + current_local_parameters = (ParametersCompiled) oob_stack.Pop (); current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop (); return retval; @@ -5911,5 +6242,484 @@ public NamespaceEntry CurrentNamespace { } } + +void Error_SyntaxError (int token) +{ + Error_SyntaxError (0, token); +} + +void Error_SyntaxError (int error_code, int token) +{ + string symbol = GetSymbolName (token); + string expecting = GetExpecting (); + + if (error_code == 0) { + if (expecting == "`)'") + error_code = 1026; + else + error_code = 1525; + } + + if (expecting != null) + Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}', expecting {1}", + symbol, expecting); + else + Report.Error (error_code, lexer.Location, "Unexpected symbol `{0}'", symbol); +} + +string GetExpecting () +{ + int [] tokens = yyExpectingTokens (yyExpectingState); + ArrayList names = new ArrayList (tokens.Length); + bool has_type = false; + bool has_identifier = false; + for (int i = 0; i < tokens.Length; i++){ + int token = tokens [i]; + has_identifier |= token == Token.IDENTIFIER; + + string name = GetTokenName (token); + if (name == "") + continue; + + has_type |= name == "type"; + if (names.Contains (name)) + continue; + + names.Add (name); + } + + // + // Too many tokens to enumerate + // + if (names.Count > 8) + return null; + + if (has_type && has_identifier) + names.Remove ("identifier"); + + if (names.Count == 1) + return "`" + GetTokenName (tokens [0]) + "'"; + + StringBuilder sb = new StringBuilder (); + names.Sort (); + int count = names.Count; + for (int i = 0; i < count; i++){ + bool last = i + 1 == count; + if (last) + sb.Append ("or "); + sb.Append ('`'); + sb.Append (names [i]); + sb.Append (last ? "'" : "', "); + } + return sb.ToString (); +} + + +string GetSymbolName (int token) +{ + switch (token){ + case Token.LITERAL_FLOAT: + case Token.LITERAL_INTEGER: + case Token.LITERAL_DOUBLE: + case Token.LITERAL_DECIMAL: + case Token.LITERAL_CHARACTER: + case Token.LITERAL_STRING: + return lexer.Value.ToString (); + case Token.IDENTIFIER: + return ((LocatedToken)lexer.Value).Value; + + case Token.BOOL: + return "bool"; + case Token.BYTE: + return "byte"; + case Token.CHAR: + return "char"; + case Token.VOID: + return "void"; + case Token.DECIMAL: + return "decimal"; + case Token.DOUBLE: + return "double"; + case Token.FLOAT: + return "float"; + case Token.INT: + return "int"; + case Token.LONG: + return "long"; + case Token.SBYTE: + return "sbyte"; + case Token.SHORT: + return "short"; + case Token.STRING: + return "string"; + case Token.UINT: + return "uint"; + case Token.ULONG: + return "ulong"; + case Token.USHORT: + return "ushort"; + case Token.OBJECT: + return "object"; + + case Token.PLUS: + return "+"; + case Token.UMINUS: + case Token.MINUS: + return "-"; + case Token.BANG: + return "!"; + case Token.BITWISE_AND: + return "&"; + case Token.BITWISE_OR: + return "|"; + case Token.STAR: + return "*"; + case Token.PERCENT: + return "%"; + case Token.DIV: + return "/"; + case Token.CARRET: + return "^"; + case Token.OP_INC: + return "++"; + case Token.OP_DEC: + return "--"; + case Token.OP_SHIFT_LEFT: + return "<<"; + case Token.OP_SHIFT_RIGHT: + return ">>"; + case Token.OP_LT: + return "<"; + case Token.OP_GT: + return ">"; + case Token.OP_LE: + return "<="; + case Token.OP_GE: + return ">="; + case Token.OP_EQ: + return "=="; + case Token.OP_NE: + return "!="; + case Token.OP_AND: + return "&&"; + case Token.OP_OR: + return "||"; + case Token.OP_PTR: + return "->"; + case Token.OP_COALESCING: + return "??"; + case Token.OP_MULT_ASSIGN: + return "*="; + case Token.OP_DIV_ASSIGN: + return "/="; + case Token.OP_MOD_ASSIGN: + return "%="; + case Token.OP_ADD_ASSIGN: + return "+="; + case Token.OP_SUB_ASSIGN: + return "-="; + case Token.OP_SHIFT_LEFT_ASSIGN: + return "<<="; + case Token.OP_SHIFT_RIGHT_ASSIGN: + return ">>="; + case Token.OP_AND_ASSIGN: + return "&="; + case Token.OP_XOR_ASSIGN: + return "^="; + case Token.OP_OR_ASSIGN: + return "|="; + } + + return GetTokenName (token); +} + +static string GetTokenName (int token) +{ + switch (token){ + case Token.ABSTRACT: + return "abstract"; + case Token.AS: + return "as"; + case Token.ADD: + return "add"; + case Token.BASE: + return "base"; + case Token.BREAK: + return "break"; + case Token.CASE: + return "case"; + case Token.CATCH: + return "catch"; + case Token.CHECKED: + return "checked"; + case Token.CLASS: + return "class"; + case Token.CONST: + return "const"; + case Token.CONTINUE: + return "continue"; + case Token.DEFAULT: + return "default"; + case Token.DELEGATE: + return "delegate"; + case Token.DO: + return "do"; + case Token.ELSE: + return "else"; + case Token.ENUM: + return "enum"; + case Token.EVENT: + return "event"; + case Token.EXPLICIT: + return "explicit"; + case Token.EXTERN: + return "extern"; + case Token.FALSE: + return "false"; + case Token.FINALLY: + return "finally"; + case Token.FIXED: + return "fixed"; + case Token.FOR: + return "for"; + case Token.FOREACH: + return "foreach"; + case Token.GOTO: + return "goto"; + case Token.IF: + return "if"; + case Token.IMPLICIT: + return "implicit"; + case Token.IN: + return "in"; + case Token.INTERFACE: + return "interface"; + case Token.INTERNAL: + return "internal"; + case Token.IS: + return "is"; + case Token.LOCK: + return "lock"; + case Token.NAMESPACE: + return "namespace"; + case Token.NEW: + return "new"; + case Token.NULL: + return "null"; + case Token.OPERATOR: + return "operator"; + case Token.OUT: + return "out"; + case Token.OVERRIDE: + return "override"; + case Token.PARAMS: + return "params"; + case Token.PRIVATE: + return "private"; + case Token.PROTECTED: + return "protected"; + case Token.PUBLIC: + return "public"; + case Token.READONLY: + return "readonly"; + case Token.REF: + return "ref"; + case Token.RETURN: + return "return"; + case Token.REMOVE: + return "remove"; + case Token.SEALED: + return "sealed"; + case Token.SIZEOF: + return "sizeof"; + case Token.STACKALLOC: + return "stackalloc"; + case Token.STATIC: + return "static"; + case Token.STRUCT: + return "struct"; + case Token.SWITCH: + return "switch"; + case Token.THIS: + return "this"; + case Token.THROW: + return "throw"; + case Token.TRUE: + return "true"; + case Token.TRY: + return "try"; + case Token.TYPEOF: + return "typeof"; + case Token.UNCHECKED: + return "unchecked"; + case Token.UNSAFE: + return "unsafe"; + case Token.USING: + return "using"; + case Token.VIRTUAL: + return "virtual"; + case Token.VOLATILE: + return "volatile"; + case Token.WHERE: + return "where"; + case Token.WHILE: + return "while"; + case Token.ARGLIST: + return "__arglist"; + case Token.PARTIAL: + return "partial"; + case Token.ARROW: + return "=>"; + case Token.FROM: + case Token.FROM_FIRST: + return "from"; + case Token.JOIN: + return "join"; + case Token.ON: + return "on"; + case Token.EQUALS: + return "equals"; + case Token.SELECT: + return "select"; + case Token.GROUP: + return "group"; + case Token.BY: + return "by"; + case Token.LET: + return "let"; + case Token.ORDERBY: + return "orderby"; + case Token.ASCENDING: + return "ascending"; + case Token.DESCENDING: + return "descending"; + case Token.INTO: + return "into"; + case Token.GET: + return "get"; + case Token.SET: + return "set"; + case Token.OPEN_BRACE: + return "{"; + case Token.CLOSE_BRACE: + return "}"; + case Token.OPEN_BRACKET: + return "["; + case Token.CLOSE_BRACKET: + return "]"; + case Token.OPEN_PARENS_CAST: + case Token.OPEN_PARENS_LAMBDA: + case Token.OPEN_PARENS: + return "("; + case Token.CLOSE_PARENS: + return ")"; + case Token.DOT: + return "."; + case Token.COMMA: + return ","; + case Token.DEFAULT_COLON: + return "default:"; + case Token.COLON: + return ":"; + case Token.SEMICOLON: + return ";"; + case Token.TILDE: + return "~"; + + case Token.PLUS: + case Token.UMINUS: + case Token.MINUS: + case Token.BANG: + case Token.OP_LT: + case Token.OP_GT: + case Token.BITWISE_AND: + case Token.BITWISE_OR: + case Token.STAR: + case Token.PERCENT: + case Token.DIV: + case Token.CARRET: + case Token.OP_INC: + case Token.OP_DEC: + case Token.OP_SHIFT_LEFT: + case Token.OP_SHIFT_RIGHT: + case Token.OP_LE: + case Token.OP_GE: + case Token.OP_EQ: + case Token.OP_NE: + case Token.OP_AND: + case Token.OP_OR: + case Token.OP_PTR: + case Token.OP_COALESCING: + case Token.OP_MULT_ASSIGN: + case Token.OP_DIV_ASSIGN: + case Token.OP_MOD_ASSIGN: + case Token.OP_ADD_ASSIGN: + case Token.OP_SUB_ASSIGN: + case Token.OP_SHIFT_LEFT_ASSIGN: + case Token.OP_SHIFT_RIGHT_ASSIGN: + case Token.OP_AND_ASSIGN: + case Token.OP_XOR_ASSIGN: + case Token.OP_OR_ASSIGN: + return ""; + + case Token.BOOL: + case Token.BYTE: + case Token.CHAR: + case Token.VOID: + case Token.DECIMAL: + case Token.DOUBLE: + case Token.FLOAT: + case Token.INT: + case Token.LONG: + case Token.SBYTE: + case Token.SHORT: + case Token.STRING: + case Token.UINT: + case Token.ULONG: + case Token.USHORT: + case Token.OBJECT: + return "type"; + + case Token.ASSIGN: + return "="; + case Token.OP_GENERICS_LT: + case Token.GENERIC_DIMENSION: + return "<"; + case Token.OP_GENERICS_GT: + return ">"; + case Token.INTERR: + case Token.INTERR_NULLABLE: + return "?"; + case Token.DOUBLE_COLON: + return "::"; + case Token.LITERAL_FLOAT: + case Token.LITERAL_INTEGER: + case Token.LITERAL_DOUBLE: + case Token.LITERAL_DECIMAL: + case Token.LITERAL_CHARACTER: + case Token.LITERAL_STRING: + return "value"; + case Token.IDENTIFIER: + return "identifier"; + + // All of these are internal. + case Token.NONE: + case Token.ERROR: + case Token.FIRST_KEYWORD: + case Token.EOF: + case Token.EVAL_COMPILATION_UNIT_PARSER: + case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER: + case Token.EVAL_STATEMENT_PARSER: + case Token.LAST_KEYWORD: + case Token.GENERATE_COMPLETION: + case Token.COMPLETE_COMPLETION: + return ""; + + // A bit more robust. + default: + return yyNames [token]; + } +} + /* end end end */ }