ParametersCompiled current_local_parameters;
bool parsing_anonymous_method;
+
+ bool async_block;
///
/// An out-of-band stack.
;
named_argument
- : IDENTIFIER COLON opt_named_modifier expression
+ : identifier_inside_body COLON opt_named_modifier expression
{
if (lang_version <= LanguageVersion.V_3)
FeatureIsNotAvailable (GetLocation ($1), "named argument");
// Add it early in the case of body being eof for full ast
Method m = (Method) $1;
- lexer.async_block = (m.ModFlags & Modifiers.ASYNC) != 0;
+ async_block = (m.ModFlags & Modifiers.ASYNC) != 0;
current_container.AddMethod (m);
}
method_body
{
Method method = (Method) $1;
method.Block = (ToplevelBlock) $3;
- lexer.async_block = false;
+ async_block = false;
if (method.Block == null) {
method.ParameterInfo.CheckParameters (method);
;
unbound_type_name
- : IDENTIFIER generic_dimension
+ : identifier_inside_body generic_dimension
{
var lt = (Tokenizer.LocatedToken) $1;
$$ = new SimpleName (lt.Value, (int) $2, lt.Location);
}
- | qualified_alias_member IDENTIFIER generic_dimension
+ | qualified_alias_member identifier_inside_body generic_dimension
{
var lt1 = (Tokenizer.LocatedToken) $1;
var lt2 = (Tokenizer.LocatedToken) $2;
$$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
}
- | unbound_type_name DOT IDENTIFIER
+ | unbound_type_name DOT identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);
}
- | unbound_type_name DOT IDENTIFIER generic_dimension
+ | unbound_type_name DOT identifier_inside_body generic_dimension
{
var lt = (Tokenizer.LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
}
- | namespace_or_type_name DOT IDENTIFIER generic_dimension
+ | namespace_or_type_name DOT identifier_inside_body generic_dimension
{
var te = ((MemberName) $1).GetTypeExpression ();
if (te.HasTypeArguments)
{
$$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
}
- | cast_expression
- | await_expression
- ;
-
-cast_expression
- : OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
+ | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
{
$$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
- ;
-
-await_expression
- : AWAIT unary_expression
+ | AWAIT prefixed_unary_expression
{
- current_block.ParametersBlock.IsAsync = true;
+ if (!async_block) {
+ report.Error (1992, GetLocation ($1),
+ "The `await' operator can only be used when its containing method or lambda expression is marked with the `async' modifier");
+ } else {
+ current_block.ParametersBlock.IsAsync = true;
+ }
+
$$ = new Await ((Expression) $2, GetLocation ($1));
}
;
;
lambda_parameter
- : parameter_modifier parameter_type IDENTIFIER
+ : parameter_modifier parameter_type identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $3;
$$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
}
- | parameter_type IDENTIFIER
+ | parameter_type identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $2;
$$ = end_anonymous ((ParametersBlock) $4);
lbag.AddLocation ($$, GetLocation ($2));
}
- | ASYNC IDENTIFIER ARROW
+ | ASYNC identifier_inside_body ARROW
{
var lt = (Tokenizer.LocatedToken) $2;
Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
;
labeled_statement
- : IDENTIFIER COLON
+ : identifier_inside_body COLON
{
var lt = (Tokenizer.LocatedToken) $1;
LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
}
;
+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");
+ $$ = Tokenizer.LocatedToken.Create ("await", GetLocation ($1));
+ }
+ }
+ ;
+
block_variable_declaration
- : variable_type IDENTIFIER
+ : variable_type identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, lt.Location);
current_variable = null;
lbag.AddLocation ($$, GetLocation ($6));
}
- | CONST variable_type IDENTIFIER
+ | CONST variable_type identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $3;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
;
variable_declarator
- : COMMA IDENTIFIER
+ : COMMA identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $2;
var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
current_block.AddLocalName (li);
lbag.AddLocation (d, GetLocation ($1));
}
- | COMMA IDENTIFIER ASSIGN block_variable_initializer
+ | COMMA identifier_inside_body ASSIGN block_variable_initializer
{
var lt = (Tokenizer.LocatedToken) $2;
var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
;
const_declarator
- : COMMA IDENTIFIER ASSIGN constant_initializer_expr
+ : COMMA identifier_inside_body ASSIGN constant_initializer_expr
{
var lt = (Tokenizer.LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
;
for_initializer
- : variable_type IDENTIFIER
+ : variable_type identifier_inside_body
{
var lt = (Tokenizer.LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, lt.Location);
report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
$$ = null;
}
- | FOREACH open_parens_any type IDENTIFIER IN expression CLOSE_PARENS
+ | FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
;
goto_statement
- : GOTO IDENTIFIER SEMICOLON
+ : GOTO identifier_inside_body SEMICOLON
{
var lt = (Tokenizer.LocatedToken) $2;
$$ = new Goto (lt.Value, lt.Location);
;
yield_statement
- : IDENTIFIER RETURN opt_expression SEMICOLON
+ : identifier_inside_body RETURN opt_expression SEMICOLON
{
var lt = (Tokenizer.LocatedToken) $1;
string s = lt.Value;
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
- | IDENTIFIER BREAK SEMICOLON
+ | identifier_inside_body BREAK SEMICOLON
{
var lt = (Tokenizer.LocatedToken) $1;
string s = lt.Value;
opt_identifier
: /* empty */
- | IDENTIFIER
+ | identifier_inside_body
;
catch_clause
;
fixed_statement
- : FIXED open_parens_any variable_type IDENTIFIER
+ : FIXED open_parens_any variable_type identifier_inside_body
{
start_block (GetLocation ($2));
;
using_statement
- : USING open_parens_any variable_type IDENTIFIER
+ : USING open_parens_any variable_type identifier_inside_body
{
start_block (GetLocation ($2));
;
first_from_clause
- : FROM_FIRST IDENTIFIER IN expression
+ : FROM_FIRST identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
}
- | FROM_FIRST type IDENTIFIER IN expression
+ | FROM_FIRST type identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
;
nested_from_clause
- : FROM IDENTIFIER IN expression
+ : FROM identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
}
- | FROM type IDENTIFIER IN expression
+ | FROM type identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
;
from_clause
- : FROM IDENTIFIER IN
+ : FROM identifier_inside_body IN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
}
- | FROM type IDENTIFIER IN
+ | FROM type identifier_inside_body IN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
;
let_clause
- : LET IDENTIFIER ASSIGN
+ : LET identifier_inside_body ASSIGN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
;
join_clause
- : JOIN IDENTIFIER IN
+ : JOIN identifier_inside_body IN
{
if (linq_clause_blocks == null)
linq_clause_blocks = new Stack<Linq.QueryBlock> ();
current_block = block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (into);
}
- | JOIN type IDENTIFIER IN
+ | JOIN type identifier_inside_body IN
{
if (linq_clause_blocks == null)
linq_clause_blocks = new Stack<Linq.QueryBlock> ();
opt_join_into
: /* empty */
- | INTO IDENTIFIER
+ | INTO identifier_inside_body
{
$$ = $2;
}
opt_query_continuation
: /* empty */
- | INTO IDENTIFIER
+ | INTO identifier_inside_body
{
// query continuation block is not linked with query block but with block
// before. This means each query can use same range variable names for
oob_stack.Push (current_anonymous_method);
oob_stack.Push (current_local_parameters);
oob_stack.Push (current_variable);
- oob_stack.Push (lexer.async_block);
+ oob_stack.Push (async_block);
current_local_parameters = parameters;
if (isLambda) {
current_anonymous_method = new AnonymousMethodExpression (isAsync, loc);
}
- lexer.async_block = isAsync;
+ async_block = isAsync;
// Force the next block to be created as a ToplevelBlock
parsing_anonymous_method = true;
}
current_anonymous_method.Block = anon_block;
retval = current_anonymous_method;
- lexer.async_block = (bool) oob_stack.Pop ();
+ async_block = (bool) oob_stack.Pop ();
current_variable = (BlockVariableDeclaration) oob_stack.Pop ();
current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
return "add";
case Token.ASYNC:
return "async";
- case Token.AWAIT:
- return "await";
case Token.BASE:
return "base";
case Token.BREAK:
case Token.LITERAL:
return "value";
case Token.IDENTIFIER:
+ case Token.AWAIT:
return "identifier";
case Token.EOF: