X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fcs-parser.jay;h=902690017e992da6e112221bbd8078cc1d7751c8;hb=7a345a73f5cdd9f89fb6103d0b52b745a8f1dd45;hp=056694106bc6d5731a29c010f6cc4c8f70accdaf;hpb=f7b665e1aad4259cf2d219f3740d9fdee8a48a05;p=mono.git diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 056694106bc..902690017e9 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -139,6 +139,7 @@ namespace Mono.CSharp // LocationsBag lbag; List> mod_locations; + Stack location_stack; %} %token EOF @@ -521,7 +522,7 @@ namespace_declaration if (doc_support) Lexer.doc_state = XmlCommentState.Allowed; } - opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon + opt_extern_alias_directives opt_using_directives opt_namespace_or_type_declarations CLOSE_BRACE opt_semicolon_error { if ($11 != null) lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($5), GetLocation ($10), GetLocation ($11)); @@ -530,6 +531,25 @@ namespace_declaration current_container = current_namespace = current_namespace.Parent; } + | opt_attributes NAMESPACE namespace_name + { + report.Error (1514, lexer.Location, "Unexpected symbol `{0}', expecting `.' or `{{'", GetSymbolName (yyToken)); + + var name = (MemberName) $3; + var ns = new NamespaceContainer (name, current_namespace); + lbag.AddLocation (ns, GetLocation ($2)); + current_namespace.AddTypeContainer (ns); + } + ; + +opt_semicolon_error + : /* empty */ + | SEMICOLON + | error + { + Error_SyntaxError (yyToken); + $$ = null; + } ; namespace_name @@ -656,6 +676,7 @@ attribute_sections attribute_section : OPEN_BRACKET { + PushLocation (GetLocation ($1)); lexer.parsing_attribute_section = true; } attribute_section_cont @@ -680,13 +701,43 @@ attribute_section_cont $$ = new List (0); else $$ = $4; - + + lbag.InsertLocation ($$, 0, PopLocation ()); + if ($5 != null) { + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($5), GetLocation ($6)); + } else { + lbag.AddLocation ($$, GetLocation ($2), GetLocation ($6)); + } + current_attr_target = null; lexer.parsing_attribute_section = false; } | attribute_list opt_comma CLOSE_BRACKET { $$ = $1; + + lbag.InsertLocation ($$, 0, PopLocation ()); + if ($2 != null) { + lbag.AddLocation ($$, GetLocation($2), GetLocation ($3)); + } else { + lbag.AddLocation ($$, GetLocation($3)); + } + } + | IDENTIFIER error + { + Error_SyntaxError (yyToken); + + var lt = (Tokenizer.LocatedToken) $1; + var tne = new SimpleName (lt.Value, null, lt.Location); + + $$ = new List () { + new Attribute (null, tne, null, GetLocation ($1), false) + }; + } + | error + { + $$ = CheckAttributeTarget (GetTokenName (yyToken), GetLocation ($1)); + $$ = null; } ; @@ -698,16 +749,6 @@ attribute_target } | EVENT { $$ = "event"; } | RETURN { $$ = "return"; } - | error - { - if (yyToken == Token.IDENTIFIER) { - Error_SyntaxError (yyToken); - $$ = null; - } else { - string name = GetTokenName (yyToken); - $$ = CheckAttributeTarget (name, GetLocation ($1)); - } - } ; attribute_list @@ -718,7 +759,10 @@ attribute_list | attribute_list COMMA attribute { var attrs = (List) $1; - attrs.Add ((Attribute) $3); + if (attrs != null) { + attrs.Add ((Attribute) $3); + lbag.AppendTo (attrs, GetLocation ($2)); + } $$ = attrs; } @@ -800,6 +844,11 @@ positional_or_named_argument $$ = new Argument ((Expression) $1); } | named_argument + | error + { + Error_SyntaxError (yyToken); + $$ = null; + } ; named_attribute_argument @@ -871,13 +920,14 @@ class_member_declaration | destructor_declaration | type_declaration | attributes_without_members + | incomplete_member | 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 @@ -886,10 +936,10 @@ struct_declaration opt_partial STRUCT { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); } opt_class_base @@ -956,6 +1006,14 @@ constant_declaration lbag.AddMember (current_field, mod_locations, GetLocation ($3), GetLocation ($9)); current_field = null; } + | opt_attributes + opt_modifiers + CONST type error + { + Error_SyntaxError (yyToken); + + current_type.AddMember (new Const (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1)); + } ; opt_constant_declarators @@ -1181,10 +1239,7 @@ method_declaration if (doc_support) Lexer.doc_state = XmlCommentState.NotAllowed; - // Add it early in the case of body being eof for full ast - Method m = (Method) $1; - async_block = (m.ModFlags & Modifiers.ASYNC) != 0; - current_type.AddMember (m); + // Was added earlier in the case of body being eof for full ast } method_body { @@ -1223,26 +1278,36 @@ method_header } opt_formal_parameter_list CLOSE_PARENS { - lexer.ConstraintsParsing = true; - } - opt_type_parameter_constraints_clauses - { - lexer.ConstraintsParsing = false; valid_param_mod = 0; MemberName name = (MemberName) $4; current_local_parameters = (ParametersCompiled) $7; var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2, - name, current_local_parameters, (Attributes) $1, $10 != null); + name, current_local_parameters, (Attributes) $1); + + current_type.AddMember (method); + + async_block = (method.ModFlags & Modifiers.ASYNC) != 0; - if ($10 != null) - method.SetConstraints ((List) $10); - if (doc_support) method.DocComment = Lexer.consume_doc_comment (); lbag.AddMember (method, mod_locations, GetLocation ($5), GetLocation ($8)); + $$ = method; + + lexer.ConstraintsParsing = true; + } + opt_type_parameter_constraints_clauses + { + lexer.ConstraintsParsing = false; + + if ($10 != null) { + var method = (Method) $9; + method.SetConstraints ((List) $10); + } + + $$ = $9; } | opt_attributes opt_modifiers @@ -1273,7 +1338,9 @@ method_header modifiers |= Modifiers.PARTIAL; var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($4)), - modifiers, name, current_local_parameters, (Attributes) $1, $11 != null); + modifiers, name, current_local_parameters, (Attributes) $1); + + current_type.AddMember (method); if ($11 != null) method.SetConstraints ((List) $11); @@ -1295,7 +1362,9 @@ method_header "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4)); var method = Method.Create (current_type, (FullNamedExpression) $3, - 0, name, (ParametersCompiled) $7, (Attributes) $1, false); + 0, name, (ParametersCompiled) $7, (Attributes) $1); + + current_type.AddMember (method); current_local_parameters = (ParametersCompiled) $7; @@ -1314,7 +1383,9 @@ method_header MemberName name = (MemberName) $4; var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2, - name, current_local_parameters, (Attributes) $1, false); + name, current_local_parameters, (Attributes) $1); + + current_type.AddMember (method); if (doc_support) method.DocComment = Lexer.consume_doc_comment (); @@ -1433,7 +1504,7 @@ fixed_parameter : opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER + identifier_inside_body { var lt = (Tokenizer.LocatedToken) $4; $$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location); @@ -1441,7 +1512,7 @@ fixed_parameter | opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER OPEN_BRACKET CLOSE_BRACKET + identifier_inside_body OPEN_BRACKET CLOSE_BRACKET { var lt = (Tokenizer.LocatedToken) $4; report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name"); @@ -1465,7 +1536,7 @@ fixed_parameter | opt_attributes opt_parameter_modifier parameter_type - IDENTIFIER + identifier_inside_body ASSIGN { ++lexer.parsing_block; @@ -1663,7 +1734,7 @@ indexer_declaration { valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue; } - opt_formal_parameter_list CLOSE_BRACKET OPEN_BRACE + opt_formal_parameter_list CLOSE_BRACKET { valid_param_mod = 0; var type = (FullNamedExpression) $3; @@ -1672,7 +1743,7 @@ indexer_declaration current_property = indexer; current_type.AddIndexer (indexer); - lbag.AddMember (current_property, mod_locations, GetLocation ($5), GetLocation ($8), GetLocation ($9)); + lbag.AddMember (current_property, mod_locations, GetLocation ($5), GetLocation ($8)); if (type.Type != null && type.Type.Kind == MemberKind.Void) report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ()); @@ -1688,7 +1759,7 @@ indexer_declaration lexer.PropertyParsing = true; } - accessor_declarations + OPEN_BRACE accessor_declarations { lexer.PropertyParsing = false; } @@ -1700,7 +1771,7 @@ indexer_declaration if (doc_support) current_property.DocComment = ConsumeStoredComment (); - lbag.AppendToMember (current_property, GetLocation ($12)); + lbag.AppendToMember (current_property, GetLocation ($10), GetLocation ($13)); current_property = null; } ; @@ -1835,10 +1906,10 @@ interface_declaration opt_partial INTERFACE { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3); lbag.AddMember (current_container, mod_locations, GetLocation ($4)); } @@ -2049,7 +2120,11 @@ conversion_operator_declarator Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `implicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2068,7 +2143,11 @@ conversion_operator_declarator Location loc = GetLocation ($2); current_local_parameters = (ParametersCompiled)$6; - + + if (current_local_parameters.Count != 1) { + report.Error (1535, loc, "Overloaded unary operator `explicit' takes one parameter"); + } + if (doc_support) { tmpComment = Lexer.consume_doc_comment (); Lexer.doc_state = XmlCommentState.NotAllowed; @@ -2297,6 +2376,14 @@ event_declaration current_event = null; current_local_parameters = null; } + | opt_attributes + opt_modifiers + EVENT type error + { + Error_SyntaxError (yyToken); + + current_type.AddMember (new EventField (current_type, (FullNamedExpression) $4, (Modifiers) $2, MemberName.Null, (Attributes) $1)); + } ; opt_event_initializer @@ -2459,6 +2546,23 @@ attributes_without_members lexer.putback ('}'); } ; + +// For full ast try to recover incomplete ambiguous member +// declaration in form on class X { public int } +incomplete_member + : opt_attributes opt_modifiers member_type CLOSE_BRACE + { + report.Error (1519, lexer.Location, "Unexpected symbol `}' in class, struct, or interface member declaration"); + + lexer.putback ('}'); + + lexer.parsing_generic_declaration = false; + FullNamedExpression type = (FullNamedExpression) $3; + current_field = new Field (current_type, type, (Modifiers) $2, MemberName.Null, (Attributes) $1); + current_type.AddField (current_field); + $$ = current_field; + } + ; enum_declaration : opt_attributes @@ -3043,35 +3147,35 @@ close_parens parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS { - $$ = new ParenthesizedExpression ((Expression) $2); + $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); } | OPEN_PARENS expression COMPLETE_COMPLETION { - $$ = new ParenthesizedExpression ((Expression) $2); + $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1)); } ; member_access - : primary_expression DOT IDENTIFIER opt_type_argument_list + : primary_expression DOT identifier_inside_body opt_type_argument_list { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | builtin_types DOT IDENTIFIER opt_type_argument_list + | builtin_types DOT identifier_inside_body opt_type_argument_list { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | BASE DOT IDENTIFIER opt_type_argument_list + | BASE DOT identifier_inside_body opt_type_argument_list { var lt = (Tokenizer.LocatedToken) $3; $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | qualified_alias_member IDENTIFIER opt_type_argument_list + | qualified_alias_member identifier_inside_body opt_type_argument_list { var lt1 = (Tokenizer.LocatedToken) $1; var lt2 = (Tokenizer.LocatedToken) $2; @@ -3109,7 +3213,13 @@ invocation_expression $$ = new Invocation ((Expression) $1, (Arguments) $3); lbag.AddLocation ($$, GetLocation ($2)); } - + | primary_expression open_parens_any error + { + Error_SyntaxError (yyToken); + + $$ = new Invocation ((Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; opt_object_or_collection_initializer @@ -3121,12 +3231,11 @@ object_or_collection_initializer : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion { if ($2 == null) { - $$ = CollectionOrObjectInitializers.Empty; - // TODO: lbag + $$ = new CollectionOrObjectInitializers (GetLocation ($1)); } else { $$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($3)); } + lbag.AddLocation ($$, GetLocation ($3)); } | OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE { @@ -3169,6 +3278,12 @@ member_initializer $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } + | AWAIT ASSIGN initializer_value + { + var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1); + $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location); + lbag.AddLocation ($$, GetLocation ($2)); + } | GENERATE_COMPLETION { $$ = new CompletionElementInitializer (null, GetLocation ($1)); @@ -3191,7 +3306,7 @@ member_initializer { report.Error (1920, GetLocation ($1), "An element initializer cannot be empty"); $$ = null; - } + } ; initializer_value @@ -3307,22 +3422,18 @@ element_access ; expression_list - : expression + : expression_or_error { var list = new List (4); list.Add ((Expression) $1); $$ = list; } - | expression_list COMMA expression + | expression_list COMMA expression_or_error { var list = (List) $1; list.Add ((Expression) $3); $$ = list; } - | expression_list error { - Error_SyntaxError (yyToken); - $$ = $1; - } ; expression_list_arguments @@ -3496,13 +3607,13 @@ anonymous_type_parameters ; anonymous_type_parameter - : IDENTIFIER ASSIGN variable_initializer + : identifier_inside_body ASSIGN variable_initializer { var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location); lbag.AddLocation ($$, GetLocation ($2)); } - | IDENTIFIER + | identifier_inside_body { var lt = (Tokenizer.LocatedToken)$1; $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location), @@ -3694,6 +3805,13 @@ sizeof_expression $$ = new SizeOf ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | SIZEOF open_parens_any type error + { + Error_SyntaxError (yyToken); + + $$ = new SizeOf ((Expression) $3, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($2)); + } ; checked_expression @@ -3702,6 +3820,12 @@ checked_expression $$ = new CheckedExpr ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | CHECKED error + { + Error_SyntaxError (yyToken); + + $$ = new CheckedExpr (null, GetLocation ($1)); + } ; unchecked_expression @@ -3710,6 +3834,12 @@ unchecked_expression $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); } + | UNCHECKED error + { + Error_SyntaxError (yyToken); + + $$ = new UnCheckedExpr (null, GetLocation ($1)); + } ; pointer_member_access @@ -3804,6 +3934,31 @@ unary_expression $$ = new Await ((Expression) $2, GetLocation ($1)); } + | BANG error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.LogicalNot, null, GetLocation ($1)); + } + | TILDE error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.OnesComplement, null, GetLocation ($1)); + } + | OPEN_PARENS_CAST type CLOSE_PARENS error + { + Error_SyntaxError (yyToken); + + $$ = new Cast ((FullNamedExpression) $2, null, GetLocation ($1)); + lbag.AddLocation ($$, GetLocation ($3)); + } + | AWAIT error + { + Error_SyntaxError (yyToken); + + $$ = new Await (null, GetLocation ($1)); + } ; // @@ -3836,6 +3991,42 @@ prefixed_unary_expression { $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1)); } + | PLUS error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.UnaryPlus, null, GetLocation ($1)); + } + | MINUS error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.UnaryNegation, null, GetLocation ($1)); + } + | OP_INC error + { + Error_SyntaxError (yyToken); + + $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, null, GetLocation ($1)); + } + | OP_DEC error + { + Error_SyntaxError (yyToken); + + $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, null, GetLocation ($1)); + } + | STAR error + { + Error_SyntaxError (yyToken); + + $$ = new Indirection (null, GetLocation ($1)); + } + | BITWISE_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Unary (Unary.Operator.AddressOf, null, GetLocation ($1)); + } ; multiplicative_expression @@ -3855,6 +4046,27 @@ multiplicative_expression $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | multiplicative_expression STAR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | multiplicative_expression DIV error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Division, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | multiplicative_expression PERCENT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; additive_expression @@ -3877,6 +4089,32 @@ additive_expression { $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2)); } + | additive_expression PLUS error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Addition, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | additive_expression MINUS error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | additive_expression AS error + { + Error_SyntaxError (yyToken); + + $$ = new As ((Expression) $1, null, GetLocation ($2)); + } + | additive_expression IS error + { + Error_SyntaxError (yyToken); + + $$ = new Is ((Expression) $1, null, GetLocation ($2)); + } ; shift_expression @@ -3891,6 +4129,20 @@ shift_expression $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | shift_expression OP_SHIFT_LEFT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | shift_expression OP_SHIFT_RIGHT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; relational_expression @@ -3915,6 +4167,34 @@ relational_expression $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | relational_expression OP_LT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_GT error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_LE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | relational_expression OP_GE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; equality_expression @@ -3929,6 +4209,20 @@ equality_expression $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | equality_expression OP_EQ error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Equality, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } + | equality_expression OP_NE error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; and_expression @@ -3938,6 +4232,13 @@ and_expression $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | and_expression BITWISE_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; exclusive_or_expression @@ -3947,6 +4248,13 @@ exclusive_or_expression $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | exclusive_or_expression CARRET error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; inclusive_or_expression @@ -3956,6 +4264,13 @@ inclusive_or_expression $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | inclusive_or_expression BITWISE_OR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; conditional_and_expression @@ -3965,6 +4280,13 @@ conditional_and_expression $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | conditional_and_expression OP_AND error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; conditional_or_expression @@ -3974,6 +4296,13 @@ conditional_or_expression $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3); lbag.AddLocation ($$, GetLocation ($2)); } + | conditional_or_expression OP_OR error + { + Error_SyntaxError (yyToken); + + $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, null); + lbag.AddLocation ($$, GetLocation ($2)); + } ; null_coalescing_expression @@ -3990,7 +4319,7 @@ null_coalescing_expression conditional_expression : null_coalescing_expression - | null_coalescing_expression INTERR expression COLON expression_or_error + | null_coalescing_expression INTERR expression COLON expression { $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($4)); @@ -3998,7 +4327,23 @@ conditional_expression | null_coalescing_expression INTERR expression error { Error_SyntaxError (yyToken); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + } + | null_coalescing_expression INTERR expression COLON error + { + Error_SyntaxError (yyToken); + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + } + | null_coalescing_expression INTERR expression COLON CLOSE_BRACE + { + Error_SyntaxError (Token.CLOSE_BRACE); + + $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2)); + lbag.AddLocation ($$, GetLocation ($4)); + lexer.putback ('}'); } ; @@ -4099,6 +4444,11 @@ lambda_parameter var lt = (Tokenizer.LocatedToken) $1; $$ = new ImplicitLambdaParameter (lt.Value, lt.Location); } + | AWAIT + { + var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1); + $$ = new ImplicitLambdaParameter (lt.Value, lt.Location); + } ; opt_lambda_parameter_list @@ -4110,32 +4460,38 @@ opt_lambda_parameter_list ; lambda_expression_body - : lambda_expression_body_simple - | block - ; - -lambda_expression_body_simple : { start_block (Location.Null); } - expression_or_error // Have to close block when error occurs + expression // All expressions must handle error or current block won't be restored and breaking ast completely { Block b = end_block (Location.Null); b.IsCompilerGenerated = true; b.AddStatement (new ContextualReturn ((Expression) $2)); $$ = b; } + | block + | error + { + // Handles only cases like foo = x.FirstOrDefault (l => ); + // where we must restore current_variable + Block b = end_block (Location.Null); + b.IsCompilerGenerated = true; + + Error_SyntaxError (yyToken); + $$ = null; + } ; - + expression_or_error : expression | error { - Error_SyntaxError (yyToken); - $$ = EmptyExpression.Null; + Error_SyntaxError (yyToken); + $$ = null; } ; - + lambda_expression : IDENTIFIER ARROW { @@ -4148,6 +4504,17 @@ lambda_expression $$ = end_anonymous ((ParametersBlock) $4); lbag.AddLocation ($$, GetLocation ($2)); } + | AWAIT ARROW + { + var lt = (Tokenizer.LocatedToken) Error_AwaitAsIdentifier ($1); + Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location); + start_anonymous (true, new ParametersCompiled (p), false, lt.Location); + } + lambda_expression_body + { + $$ = end_anonymous ((ParametersBlock) $4); + lbag.AddLocation ($$, GetLocation ($2)); + } | ASYNC identifier_inside_body ARROW { var lt = (Tokenizer.LocatedToken) $2; @@ -4242,10 +4609,11 @@ class_declaration opt_partial CLASS { - lexer.ConstraintsParsing = true; } type_declaration_name { + lexer.ConstraintsParsing = true; + Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1); if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) { FeatureIsNotAvailable (c.Location, "static classes"); @@ -4822,10 +5190,7 @@ identifier_inside_body : IDENTIFIER | AWAIT { - if (async_block) { - report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression"); - $$ = new Tokenizer.LocatedToken ("await", GetLocation ($1)); - } + $$ = Error_AwaitAsIdentifier ($1); } ; @@ -4841,7 +5206,10 @@ block_variable_declaration { $$ = current_variable; current_variable = null; - lbag.AddLocation ($$, GetLocation ($6)); + if ($4 != null) + lbag.AddLocation ($$, PopLocation (), GetLocation ($6)); + else + lbag.AddLocation ($$, GetLocation ($6)); } | CONST variable_type identifier_inside_body { @@ -4863,7 +5231,8 @@ opt_local_variable_initializer | ASSIGN block_variable_initializer { current_variable.Initializer = (Expression) $2; - // TODO: lbag + PushLocation (GetLocation ($1)); + $$ = current_variable; } | error { @@ -4994,8 +5363,9 @@ statement_expression { ExpressionStatement s = $1 as ExpressionStatement; if (s == null) { - Expression.Error_InvalidExpressionStatement (report, GetLocation ($1)); - $$ = new StatementErrorExpression ($1 as Expression); + var expr = $1 as Expression; + expr.Error_InvalidExpressionStatement (report); + $$ = new StatementErrorExpression (expr); } else { $$ = new StatementExpression (s); } @@ -5060,7 +5430,7 @@ switch_statement } opt_switch_sections CLOSE_BRACE { - $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List) $7, GetLocation ($1)); + $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1)); end_block (GetLocation ($8)); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); } @@ -5068,7 +5438,7 @@ switch_statement { Error_SyntaxError (yyToken); - $$ = new Switch ((Expression) $3, null, null, GetLocation ($1)); + $$ = new Switch ((Expression) $3, null, GetLocation ($1)); lbag.AddStatement ($$, GetLocation ($2)); } ; @@ -5077,58 +5447,33 @@ opt_switch_sections : /* empty */ { report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); - $$ = new List (); } | switch_sections ; switch_sections : switch_section - { - var sections = new List (4); - - sections.Add ((SwitchSection) $1); - $$ = sections; - } | switch_sections switch_section - { - var sections = (List) $1; - - sections.Add ((SwitchSection) $2); - $$ = sections; - } | error { Error_SyntaxError (yyToken); - $$ = new List (); } ; switch_section - : switch_labels - { - current_block = current_block.CreateSwitchBlock (lexer.Location); - } - statement_list - { - $$ = new SwitchSection ((List) $1, current_block); - } + : switch_labels statement_list ; switch_labels : switch_label { - var labels = new List (2); - - labels.Add ((SwitchLabel) $1); - $$ = labels; + var label = (SwitchLabel) $1; + label.SectionStart = true; + current_block.AddStatement (label); } | switch_labels switch_label { - var labels = (List) ($1); - labels.Add ((SwitchLabel) $2); - - $$ = labels; + current_block.AddStatement ((Statement) $2); } ; @@ -5294,6 +5639,9 @@ for_initializer opt_local_variable_initializer opt_variable_declarators { $$ = current_variable; + if ($4 != null) + lbag.AddLocation (current_variable, PopLocation ()); + current_variable = null; } | statement_expression_list @@ -5509,7 +5857,7 @@ yield_statement FeatureIsNotAvailable (lt.Location, "iterators"); } - current_block.Explicit.RegisterIteratorYield (); + current_block.ParametersBlock.TopBlock.IsIterator = true; $$ = new YieldBreak (lt.Location); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3)); } @@ -5604,6 +5952,24 @@ catch_clause $$ = new Catch (null, GetLocation ($1)); } + | CATCH open_parens_any type opt_identifier CLOSE_PARENS error + { + Error_SyntaxError (yyToken); + + // Required otherwise missing block could not be detected because + // start_block is run early + var c = new Catch (null, GetLocation ($1)); + c.TypeExpression = (FullNamedExpression) $3; + + if ($4 != null) { + var lt = (Tokenizer.LocatedToken) $4; + c.Variable = new LocalVariable (current_block, lt.Value, lt.Location); + } + + lbag.AddLocation (c, GetLocation ($2), GetLocation ($5)); + + $$ = c; + } ; checked_statement @@ -5930,15 +6296,29 @@ select_or_group_clause current_block = new Linq.QueryBlock (current_block, lexer.Location); } - BY expression_or_error + by_expression { - $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1)); - lbag.AddLocation ($$, GetLocation ($5)); + var obj = (object[]) $5; + + $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)obj[0], GetLocation ($1)); + lbag.AddLocation ($$, (Location) obj[1]); current_block.SetEndLocation (lexer.Location); current_block = current_block.Parent; } ; + +by_expression + : BY expression_or_error + { + $$ = new object[] { $2, GetLocation ($1) }; + } + | error + { + Error_SyntaxError (yyToken); + $$ = new object[2] { null, Location.Null }; + } + ; query_body_clauses : query_body_clause @@ -6451,7 +6831,7 @@ void Error_ExpectingTypeName (Expression expr) if (expr is Invocation){ report.Error (1002, expr.Location, "Expecting `;'"); } else { - Expression.Error_InvalidExpressionStatement (report, expr.Location); + expr.Error_InvalidExpressionStatement (report); } } @@ -6492,6 +6872,16 @@ void Error_MissingInitializer (Location loc) report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration"); } +object Error_AwaitAsIdentifier (object token) +{ + if (async_block) { + report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression"); + return new Tokenizer.LocatedToken ("await", GetLocation (token)); + } + + return token; +} + void push_current_container (TypeDefinition tc, object partial_token) { if (module.Evaluator != null){ @@ -6534,6 +6924,23 @@ void StoreModifierLocation (object token, Location loc) mod_locations.Add (Tuple.Create ((Modifiers) token, loc)); } +[System.Diagnostics.Conditional ("FULL_AST")] +void PushLocation (Location loc) +{ + if (location_stack == null) + location_stack = new Stack (); + + location_stack.Push (loc); +} + +Location PopLocation () +{ + if (location_stack == null) + return Location.Null; + + return location_stack.Pop (); +} + string CheckAttributeTarget (string a, Location l) { switch (a) { @@ -6621,7 +7028,8 @@ public void parse () } if (e is yyParser.yyException) { - report.Error (-25, lexer.Location, "Parsing error"); + if (report.Errors == 0) + report.Error (-25, lexer.Location, "Parsing error"); } else { // Used by compiler-tester to test internal errors if (yacc_verbose_flag > 0 || e is FatalException)