//
LocationsBag lbag;
List<Tuple<Modifiers, Location>> mod_locations;
+ Stack<Location> location_stack;
%}
%token EOF
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));
}
;
+opt_semicolon_error
+ : /* empty */
+ | SEMICOLON
+ | error
+ {
+ Error_SyntaxError (yyToken);
+ $$ = null;
+ }
+ ;
+
namespace_name
: IDENTIFIER
{
attribute_section
: OPEN_BRACKET
{
+ PushLocation (GetLocation ($1));
lexer.parsing_attribute_section = true;
}
attribute_section_cont
$$ = new List<Attribute> (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<Attribute> () {
+ new Attribute (null, tne, null, GetLocation ($1), false)
+ };
+ }
+ | error
+ {
+ $$ = CheckAttributeTarget (GetTokenName (yyToken), GetLocation ($1));
+ $$ = null;
}
;
}
| EVENT { $$ = "event"; }
| RETURN { $$ = "return"; }
- | error
- {
- if (yyToken == Token.IDENTIFIER) {
- Error_SyntaxError (yyToken);
- $$ = null;
- } else {
- string name = GetTokenName (yyToken);
- $$ = CheckAttributeTarget (name, GetLocation ($1));
- }
- }
;
attribute_list
| attribute_list COMMA attribute
{
var attrs = (List<Attribute>) $1;
- attrs.Add ((Attribute) $3);
+ if (attrs != null) {
+ attrs.Add ((Attribute) $3);
+ lbag.AppendTo (attrs, GetLocation ($2));
+ }
$$ = attrs;
}
$$ = new Argument ((Expression) $1);
}
| named_argument
+ | error
+ {
+ Error_SyntaxError (yyToken);
+ $$ = null;
+ }
;
named_attribute_argument
| 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
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
: 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);
| 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");
| opt_attributes
opt_parameter_modifier
parameter_type
- IDENTIFIER
+ identifier_inside_body
ASSIGN
{
++lexer.parsing_block;
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));
}
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
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;
$$ = new Invocation ((Expression) $1, null);
lbag.AddLocation ($$, GetLocation ($2));
- }
+ }
;
opt_object_or_collection_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));
{
report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
$$ = null;
- }
+ }
;
initializer_value
;
expression_list
- : expression
+ : expression_or_error
{
var list = new List<Expression> (4);
list.Add ((Expression) $1);
$$ = list;
}
- | expression_list COMMA expression
+ | expression_list COMMA expression_or_error
{
var list = (List<Expression>) $1;
list.Add ((Expression) $3);
$$ = list;
}
- | expression_list error {
- Error_SyntaxError (yyToken);
- $$ = $1;
- }
;
expression_list_arguments
;
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),
$$ = 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 ('}');
+ }
;
assignment_expression
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
$$ = 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;
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");
: 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);
}
;
{
$$ = 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
{
| ASSIGN block_variable_initializer
{
current_variable.Initializer = (Expression) $2;
- // TODO: lbag
+ PushLocation (GetLocation ($1));
+ $$ = current_variable;
}
| error
{
}
opt_switch_sections CLOSE_BRACE
{
- $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, (List<SwitchSection>) $7, GetLocation ($1));
+ $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1));
end_block (GetLocation ($8));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
{
Error_SyntaxError (yyToken);
- $$ = new Switch ((Expression) $3, null, null, GetLocation ($1));
+ $$ = new Switch ((Expression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
: /* empty */
{
report.Warning (1522, 1, current_block.StartLocation, "Empty switch block");
- $$ = new List<SwitchSection> ();
}
| switch_sections
;
switch_sections
: switch_section
- {
- var sections = new List<SwitchSection> (4);
-
- sections.Add ((SwitchSection) $1);
- $$ = sections;
- }
| switch_sections switch_section
- {
- var sections = (List<SwitchSection>) $1;
-
- sections.Add ((SwitchSection) $2);
- $$ = sections;
- }
| error
{
Error_SyntaxError (yyToken);
- $$ = new List<SwitchSection> ();
}
;
switch_section
- : switch_labels
- {
- current_block = current_block.CreateSwitchBlock (lexer.Location);
- }
- statement_list
- {
- $$ = new SwitchSection ((List<SwitchLabel>) $1, current_block);
- }
+ : switch_labels statement_list
;
switch_labels
: switch_label
{
- var labels = new List<SwitchLabel> (2);
-
- labels.Add ((SwitchLabel) $1);
- $$ = labels;
+ var label = (SwitchLabel) $1;
+ label.SectionStart = true;
+ current_block.AddStatement (label);
}
| switch_labels switch_label
{
- var labels = (List<SwitchLabel>) ($1);
- labels.Add ((SwitchLabel) $2);
-
- $$ = labels;
+ current_block.AddStatement ((Statement) $2);
}
;
opt_local_variable_initializer opt_variable_declarators
{
$$ = current_variable;
+ if ($4 != null)
+ lbag.AddLocation (current_variable, PopLocation ());
+
current_variable = null;
}
| statement_expression_list
FeatureIsNotAvailable (lt.Location, "iterators");
}
- current_block.Explicit.RegisterIteratorYield ();
+ current_block.ParametersBlock.TopBlock.IsIterator = true;
$$ = new YieldBreak (lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
}
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
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){
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> ();
+
+ 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) {