%{
//
// cs-parser.jay: The Parser for the C# compiler
//
// Authors: Miguel de Icaza (miguel@gnome.org)
// Ravi Pratap (ravi@ximian.com)
// Marek Safar (marek.safar@gmail.com)
//
// Dual Licensed under the terms of the GNU GPL and the MIT X11 license
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
// (C) 2004-2011 Novell, Inc
// Copyright 2011-2012 Xamarin Inc.
//
using System.Text;
using System.IO;
using System;
using System.Collections.Generic;
namespace Mono.CSharp
{
///
/// The C# Parser
///
public class CSharpParser
{
[Flags]
enum ParameterModifierType
{
Ref = 1 << 1,
Out = 1 << 2,
This = 1 << 3,
Params = 1 << 4,
Arglist = 1 << 5,
DefaultValue = 1 << 6,
All = Ref | Out | This | Params | Arglist | DefaultValue,
PrimaryConstructor = Ref | Out | Params | DefaultValue
}
static readonly object ModifierNone = 0;
NamespaceContainer current_namespace;
TypeContainer current_container;
TypeDefinition current_type;
PropertyBase current_property;
EventProperty current_event;
EventField current_event_field;
FieldBase current_field;
///
/// Current block is used to add statements as we find
/// them.
///
Block current_block;
BlockVariable current_variable;
Delegate current_delegate;
AnonymousMethodExpression current_anonymous_method;
///
/// This is used by the unary_expression code to resolve
/// a name against a parameter.
///
// FIXME: This is very ugly and it's very hard to reset it correctly
// on all places, especially when some parameters are autogenerated.
ParametersCompiled current_local_parameters;
bool parsing_anonymous_method;
bool async_block;
///
/// An out-of-band stack.
///
Stack oob_stack;
///
/// Controls the verbosity of the errors produced by the parser
///
int yacc_verbose_flag;
///
/// Used by the interactive shell, flags whether EOF was reached
/// and an error was produced
///
public bool UnexpectedEOF;
///
/// The current file.
///
readonly CompilationSourceFile file;
///
/// Temporary Xml documentation cache.
/// For enum types, we need one more temporary store.
///
string tmpComment;
string enumTypeComment;
/// Current attribute target
string current_attr_target;
ParameterModifierType valid_param_mod;
bool default_parameter_used;
/// When using the interactive parser, this holds the
/// resulting expression
public Class InteractiveResult;
//
// Keeps track of global data changes to undo on parser error
//
public Undo undo;
bool? interactive_async;
Stack linq_clause_blocks;
ModuleContainer module;
readonly CompilerContext compiler;
readonly LanguageVersion lang_version;
readonly bool doc_support;
readonly CompilerSettings settings;
readonly Report report;
//
// Instead of allocating carrier array everytime we
// share the bucket for very common constructs which can never
// be recursive
//
List parameters_bucket;
//
// Full AST support members
//
LocationsBag lbag;
List> mod_locations;
Location parameterModifierLocation, savedLocation, savedEventAssignLocation;
Location savedAttrParenOpenLocation, savedAttrParenCloseLocation, savedOperatorLocation;
Stack> locationListStack = new Stack> (); // used for type parameters
Stack opt_intoStack = new Stack ();
bool HadAttributeParens;
List attributeArgumentCommas = new List ();
List parameterListCommas = new List ();
Stack location_stack;
%}
%token EOF
%token NONE /* This token is never returned by our lexer */
%token ERROR // This is used not by the parser, but by the tokenizer.
// do not remove.
/*
*These are the C# keywords
*/
%token FIRST_KEYWORD
%token ABSTRACT
%token AS
%token ADD
%token BASE
%token BOOL
%token BREAK
%token BYTE
%token CASE
%token CATCH
%token CHAR
%token CHECKED
%token CLASS
%token CONST
%token CONTINUE
%token DECIMAL
%token DEFAULT
%token DELEGATE
%token DO
%token DOUBLE
%token ELSE
%token ENUM
%token EVENT
%token EXPLICIT
%token EXTERN
%token FALSE
%token FINALLY
%token FIXED
%token FLOAT
%token FOR
%token FOREACH
%token GOTO
%token IF
%token IMPLICIT
%token IN
%token INT
%token INTERFACE
%token INTERNAL
%token IS
%token LOCK
%token LONG
%token NAMESPACE
%token NEW
%token NULL
%token OBJECT
%token OPERATOR
%token OUT
%token OVERRIDE
%token PARAMS
%token PRIVATE
%token PROTECTED
%token PUBLIC
%token READONLY
%token REF
%token RETURN
%token REMOVE
%token SBYTE
%token SEALED
%token SHORT
%token SIZEOF
%token STACKALLOC
%token STATIC
%token STRING
%token STRUCT
%token SWITCH
%token THIS
%token THROW
%token TRUE
%token TRY
%token TYPEOF
%token UINT
%token ULONG
%token UNCHECKED
%token UNSAFE
%token USHORT
%token USING
%token VIRTUAL
%token VOID
%token VOLATILE
%token WHERE
%token WHILE
%token ARGLIST
%token PARTIAL
%token ARROW
%token FROM
%token FROM_FIRST
%token JOIN
%token ON
%token EQUALS
%token SELECT
%token GROUP
%token BY
%token LET
%token ORDERBY
%token ASCENDING
%token DESCENDING
%token INTO
%token INTERR_NULLABLE
%token EXTERN_ALIAS
%token REFVALUE
%token REFTYPE
%token MAKEREF
%token ASYNC
%token AWAIT
%token INTERR_OPERATOR
/* C# keywords which are not really keywords */
%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_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
/* Generics <,> tokens */
%token OP_GENERICS_LT
%token OP_GENERICS_LT_DECL
%token OP_GENERICS_GT
%token LITERAL
%token IDENTIFIER
%token OPEN_PARENS_LAMBDA
%token OPEN_PARENS_CAST
%token GENERIC_DIMENSION
%token DEFAULT_COLON
%token OPEN_BRACKET_EXPR
// Make the parser go into eval mode parsing (statements and compilation units).
%token EVAL_STATEMENT_PARSER
%token EVAL_COMPILATION_UNIT_PARSER
%token EVAL_USING_DECLARATIONS_UNIT_PARSER
%token DOC_SEE
//
// 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 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
%left BITWISE_AND
%left OP_SHIFT_LEFT OP_SHIFT_RIGHT
%left PLUS MINUS
%left STAR DIV PERCENT
%right BANG CARRET UMINUS
%nonassoc OP_INC OP_DEC
%left OPEN_PARENS
%left OPEN_BRACKET OPEN_BRACE
%left DOT
%start compilation_unit
%%
compilation_unit
: outer_declaration opt_EOF
{
Lexer.check_incorrect_doc_comment ();
}
| interactive_parsing { Lexer.CompleteOnEOF = false; } opt_EOF
| documentation_parsing
;
outer_declaration
: opt_extern_alias_directives opt_using_directives
| opt_extern_alias_directives opt_using_directives namespace_or_type_declarations opt_attributes
{
if ($4 != null) {
Attributes attrs = (Attributes) $4;
report.Error (1730, attrs.Attrs [0].Location,
"Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
current_namespace.UnattachedAttributes = attrs;
}
}
| opt_extern_alias_directives opt_using_directives attribute_sections
{
module.AddAttributes ((Attributes) $3, current_namespace);
}
| error
{
if (yyToken == Token.EXTERN_ALIAS)
report.Error (439, lexer.Location, "An extern alias declaration must precede all other elements");
else
Error_SyntaxError (yyToken);
}
;
opt_EOF
: /* empty */
| EOF
;
extern_alias_directives
: extern_alias_directive
| extern_alias_directives extern_alias_directive
;
extern_alias_directive
: EXTERN_ALIAS IDENTIFIER IDENTIFIER SEMICOLON
{
var lt = (LocatedToken) $2;
string s = lt.Value;
if (s != "alias") {
syntax_error (lt.Location, "`alias' expected");
} else {
if (lang_version == LanguageVersion.ISO_1)
FeatureIsNotAvailable (lt.Location, "external alias");
lt = (LocatedToken) $3;
if (lt.Value == QualifiedAliasMember.GlobalAlias) {
RootNamespace.Error_GlobalNamespaceRedefined (report, lt.Location);
}
var na = new UsingExternAlias (new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
current_namespace.AddUsing (na);
lbag.AddLocation (na, GetLocation ($2), GetLocation ($4));
}
}
| EXTERN_ALIAS error
{
Error_SyntaxError (yyToken);
}
;
using_directives
: using_directive
| using_directives using_directive
;
using_directive
: using_namespace
{
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
;
using_namespace
: USING namespace_or_type_expr SEMICOLON
{
var un = new UsingNamespace ((ATypeNameExpression) $2, GetLocation ($1));
current_namespace.AddUsing (un);
lbag.AddLocation (un, GetLocation ($3));
}
| USING IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON
{
var lt = (LocatedToken) $2;
if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") {
report.Warning (440, 2, lt.Location,
"An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead");
}
var un = new UsingAliasNamespace (new SimpleMemberName (lt.Value, lt.Location), (ATypeNameExpression) $4, GetLocation ($1));
current_namespace.AddUsing (un);
lbag.AddLocation (un, GetLocation ($3), GetLocation ($5));
}
| USING error
{
Error_SyntaxError (yyToken);
$$ = null;
}
;
//
// Strictly speaking, namespaces don't have attributes but
// we parse global attributes along with namespace declarations and then
// detach them
//
namespace_declaration
: opt_attributes NAMESPACE namespace_name
{
Attributes attrs = (Attributes) $1;
var name = (MemberName) $3;
if (attrs != null) {
bool valid_global_attrs = true;
if ((current_namespace.DeclarationFound || current_namespace != file)) {
valid_global_attrs = false;
} else {
foreach (var a in attrs.Attrs) {
if (a.ExplicitTarget == "assembly" || a.ExplicitTarget == "module")
continue;
valid_global_attrs = false;
break;
}
}
if (!valid_global_attrs)
report.Error (1671, name.Location, "A namespace declaration cannot have modifiers or attributes");
}
module.AddAttributes (attrs, current_namespace);
var ns = new NamespaceContainer (name, current_namespace);
current_namespace.AddTypeContainer (ns);
current_container = current_namespace = ns;
}
OPEN_BRACE
{
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
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));
else
lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($5), GetLocation ($10));
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
: IDENTIFIER
{
var lt = (LocatedToken) $1;
$$ = new MemberName (lt.Value, lt.Location);
}
| namespace_name DOT IDENTIFIER
{
var lt = (LocatedToken) $3;
$$ = new MemberName ((MemberName) $1, lt.Value, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| error
{
Error_SyntaxError (yyToken);
$$ = new MemberName ("", lexer.Location);
}
;
opt_semicolon
: /* empty */
| SEMICOLON
;
opt_comma
: /* empty */
| COMMA
;
opt_using_directives
: /* empty */
| using_directives
;
opt_extern_alias_directives
: /* empty */
| extern_alias_directives
;
opt_namespace_or_type_declarations
: /* empty */
| namespace_or_type_declarations
;
namespace_or_type_declarations
: namespace_or_type_declaration
| namespace_or_type_declarations namespace_or_type_declaration
;
namespace_or_type_declaration
: type_declaration
{
if ($1 != null) {
TypeContainer ds = (TypeContainer)$1;
if ((ds.ModFlags & (Modifiers.PRIVATE | Modifiers.PROTECTED)) != 0){
report.Error (1527, ds.Location,
"Namespace elements cannot be explicitly declared as private, protected or protected internal");
}
// Here is a trick, for explicit attributes we don't know where they belong to until
// we parse succeeding declaration hence we parse them as normal and re-attach them
// when we know whether they are global (assembly:, module:) or local (type:).
if (ds.OptAttributes != null) {
ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file);
}
}
current_namespace.DeclarationFound = true;
}
| namespace_declaration
{
current_namespace.DeclarationFound = true;
}
| attribute_sections CLOSE_BRACE {
current_namespace.UnattachedAttributes = (Attributes) $1;
report.Error (1518, lexer.Location, "Attributes must be attached to class, delegate, enum, interface or struct");
lexer.putback ('}');
}
;
type_declaration
: class_declaration
| struct_declaration
| interface_declaration
| enum_declaration
| delegate_declaration
//
// Enable this when we have handled all errors, because this acts as a generic fallback
//
// | error {
// Console.WriteLine ("Token=" + yyToken);
// report.Error (1518, GetLocation ($1), "Expected class, struct, interface, enum or delegate");
// }
;
//
// Attributes
//
opt_attributes
: /* empty */
| attribute_sections
;
attribute_sections
: attribute_section
{
var sect = (List) $1;
$$ = new Attributes (sect);
}
| attribute_sections attribute_section
{
Attributes attrs = $1 as Attributes;
var sect = (List) $2;
if (attrs == null)
attrs = new Attributes (sect);
else if (sect != null)
attrs.AddAttributes (sect);
$$ = attrs;
}
;
attribute_section
: OPEN_BRACKET
{
PushLocation (GetLocation ($1));
lexer.parsing_attribute_section = true;
}
attribute_section_cont
{
lexer.parsing_attribute_section = false;
$$ = $3;
}
;
attribute_section_cont
: attribute_target COLON
{
current_attr_target = (string) $1;
if (current_attr_target == "assembly" || current_attr_target == "module") {
Lexer.check_incorrect_doc_comment ();
}
}
attribute_list opt_comma CLOSE_BRACKET
{
// when attribute target is invalid
if (current_attr_target == string.Empty)
$$ = new List (0);
else
$$ = $4;
lbag.InsertLocation ($$, 0, GetLocation ($2));
lbag.InsertLocation ($$, 0, PopLocation ());
lbag.InsertLocation ($$, 0, PopLocation ());
if ($5 != null) {
lbag.AddLocation ($$, GetLocation ($5), GetLocation ($6));
} else {
lbag.AddLocation ($$, 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 = (LocatedToken) $1;
var tne = new SimpleName (lt.Value, null, lt.Location);
$$ = new List () {
new Attribute (null, tne, null, GetLocation ($1), false)
};
}
| error
{
CheckAttributeTarget (yyToken, GetTokenName (yyToken), GetLocation ($1));
$$ = null;
}
;
attribute_target
: IDENTIFIER
{
var lt = (LocatedToken) $1;
$$ = CheckAttributeTarget (yyToken, lt.Value, lt.Location);
PushLocation (GetLocation ($1));
}
| EVENT { $$ = "event"; PushLocation (GetLocation ($1)); }
| RETURN { $$ = "return"; PushLocation (GetLocation ($1)); }
;
attribute_list
: attribute
{
$$ = new List (4) { (Attribute) $1 };
}
| attribute_list COMMA attribute
{
var attrs = (List) $1;
if (attrs != null) {
attrs.Add ((Attribute) $3);
lbag.AddLocation (attrs, GetLocation ($2));
}
$$ = attrs;
}
;
attribute
: attribute_name
{
++lexer.parsing_block;
}
opt_attribute_arguments
{
--lexer.parsing_block;
var tne = (ATypeNameExpression) $1;
if (tne.HasTypeArguments) {
report.Error (404, tne.Location, "Attributes cannot be generic");
}
Arguments [] arguments = (Arguments []) $3;
$$ = new Attribute (current_attr_target, tne, (Arguments[]) $3, GetLocation ($1), lexer.IsEscapedIdentifier (tne));
if (arguments != null) {
attributeArgumentCommas.Insert (0, savedAttrParenOpenLocation);
attributeArgumentCommas.Add (savedAttrParenCloseLocation);
lbag.AddLocation ($$, attributeArgumentCommas);
attributeArgumentCommas.Clear ();
} else if (HadAttributeParens) {
lbag.AddLocation ($$, savedAttrParenOpenLocation, savedAttrParenCloseLocation);
}
}
;
attribute_name
: namespace_or_type_expr
;
opt_attribute_arguments
: /* empty */ { $$ = null; HadAttributeParens = false; }
| OPEN_PARENS attribute_arguments CLOSE_PARENS
{
savedAttrParenOpenLocation = GetLocation ($1);
savedAttrParenCloseLocation = GetLocation ($3);
$$ = $2;
HadAttributeParens = true;
}
;
attribute_arguments
: /* empty */ { $$ = null; }
| positional_or_named_argument
{
Arguments a = new Arguments (4);
a.Add ((Argument) $1);
$$ = new Arguments [] { a, null };
}
| named_attribute_argument
{
Arguments a = new Arguments (4);
a.Add ((Argument) $1);
$$ = new Arguments [] { null, a };
}
| attribute_arguments COMMA positional_or_named_argument
{
Arguments[] o = (Arguments[]) $1;
if (o [1] != null) {
report.Error (1016, ((Argument) $3).Expr.Location, "Named attribute arguments must appear after the positional arguments");
o [0] = new Arguments (4);
}
Arguments args = ((Arguments) o [0]);
if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument)
Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
args.Add ((Argument) $3);
attributeArgumentCommas.Add (GetLocation ($2));
}
| attribute_arguments COMMA named_attribute_argument
{
Arguments[] o = (Arguments[]) $1;
if (o [1] == null) {
o [1] = new Arguments (4);
}
((Arguments) o [1]).Add ((Argument) $3);
attributeArgumentCommas.Add (GetLocation ($2));
}
;
positional_or_named_argument
: expression
{
$$ = new Argument ((Expression) $1);
}
| named_argument
| error
{
Error_SyntaxError (yyToken);
$$ = null;
}
;
named_attribute_argument
: IDENTIFIER ASSIGN
{
++lexer.parsing_block;
}
expression
{
--lexer.parsing_block;
var lt = (LocatedToken) $1;
$$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4);
lbag.AddLocation ($$, GetLocation($2));
}
;
named_argument
: identifier_inside_body COLON opt_named_modifier expression_or_error
{
if (lang_version <= LanguageVersion.V_3)
FeatureIsNotAvailable (GetLocation ($1), "named argument");
// Avoid boxing in common case (no modifier)
var arg_mod = $3 == null ? Argument.AType.None : (Argument.AType) $3;
var lt = (LocatedToken) $1;
$$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod);
lbag.AddLocation ($$, GetLocation($2));
}
;
opt_named_modifier
: /* empty */ { $$ = null; }
| REF
{
$$ = Argument.AType.Ref;
}
| OUT
{
$$ = Argument.AType.Out;
}
;
opt_class_member_declarations
: /* empty */
| class_member_declarations
;
class_member_declarations
: class_member_declaration
{
lexer.parsing_modifiers = true;
lexer.parsing_block = 0;
}
| class_member_declarations class_member_declaration
{
lexer.parsing_modifiers = true;
lexer.parsing_block = 0;
}
;
class_member_declaration
: constant_declaration
| field_declaration
| method_declaration
| property_declaration
| event_declaration
| indexer_declaration
| operator_declaration
| constructor_declaration
| primary_constructor_body
| 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;
}
;
primary_constructor_body
: OPEN_BRACE
{
current_local_parameters = current_type.PrimaryConstructorParameters;
if (current_local_parameters == null) {
report.Error (9010, GetLocation ($1), "Primary constructor body is not allowed");
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
}
++lexer.parsing_block;
start_block (GetLocation ($1));
}
opt_statement_list block_end
{
current_local_parameters = null;
var t = current_type as ClassOrStruct;
if (t != null) {
var b = (ToplevelBlock) $4;
if (t.PrimaryConstructorBlock != null) {
report.Error (8041, b.StartLocation, "Primary constructor already has a body");
} else {
t.PrimaryConstructorBlock = b;
}
}
}
;
struct_declaration
: opt_attributes
opt_modifiers
opt_partial
STRUCT
{
}
type_declaration_name
{
lexer.ConstraintsParsing = true;
valid_param_mod = ParameterModifierType.PrimaryConstructor;
push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4));
}
opt_primary_parameters
opt_class_base
opt_type_parameter_constraints_clauses
{
valid_param_mod = 0;
lexer.ConstraintsParsing = false;
if ($8 != null)
current_type.PrimaryConstructorParameters = (ParametersCompiled) $8;
if ($10 != null)
current_container.SetConstraints ((List) $10);
if (doc_support)
current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
lexer.parsing_modifiers = true;
}
OPEN_BRACE
{
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
opt_class_member_declarations CLOSE_BRACE
{
--lexer.parsing_declaration;
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
opt_semicolon
{
if ($16 == null) {
lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15));
} else {
lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15), GetLocation ($17));
}
$$ = pop_current_class ();
}
| opt_attributes opt_modifiers opt_partial STRUCT error
{
Error_SyntaxError (yyToken);
}
;
constant_declaration
: opt_attributes
opt_modifiers
CONST type IDENTIFIER
{
var lt = (LocatedToken) $5;
var mod = (Modifiers) $2;
current_field = new Const (current_type, (FullNamedExpression) $4, mod, new MemberName (lt.Value, lt.Location), (Attributes) $1);
current_type.AddMember (current_field);
if ((mod & Modifiers.STATIC) != 0) {
report.Error (504, current_field.Location, "The constant `{0}' cannot be marked static", current_field.GetSignatureForError ());
}
$$ = current_field;
}
constant_initializer opt_constant_declarators SEMICOLON
{
if (doc_support) {
current_field.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
current_field.Initializer = (ConstInitializer) $7;
lbag.AddMember (current_field, GetModifierLocations (), 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
: /* empty */
| constant_declarators
;
constant_declarators
: constant_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $1);
}
| constant_declarators constant_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $2);
}
;
constant_declarator
: COMMA IDENTIFIER constant_initializer
{
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3);
lbag.AddLocation ($$, GetLocation ($1));
}
;
constant_initializer
: ASSIGN
{
++lexer.parsing_block;
}
constant_initializer_expr
{
--lexer.parsing_block;
$$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1));
}
| error
{
report.Error (145, lexer.Location, "A const field requires a value to be provided");
$$ = null;
}
;
constant_initializer_expr
: constant_expression
| array_initializer
;
field_declaration
: opt_attributes
opt_modifiers
member_type IDENTIFIER
{
lexer.parsing_generic_declaration = false;
FullNamedExpression type = (FullNamedExpression) $3;
if (type.Type != null && type.Type.Kind == MemberKind.Void)
report.Error (670, GetLocation ($3), "Fields cannot have void type");
var lt = (LocatedToken) $4;
current_field = new Field (current_type, type, (Modifiers) $2, new MemberName (lt.Value, lt.Location), (Attributes) $1);
current_type.AddField (current_field);
$$ = current_field;
}
opt_field_initializer
opt_field_declarators
SEMICOLON
{
if (doc_support) {
current_field.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
lbag.AddMember (current_field, GetModifierLocations (), GetLocation ($8));
$$ = current_field;
current_field = null;
}
| opt_attributes
opt_modifiers
FIXED simple_type IDENTIFIER
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($3), "fixed size buffers");
var lt = (LocatedToken) $5;
current_field = new FixedField (current_type, (FullNamedExpression) $4, (Modifiers) $2,
new MemberName (lt.Value, lt.Location), (Attributes) $1);
current_type.AddField (current_field);
}
fixed_field_size opt_fixed_field_declarators SEMICOLON
{
if (doc_support) {
current_field.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
current_field.Initializer = (ConstInitializer) $7;
lbag.AddMember (current_field, GetModifierLocations (), GetLocation ($3), GetLocation ($9));
$$ = current_field;
current_field = null;
}
| opt_attributes
opt_modifiers
FIXED simple_type error
SEMICOLON
{
report.Error (1641, GetLocation ($5), "A fixed size buffer field must have the array size specifier after the field name");
}
;
opt_field_initializer
: /* empty */
| ASSIGN
{
++lexer.parsing_block;
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
start_block (GetLocation ($1));
}
variable_initializer
{
--lexer.parsing_block;
current_field.Initializer = (Expression) $3;
lbag.AppendToMember (current_field, GetLocation ($1));
end_block (lexer.Location);
current_local_parameters = null;
}
;
opt_field_declarators
: /* empty */
| field_declarators
;
field_declarators
: field_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $1);
}
| field_declarators field_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $2);
}
;
field_declarator
: COMMA IDENTIFIER
{
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null);
lbag.AddLocation ($$, GetLocation ($1));
}
| COMMA IDENTIFIER ASSIGN
{
++lexer.parsing_block;
}
variable_initializer
{
--lexer.parsing_block;
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
}
;
opt_fixed_field_declarators
: /* empty */
| fixed_field_declarators
;
fixed_field_declarators
: fixed_field_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $1);
}
| fixed_field_declarators fixed_field_declarator
{
current_field.AddDeclarator ((FieldDeclarator) $2);
}
;
fixed_field_declarator
: COMMA IDENTIFIER fixed_field_size
{
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (ConstInitializer) $3);
lbag.AddLocation ($$, GetLocation ($1));
}
;
fixed_field_size
: OPEN_BRACKET
{
++lexer.parsing_block;
}
expression CLOSE_BRACKET
{
--lexer.parsing_block;
$$ = new ConstInitializer (current_field, (Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($4));
}
| OPEN_BRACKET error
{
report.Error (443, lexer.Location, "Value or constant expected");
$$ = null;
}
;
variable_initializer
: expression
| array_initializer
| error
{
// It has to be here for the parent to safely restore artificial block
Error_SyntaxError (yyToken);
$$ = null;
}
;
method_declaration
: method_header
{
if (doc_support)
Lexer.doc_state = XmlCommentState.NotAllowed;
// Was added earlier in the case of body being eof for full ast
}
method_body_expression_block
{
Method method = (Method) $1;
method.Block = (ToplevelBlock) $3;
async_block = false;
if (method.Block == null) {
lbag.AppendToMember (method, savedLocation); // semicolon
method.ParameterInfo.CheckParameters (method);
if ((method.ModFlags & Modifiers.ASYNC) != 0) {
report.Error (1994, method.Location, "`{0}': The async modifier can only be used with methods that have a body",
method.GetSignatureForError ());
}
} else {
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, method.Location, "`{0}': interface members cannot have a definition",
method.GetSignatureForError ());
}
}
current_local_parameters = null;
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
;
method_header
: opt_attributes
opt_modifiers
member_type
method_declaration_name OPEN_PARENS
{
valid_param_mod = ParameterModifierType.All;
}
opt_formal_parameter_list CLOSE_PARENS
{
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);
current_type.AddMember (method);
async_block = (method.ModFlags & Modifiers.ASYNC) != 0;
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
lbag.AddMember (method, GetModifierLocations (), 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
PARTIAL
VOID
{
lexer.parsing_generic_declaration = true;
}
method_declaration_name
OPEN_PARENS
{
lexer.parsing_generic_declaration = false;
valid_param_mod = ParameterModifierType.All;
}
opt_formal_parameter_list CLOSE_PARENS
{
lexer.ConstraintsParsing = true;
}
opt_type_parameter_constraints_clauses
{
lexer.ConstraintsParsing = false;
valid_param_mod = 0;
MemberName name = (MemberName) $6;
current_local_parameters = (ParametersCompiled) $9;
var modifiers = (Modifiers) $2;
modifiers |= Modifiers.PARTIAL;
var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($4)),
modifiers, name, current_local_parameters, (Attributes) $1);
current_type.AddMember (method);
async_block = (method.ModFlags & Modifiers.ASYNC) != 0;
if ($12 != null)
method.SetConstraints ((List) $12);
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($3));
lbag.AddMember (method, GetModifierLocations (), GetLocation ($7), GetLocation ($10));
$$ = method;
}
| opt_attributes
opt_modifiers
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", ModifiersExtensions.Name ((Modifiers) $4));
var method = Method.Create (current_type, (FullNamedExpression) $3,
0, name, (ParametersCompiled) $7, (Attributes) $1);
current_type.AddMember (method);
current_local_parameters = (ParametersCompiled) $7;
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
$$ = method;
}
| opt_attributes
opt_modifiers
member_type
method_declaration_name error
{
Error_SyntaxError (yyToken);
current_local_parameters = ParametersCompiled.Undefined;
MemberName name = (MemberName) $4;
var method = Method.Create (current_type, (FullNamedExpression) $3, (Modifiers) $2,
name, current_local_parameters, (Attributes) $1);
current_type.AddMember (method);
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
$$ = method;
}
;
method_body_expression_block
: method_body
| expression_block
;
method_body
: block
| SEMICOLON { savedLocation = GetLocation ($1); $$ = null; }
;
expression_block
: ARROW
{
if (lang_version < LanguageVersion.V_6) {
FeatureIsNotAvailable (GetLocation ($1), "expression bodied members");
}
++lexer.parsing_block;
start_block (GetLocation ($1));
}
expression SEMICOLON
{
lexer.parsing_block = 0;
current_block.AddStatement (new ContextualReturn ((Expression) $3));
var b = end_block (GetLocation ($4));
b.IsCompilerGenerated = true;
$$ = b;
}
;
opt_formal_parameter_list
: /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
| formal_parameter_list
;
formal_parameter_list
: fixed_parameters
{
var pars_list = (List) $1;
$$ = new ParametersCompiled (pars_list.ToArray ());
lbag.AddLocation ($$, parameterListCommas);
}
| fixed_parameters COMMA parameter_array
{
var pars_list = (List) $1;
pars_list.Add ((Parameter) $3);
parameterListCommas.Add (GetLocation ($2));
$$ = new ParametersCompiled (pars_list.ToArray ());
lbag.AddLocation ($$, parameterListCommas);
}
| fixed_parameters COMMA arglist_modifier
{
var pars_list = (List) $1;
pars_list.Add (new ArglistParameter (GetLocation ($3)));
parameterListCommas.Add (GetLocation ($2));
$$ = new ParametersCompiled (pars_list.ToArray (), true);
lbag.AddLocation ($$, parameterListCommas);
}
| parameter_array COMMA error
{
if ($1 != null)
report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
$$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );
lbag.AddLocation ($$, parameterListCommas);
}
| fixed_parameters COMMA parameter_array COMMA error
{
if ($3 != null)
report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
var pars_list = (List) $1;
pars_list.Add (new ArglistParameter (GetLocation ($3)));
parameterListCommas.Add (GetLocation ($2));
parameterListCommas.Add (GetLocation ($4));
$$ = new ParametersCompiled (pars_list.ToArray (), true);
lbag.AddLocation ($$, parameterListCommas);
}
| arglist_modifier COMMA error
{
report.Error (257, GetLocation ($1), "An __arglist parameter must be the last parameter in a formal parameter list");
$$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
lbag.AddLocation ($$, parameterListCommas);
}
| fixed_parameters COMMA ARGLIST COMMA error
{
report.Error (257, GetLocation ($3), "An __arglist parameter must be the last parameter in a formal parameter list");
var pars_list = (List) $1;
pars_list.Add (new ArglistParameter (GetLocation ($3)));
parameterListCommas.Add (GetLocation ($2));
parameterListCommas.Add (GetLocation ($4));
$$ = new ParametersCompiled (pars_list.ToArray (), true);
lbag.AddLocation ($$, parameterListCommas);
}
| parameter_array
{
$$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );
}
| arglist_modifier
{
$$ = new ParametersCompiled (new Parameter [] { new ArglistParameter (GetLocation ($1)) }, true);
}
| error
{
Error_SyntaxError (yyToken);
$$ = ParametersCompiled.EmptyReadOnlyParameters;
}
;
fixed_parameters
: fixed_parameter
{
parameters_bucket.Clear ();
Parameter p = (Parameter) $1;
parameters_bucket.Add (p);
parameterListCommas.Clear ();
default_parameter_used = p.HasDefaultValue;
$$ = parameters_bucket;
}
| fixed_parameters COMMA fixed_parameter
{
var pars = (List) $1;
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);
parameterListCommas.Add (GetLocation ($2));
}
$$ = $1;
}
;
fixed_parameter
: opt_attributes
opt_parameter_modifier
parameter_type
identifier_inside_body
{
var lt = (LocatedToken) $4;
$$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, parameterModifierLocation);
}
| opt_attributes
opt_parameter_modifier
parameter_type
identifier_inside_body OPEN_BRACKET CLOSE_BRACKET
{
var lt = (LocatedToken) $4;
report.Error (1552, lt.Location, "Array type specifier, [], must appear before parameter name");
$$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, parameterModifierLocation);
}
| attribute_sections error
{
Error_SyntaxError (yyToken);
Location l = GetLocation ($2);
$$ = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) $1, l);
}
| opt_attributes
opt_parameter_modifier
parameter_type
error
{
Error_SyntaxError (yyToken);
Location l = GetLocation ($4);
$$ = new Parameter ((FullNamedExpression) $3, null, (Parameter.Modifier) $2, (Attributes) $1, l);
lbag.AddLocation ($$, parameterModifierLocation);
}
| opt_attributes
opt_parameter_modifier
parameter_type
identifier_inside_body
ASSIGN
{
++lexer.parsing_block;
}
constant_expression
{
--lexer.parsing_block;
if (lang_version <= LanguageVersion.V_3) {
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 ((valid_param_mod & ParameterModifierType.DefaultValue) == 0)
report.Error (1065, GetLocation ($5), "Optional parameter is not valid in this context");
var lt = (LocatedToken) $4;
$$ = new Parameter ((FullNamedExpression) $3, lt.Value, mod, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, parameterModifierLocation, GetLocation ($5)); // parameterModifierLocation should be ignored when mod == NONE
if ($7 != null)
((Parameter) $$).DefaultValue = new DefaultParameterValueExpression ((Expression) $7);
}
;
opt_parameter_modifier
: /* empty */ { $$ = Parameter.Modifier.NONE; }
| parameter_modifiers
;
parameter_modifiers
: parameter_modifier
{
$$ = $1;
}
| parameter_modifiers parameter_modifier
{
Parameter.Modifier p2 = (Parameter.Modifier)$2;
Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
if (((Parameter.Modifier)$1 & p2) == p2) {
Error_DuplicateParameterModifier (lexer.Location, p2);
} else {
switch (mod & ~Parameter.Modifier.This) {
case Parameter.Modifier.REF:
report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
break;
case Parameter.Modifier.OUT:
report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether");
break;
default:
report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier");
break;
}
}
$$ = mod;
}
;
parameter_modifier
: REF
{
if ((valid_param_mod & ParameterModifierType.Ref) == 0)
Error_ParameterModifierNotValid ("ref", GetLocation ($1));
parameterModifierLocation = GetLocation ($1);
$$ = Parameter.Modifier.REF;
}
| OUT
{
if ((valid_param_mod & ParameterModifierType.Out) == 0)
Error_ParameterModifierNotValid ("out", GetLocation ($1));
parameterModifierLocation = GetLocation ($1);
$$ = Parameter.Modifier.OUT;
}
| THIS
{
if ((valid_param_mod & ParameterModifierType.This) == 0)
Error_ParameterModifierNotValid ("this", GetLocation ($1));
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "extension methods");
parameterModifierLocation = GetLocation ($1);
$$ = Parameter.Modifier.This;
}
;
parameter_array
: opt_attributes params_modifier type IDENTIFIER
{
var lt = (LocatedToken) $4;
$$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, savedLocation);
}
| opt_attributes params_modifier type IDENTIFIER ASSIGN constant_expression
{
report.Error (1751, GetLocation ($2), "Cannot specify a default value for a parameter array");
var lt = (LocatedToken) $4;
$$ = new ParamsParameter ((FullNamedExpression) $3, lt.Value, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, savedLocation);
}
| opt_attributes params_modifier type error
{
Error_SyntaxError (yyToken);
$$ = new ParamsParameter ((FullNamedExpression) $3, null, (Attributes) $1, Location.Null);
}
;
params_modifier
: PARAMS
{
if ((valid_param_mod & ParameterModifierType.Params) == 0)
report.Error (1670, (GetLocation ($1)), "The `params' modifier is not allowed in current context");
savedLocation = GetLocation ($1);
}
| PARAMS parameter_modifier
{
Parameter.Modifier mod = (Parameter.Modifier)$2;
if ((mod & Parameter.Modifier.This) != 0) {
report.Error (1104, GetLocation ($1), "The parameter modifiers `this' and `params' cannot be used altogether");
} else {
report.Error (1611, GetLocation ($1), "The params parameter cannot be declared as ref or out");
}
savedLocation = GetLocation ($1);
}
| PARAMS params_modifier
{
Error_DuplicateParameterModifier (GetLocation ($1), Parameter.Modifier.PARAMS);
}
;
arglist_modifier
: ARGLIST
{
if ((valid_param_mod & ParameterModifierType.Arglist) == 0)
report.Error (1669, GetLocation ($1), "__arglist is not valid in this context");
}
;
property_declaration
: opt_attributes
opt_modifiers
member_type
member_declaration_name
{
lexer.parsing_generic_declaration = false;
if (doc_support)
tmpComment = Lexer.consume_doc_comment ();
}
OPEN_BRACE
{
var type = (FullNamedExpression) $3;
current_property = new Property (current_type, type, (Modifiers) $2,
(MemberName) $4, (Attributes) $1);
if (type.Type != null && type.Type.Kind == MemberKind.Void)
report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ());
current_type.AddMember (current_property);
lbag.AddMember (current_property, GetModifierLocations (), GetLocation ($6));
lexer.PropertyParsing = true;
}
accessor_declarations
{
lexer.PropertyParsing = false;
if (doc_support)
current_property.DocComment = ConsumeStoredComment ();
}
CLOSE_BRACE
{
lbag.AppendToMember (current_property, GetLocation ($10));
lexer.parsing_modifiers = true;
}
opt_property_initializer
{
current_property = null;
}
| opt_attributes
opt_modifiers
member_type
member_declaration_name
{
lexer.parsing_generic_declaration = false;
if (doc_support)
tmpComment = Lexer.consume_doc_comment ();
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
}
expression_block
{
var type = (FullNamedExpression) $3;
var property = new Property (current_type, type, (Modifiers) $2,
(MemberName) $4, (Attributes) $1);
property.Get = new Property.GetMethod (property, Modifiers.COMPILER_GENERATED, null, property.Location);
property.Get.Block = (ToplevelBlock) $6;
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, property.Get.Block.StartLocation,
"`{0}': interface members cannot have a definition", property.GetSignatureForError ());
}
if (type.Type != null && type.Type.Kind == MemberKind.Void)
report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", property.GetSignatureForError ());
current_type.AddMember (property);
current_local_parameters = null;
}
;
opt_property_initializer
: /* empty */
| ASSIGN
{
++lexer.parsing_block;
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
start_block (GetLocation ($1));
}
property_initializer SEMICOLON
{
--lexer.parsing_block;
((Property)current_property).Initializer = (Expression) $3;
lbag.AppendToMember (current_property, GetLocation ($1), GetLocation ($4));
end_block (GetLocation ($4));
current_local_parameters = null;
}
;
property_initializer
: expression
| array_initializer
;
indexer_declaration
: opt_attributes opt_modifiers
member_type indexer_declaration_name OPEN_BRACKET
{
valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue;
}
opt_formal_parameter_list CLOSE_BRACKET
{
valid_param_mod = 0;
var type = (FullNamedExpression) $3;
Indexer indexer = new Indexer (current_type, type, (MemberName) $4, (Modifiers) $2, (ParametersCompiled) $7, (Attributes) $1);
current_property = indexer;
current_type.AddIndexer (indexer);
lbag.AddMember (current_property, GetModifierLocations (), 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 ());
if (indexer.ParameterInfo.IsEmpty) {
report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter");
}
if (doc_support) {
tmpComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
lexer.PropertyParsing = true;
current_local_parameters = (ParametersCompiled) $7;
}
indexer_body
{
lexer.PropertyParsing = false;
current_local_parameters = null;
if (current_property.AccessorFirst != null && current_property.AccessorFirst.Block == null)
((Indexer) current_property).ParameterInfo.CheckParameters (current_property);
if (doc_support)
current_property.DocComment = ConsumeStoredComment ();
current_property = null;
}
;
indexer_body
: OPEN_BRACE accessor_declarations CLOSE_BRACE
{
lbag.AppendToMember (current_property, GetLocation ($1), GetLocation ($3));
}
| expression_block
{
current_property.Get = new Indexer.GetIndexerMethod (current_property, Modifiers.COMPILER_GENERATED, current_local_parameters, null, current_property.Location);
current_property.Get.Block = (ToplevelBlock) $1;
}
;
accessor_declarations
: get_accessor_declaration
| get_accessor_declaration accessor_declarations
| set_accessor_declaration
| set_accessor_declaration accessor_declarations
| error
{
if (yyToken == Token.CLOSE_BRACE) {
report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", current_property.GetSignatureForError ());
} 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");
}
}
;
get_accessor_declaration
: opt_attributes opt_modifiers GET
{
if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
}
if (current_property.Get != null) {
report.Error (1007, GetLocation ($3), "Property accessor already defined");
}
if (current_property is Indexer) {
current_property.Get = new Indexer.GetIndexerMethod (current_property, (Modifiers) $2, ((Indexer)current_property).ParameterInfo.Clone (),
(Attributes) $1, GetLocation ($3));
} else {
current_property.Get = new Property.GetMethod (current_property,
(Modifiers) $2, (Attributes) $1, GetLocation ($3));
}
current_local_parameters = current_property.Get.ParameterInfo;
lexer.PropertyParsing = false;
}
accessor_body
{
if ($5 != null) {
current_property.Get.Block = (ToplevelBlock) $5;
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, current_property.Get.Block.StartLocation,
"`{0}': interface members cannot have a definition", current_property.Get.GetSignatureForError ());
}
lbag.AddMember (current_property.Get, GetModifierLocations ());
} else {
lbag.AddMember (current_property.Get, GetModifierLocations (), savedLocation);
}
current_local_parameters = null;
lexer.PropertyParsing = true;
if (doc_support)
if (Lexer.doc_state == XmlCommentState.Error)
Lexer.doc_state = XmlCommentState.NotAllowed;
}
;
set_accessor_declaration
: opt_attributes opt_modifiers SET
{
if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
}
if (current_property.Set != null) {
report.Error (1007, GetLocation ($3), "Property accessor already defined");
}
if (current_property is Indexer) {
current_property.Set = new Indexer.SetIndexerMethod (current_property, (Modifiers) $2,
ParametersCompiled.MergeGenerated (compiler,
((Indexer)current_property).ParameterInfo, true, new Parameter (
current_property.TypeExpression, "value", Parameter.Modifier.NONE, null, GetLocation ($3)),
null),
(Attributes) $1, GetLocation ($3));
} else {
current_property.Set = new Property.SetMethod (current_property, (Modifiers) $2,
ParametersCompiled.CreateImplicitParameter (current_property.TypeExpression, GetLocation ($3)),
(Attributes) $1, GetLocation ($3));
}
current_local_parameters = current_property.Set.ParameterInfo;
lexer.PropertyParsing = false;
}
accessor_body
{
if ($5 != null) {
current_property.Set.Block = (ToplevelBlock) $5;
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, current_property.Set.Block.StartLocation,
"`{0}': interface members cannot have a definition", current_property.Set.GetSignatureForError ());
}
lbag.AddMember (current_property.Set, GetModifierLocations ());
} else {
lbag.AddMember (current_property.Set, GetModifierLocations (), savedLocation);
}
current_local_parameters = null;
lexer.PropertyParsing = true;
if (doc_support
&& Lexer.doc_state == XmlCommentState.Error)
Lexer.doc_state = XmlCommentState.NotAllowed;
}
;
accessor_body
: block
| SEMICOLON
{
savedLocation = GetLocation ($1);
$$ = null;
}
| error
{
Error_SyntaxError (1043, yyToken, "Invalid accessor body");
$$ = null;
}
;
interface_declaration
: opt_attributes
opt_modifiers
opt_partial
INTERFACE
{
}
type_declaration_name
{
lexer.ConstraintsParsing = true;
push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), $3);
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4));
}
opt_class_base
opt_type_parameter_constraints_clauses
{
lexer.ConstraintsParsing = false;
if ($9 != null)
current_container.SetConstraints ((List) $9);
if (doc_support) {
current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
lexer.parsing_modifiers = true;
}
OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE
{
--lexer.parsing_declaration;
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
opt_semicolon
{
if ($15 == null) {
lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13));
} else {
lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
}
$$ = pop_current_class ();
}
| opt_attributes opt_modifiers opt_partial INTERFACE error
{
Error_SyntaxError (yyToken);
}
;
opt_interface_member_declarations
: /* empty */
| interface_member_declarations
;
interface_member_declarations
: interface_member_declaration
{
lexer.parsing_modifiers = true;
lexer.parsing_block = 0;
}
| interface_member_declarations interface_member_declaration
{
lexer.parsing_modifiers = true;
lexer.parsing_block = 0;
}
;
interface_member_declaration
: constant_declaration
{
report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
}
| field_declaration
{
report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
}
| method_declaration
| property_declaration
| event_declaration
| indexer_declaration
| operator_declaration
{
report.Error (567, GetLocation ($1), "Interfaces cannot contain operators");
}
| constructor_declaration
{
report.Error (526, GetLocation ($1), "Interfaces cannot contain contructors");
}
| type_declaration
{
report.Error (524, GetLocation ($1), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations");
}
;
operator_declaration
: opt_attributes opt_modifiers operator_declarator
{
}
method_body_expression_block
{
OperatorDeclaration decl = (OperatorDeclaration) $3;
if (decl != null) {
Operator op = new Operator (
current_type, decl.optype, decl.ret_type, (Modifiers) $2,
current_local_parameters,
(ToplevelBlock) $5, (Attributes) $1, decl.location);
if (op.Block == null)
op.ParameterInfo.CheckParameters (op);
if (doc_support) {
op.DocComment = tmpComment;
Lexer.doc_state = XmlCommentState.Allowed;
}
// Note again, checking is done in semantic analysis
current_type.AddOperator (op);
lbag.AddMember (op, GetModifierLocations (), lbag.GetLocations (decl));
if ($5 == null) { // Semicolon
lbag.AddLocation (op, savedLocation);
}
}
current_local_parameters = null;
}
;
operator_type
: type_expression_or_array
| VOID
{
report.Error (590, GetLocation ($1), "User-defined operators cannot return void");
$$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
}
;
operator_declarator
: operator_type OPERATOR overloadable_operator OPEN_PARENS
{
valid_param_mod = ParameterModifierType.DefaultValue;
}
opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
Location loc = GetLocation ($2);
Operator.OpType op = (Operator.OpType) $3;
current_local_parameters = (ParametersCompiled)$6;
int p_count = current_local_parameters.Count;
if (p_count == 1) {
if (op == Operator.OpType.Addition)
op = Operator.OpType.UnaryPlus;
else if (op == Operator.OpType.Subtraction)
op = Operator.OpType.UnaryNegation;
}
if (IsUnaryOperator (op)) {
if (p_count == 2) {
report.Error (1020, loc, "Overloadable binary operator expected");
} else if (p_count != 1) {
report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
Operator.GetName (op));
}
} else {
if (p_count == 1) {
report.Error (1019, loc, "Overloadable unary operator expected");
} else if (p_count != 2) {
report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
Operator.GetName (op));
}
}
if (doc_support) {
tmpComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.NotAllowed;
}
$$ = new OperatorDeclaration (op, (FullNamedExpression) $1, loc);
lbag.AddLocation ($$, GetLocation ($2), savedOperatorLocation, GetLocation ($4), GetLocation ($7));
}
| conversion_operator_declarator
;
overloadable_operator
// Unary operators:
: BANG { $$ = Operator.OpType.LogicalNot; savedOperatorLocation = GetLocation ($1); }
| TILDE { $$ = Operator.OpType.OnesComplement; savedOperatorLocation = GetLocation ($1); }
| OP_INC { $$ = Operator.OpType.Increment; savedOperatorLocation = GetLocation ($1); }
| OP_DEC { $$ = Operator.OpType.Decrement; savedOperatorLocation = GetLocation ($1); }
| TRUE { $$ = Operator.OpType.True; savedOperatorLocation = GetLocation ($1); }
| FALSE { $$ = Operator.OpType.False; savedOperatorLocation = GetLocation ($1); }
// Unary and binary:
| PLUS { $$ = Operator.OpType.Addition; savedOperatorLocation = GetLocation ($1); }
| MINUS { $$ = Operator.OpType.Subtraction; savedOperatorLocation = GetLocation ($1); }
// Binary:
| STAR { $$ = Operator.OpType.Multiply; savedOperatorLocation = GetLocation ($1); }
| DIV { $$ = Operator.OpType.Division; savedOperatorLocation = GetLocation ($1); }
| PERCENT { $$ = Operator.OpType.Modulus; savedOperatorLocation = GetLocation ($1); }
| BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; savedOperatorLocation = GetLocation ($1); }
| BITWISE_OR { $$ = Operator.OpType.BitwiseOr; savedOperatorLocation = GetLocation ($1); }
| CARRET { $$ = Operator.OpType.ExclusiveOr; savedOperatorLocation = GetLocation ($1); }
| OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; savedOperatorLocation = GetLocation ($1); }
| OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; savedOperatorLocation = GetLocation ($1); }
| OP_EQ { $$ = Operator.OpType.Equality; savedOperatorLocation = GetLocation ($1); }
| OP_NE { $$ = Operator.OpType.Inequality; savedOperatorLocation = GetLocation ($1); }
| OP_GT { $$ = Operator.OpType.GreaterThan; savedOperatorLocation = GetLocation ($1); }
| OP_LT { $$ = Operator.OpType.LessThan; savedOperatorLocation = GetLocation ($1); }
| OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; savedOperatorLocation = GetLocation ($1); }
| OP_LE { $$ = Operator.OpType.LessThanOrEqual; savedOperatorLocation = GetLocation ($1); }
;
conversion_operator_declarator
: IMPLICIT OPERATOR type OPEN_PARENS
{
valid_param_mod = ParameterModifierType.DefaultValue;
}
opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
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;
}
$$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
}
| EXPLICIT OPERATOR type OPEN_PARENS
{
valid_param_mod = ParameterModifierType.DefaultValue;
}
opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
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;
}
$$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
}
| IMPLICIT error
{
Error_SyntaxError (yyToken);
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
$$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1));
}
| EXPLICIT error
{
Error_SyntaxError (yyToken);
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
$$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1));
}
;
constructor_declaration
: constructor_declarator
constructor_body
{
Constructor c = (Constructor) $1;
c.Block = (ToplevelBlock) $2;
if (doc_support)
c.DocComment = ConsumeStoredComment ();
current_local_parameters = null;
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
;
constructor_declarator
: opt_attributes
opt_modifiers
IDENTIFIER
{
if (doc_support) {
tmpComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
valid_param_mod = ParameterModifierType.All;
}
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
current_local_parameters = (ParametersCompiled) $6;
var lt = (LocatedToken) $3;
var mods = (Modifiers) $2;
var c = new Constructor (current_type, lt.Value, mods, (Attributes) $1, current_local_parameters, 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.AccessibilityMask) != 0){
report.Error (515, c.Location,
"`{0}': static constructor cannot have an access modifier",
c.GetSignatureForError ());
}
}
current_type.AddConstructor (c);
lbag.AddMember (c, GetModifierLocations (), GetLocation ($5), GetLocation ($7));
$$ = c;
//
// start block here, so possible anonymous methods inside
// constructor initializer can get correct parent block
//
start_block (lexer.Location);
}
opt_constructor_initializer
{
if ($9 != null) {
var c = (Constructor) $8;
c.Initializer = (ConstructorInitializer) $9;
if (c.IsStatic) {
report.Error (514, c.Location,
"`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
c.GetSignatureForError ());
}
}
$$ = $8;
}
;
constructor_body
: block_prepared
| SEMICOLON { current_block = null; $$ = null; }
;
opt_constructor_initializer
: /* Empty */
| constructor_initializer
;
constructor_initializer
: COLON BASE OPEN_PARENS
{
++lexer.parsing_block;
}
opt_argument_list CLOSE_PARENS
{
--lexer.parsing_block;
$$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
}
| COLON THIS OPEN_PARENS
{
++lexer.parsing_block;
}
opt_argument_list CLOSE_PARENS
{
--lexer.parsing_block;
$$ = new ConstructorThisInitializer ((Arguments) $5, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
}
| COLON error
{
Error_SyntaxError (yyToken);
$$ = new ConstructorThisInitializer (null, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($1));
}
| error
{
Error_SyntaxError (yyToken);
$$ = null;
}
;
destructor_declaration
: opt_attributes opt_modifiers TILDE
{
if (doc_support) {
tmpComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.NotAllowed;
}
current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
}
IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body
{
var lt = (LocatedToken) $5;
if (lt.Value != current_container.MemberName.Name){
report.Error (574, lt.Location, "Name of destructor must match name of class");
} else if (current_container.Kind != MemberKind.Class){
report.Error (575, lt.Location, "Only class types can contain destructor");
}
Destructor d = new Destructor (current_type, (Modifiers) $2,
ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location);
d.Identifier = lt.Value;
if (doc_support)
d.DocComment = ConsumeStoredComment ();
d.Block = (ToplevelBlock) $8;
current_type.AddMember (d);
lbag.AddMember (d, GetModifierLocations (), GetLocation ($3), GetLocation ($6), GetLocation ($7));
current_local_parameters = null;
}
;
event_declaration
: opt_attributes
opt_modifiers
EVENT type member_declaration_name
{
current_event_field = new EventField (current_type, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1);
current_type.AddMember (current_event_field);
if (current_event_field.MemberName.ExplicitInterface != null) {
report.Error (71, current_event_field.Location, "`{0}': An explicit interface implementation of an event must use property syntax",
current_event_field.GetSignatureForError ());
}
$$ = current_event_field;
}
opt_event_initializer
opt_event_declarators
SEMICOLON
{
if (doc_support) {
current_event_field.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
if (current_event_field.Initializer != null) {
lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation ($3), savedEventAssignLocation, GetLocation ($9));
} else {
lbag.AddMember (current_event_field, GetModifierLocations (), GetLocation ($3), GetLocation ($9));
}
current_event_field = null;
}
| opt_attributes
opt_modifiers
EVENT type member_declaration_name
OPEN_BRACE
{
current_event = new EventProperty (current_type, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, (Attributes) $1);
current_type.AddMember (current_event);
lbag.AddMember (current_event, GetModifierLocations (), GetLocation ($3), GetLocation ($6));
lexer.EventParsing = true;
}
event_accessor_declarations
{
if (current_container.Kind == MemberKind.Interface)
report.Error (69, GetLocation ($6), "Event in interface cannot have add or remove accessors");
lexer.EventParsing = false;
}
CLOSE_BRACE
{
if (doc_support) {
current_event.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
lbag.AppendToMember (current_event, GetLocation ($9));
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
: /* empty */
| ASSIGN
{
++lexer.parsing_block;
}
event_variable_initializer
{
--lexer.parsing_block;
savedEventAssignLocation = GetLocation ($1);
current_event_field.Initializer = (Expression) $3;
}
;
opt_event_declarators
: /* empty */
| event_declarators
;
event_declarators
: event_declarator
{
current_event_field.AddDeclarator ((FieldDeclarator) $1);
}
| event_declarators event_declarator
{
current_event_field.AddDeclarator ((FieldDeclarator) $2);
}
;
event_declarator
: COMMA IDENTIFIER
{
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null);
lbag.AddLocation ($$, GetLocation ($1));
}
| COMMA IDENTIFIER ASSIGN
{
++lexer.parsing_block;
}
event_variable_initializer
{
--lexer.parsing_block;
var lt = (LocatedToken) $2;
$$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $5);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
}
;
event_variable_initializer
: {
if (current_container.Kind == MemberKind.Interface) {
report.Error (68, lexer.Location, "`{0}': event in interface cannot have an initializer",
current_event_field.GetSignatureForError ());
}
if ((current_event_field.ModFlags & Modifiers.ABSTRACT) != 0) {
report.Error (74, lexer.Location, "`{0}': abstract event cannot have an initializer",
current_event_field.GetSignatureForError ());
}
}
variable_initializer
{
$$ = $2;
}
;
event_accessor_declarations
: add_accessor_declaration remove_accessor_declaration
| remove_accessor_declaration add_accessor_declaration
| add_accessor_declaration
{
report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
current_event.GetSignatureForError ());
}
| remove_accessor_declaration
{
report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
current_event.GetSignatureForError ());
}
| error
{
report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
$$ = null;
}
;
add_accessor_declaration
: opt_attributes opt_modifiers ADD
{
if ($2 != ModifierNone) {
report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
}
current_event.Add = new EventProperty.AddDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
current_local_parameters = current_event.Add.ParameterInfo;
lbag.AddMember (current_event.Add, GetModifierLocations ());
lexer.EventParsing = false;
}
event_accessor_block
{
lexer.EventParsing = true;
current_event.Add.Block = (ToplevelBlock) $5;
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, current_event.Add.Block.StartLocation,
"`{0}': interface members cannot have a definition", current_event.Add.GetSignatureForError ());
}
current_local_parameters = null;
}
;
remove_accessor_declaration
: opt_attributes opt_modifiers REMOVE
{
if ($2 != ModifierNone) {
report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
}
current_event.Remove = new EventProperty.RemoveDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
current_local_parameters = current_event.Remove.ParameterInfo;
lbag.AddMember (current_event.Remove, GetModifierLocations ());
lexer.EventParsing = false;
}
event_accessor_block
{
lexer.EventParsing = true;
current_event.Remove.Block = (ToplevelBlock) $5;
if (current_container.Kind == MemberKind.Interface) {
report.Error (531, current_event.Remove.Block.StartLocation,
"`{0}': interface members cannot have a definition", current_event.Remove.GetSignatureForError ());
}
current_local_parameters = null;
}
;
event_accessor_block
: opt_semicolon
{
report.Error (73, lexer.Location, "An add or remove accessor must have a body");
$$ = null;
}
| block;
;
attributes_without_members
: attribute_sections CLOSE_BRACE
{
current_type.UnattachedAttributes = (Attributes) $1;
report.Error (1519, GetLocation ($1), "An attribute is missing member declaration");
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);
lbag.AddMember (current_field, GetModifierLocations ());
$$ = current_field;
}
;
enum_declaration
: opt_attributes
opt_modifiers
ENUM
type_declaration_name
opt_enum_base
{
if (doc_support)
enumTypeComment = Lexer.consume_doc_comment ();
}
OPEN_BRACE
{
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
MemberName name = (MemberName) $4;
if (name.IsGeneric) {
report.Error (1675, name.Location, "Enums cannot have type parameters");
}
push_current_container (new Enum (current_container, (FullNamedExpression) $5, (Modifiers) $2, name, (Attributes) $1), null);
if ($5 != null) {
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($3), savedLocation, GetLocation ($7));
} else {
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($3), GetLocation ($7));
}
}
opt_enum_member_declarations
{
lexer.parsing_modifiers = true;
// here will be evaluated after CLOSE_BLACE is consumed.
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
CLOSE_BRACE opt_semicolon
{
lbag.AppendToMember (current_container, GetLocation ($11));
if ($12 != null) {
lbag.AppendToMember (current_container, GetLocation ($12));
}
if (doc_support)
current_container.DocComment = enumTypeComment;
--lexer.parsing_declaration;
// if (doc_support)
// em.DocComment = ev.DocComment;
$$ = pop_current_class ();
}
;
opt_enum_base
: /* empty */
| COLON type
{
savedLocation = GetLocation ($1);
$$ = $2;
}
| COLON error
{
Error_TypeExpected (GetLocation ($1));
$$ = null;
}
;
opt_enum_member_declarations
: /* empty */
| enum_member_declarations
| enum_member_declarations COMMA
{
lbag.AppendToMember (current_container, GetLocation ($2));
}
;
enum_member_declarations
: enum_member_declaration
| enum_member_declarations COMMA enum_member_declaration
{
lbag.AppendToMember (current_container, GetLocation ($2));
$$ = $3;
}
;
enum_member_declaration
: opt_attributes IDENTIFIER
{
var lt = (LocatedToken) $2;
var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
((Enum) current_type).AddEnumMember (em);
if (doc_support) {
em.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
$$ = em;
}
| opt_attributes IDENTIFIER
{
++lexer.parsing_block;
if (doc_support) {
tmpComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.NotAllowed;
}
}
ASSIGN constant_expression
{
--lexer.parsing_block;
var lt = (LocatedToken) $2;
var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
em.Initializer = new ConstInitializer (em, (Expression) $5, GetLocation ($4));
((Enum) current_type).AddEnumMember (em);
if (doc_support)
em.DocComment = ConsumeStoredComment ();
$$ = em;
}
| opt_attributes IDENTIFIER error
{
Error_SyntaxError (yyToken);
var lt = (LocatedToken) $2;
var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
((Enum) current_type).AddEnumMember (em);
if (doc_support) {
em.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
$$ = em;
}
| attributes_without_members
;
delegate_declaration
: opt_attributes
opt_modifiers
DELEGATE
member_type type_declaration_name
OPEN_PARENS
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
}
opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
ParametersCompiled p = (ParametersCompiled) $8;
Delegate del = new Delegate (current_container, (FullNamedExpression) $4, (Modifiers) $2, (MemberName) $5, p, (Attributes) $1);
p.CheckParameters (del);
current_container.AddTypeContainer (del);
current_delegate = del;
lexer.ConstraintsParsing = true;
}
opt_type_parameter_constraints_clauses
{
lexer.ConstraintsParsing = false;
}
SEMICOLON
{
if (doc_support) {
current_delegate.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
if ($11 != null)
current_delegate.SetConstraints ((List) $11);
lbag.AddMember (current_delegate, GetModifierLocations (), GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($13));
$$ = current_delegate;
current_delegate = null;
}
;
opt_nullable
: /* empty */
| INTERR_NULLABLE
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "nullable types");
$$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1));
}
;
namespace_or_type_expr
: member_name
| qualified_alias_member IDENTIFIER opt_type_argument_list
{
var lt1 = (LocatedToken) $1;
var lt2 = (LocatedToken) $2;
$$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
lbag.AddLocation ($$, savedLocation, GetLocation ($2));
}
| qualified_alias_member IDENTIFIER generic_dimension
{
var lt1 = (LocatedToken) $1;
var lt2 = (LocatedToken) $2;
var qam = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
lbag.AddLocation (qam.TypeArguments, Lexer.GenericDimensionLocations);
$$ = qam;
lbag.AddLocation ($$, GetLocation ($2));
}
;
member_name
: simple_name_expr
| namespace_or_type_expr DOT IDENTIFIER opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| namespace_or_type_expr DOT IDENTIFIER generic_dimension
{
var lt = (LocatedToken) $3;
var ma = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
lbag.AddLocation (ma.TypeArguments, Lexer.GenericDimensionLocations);
$$ = ma;
lbag.AddLocation ($$, GetLocation ($2));
}
;
simple_name_expr
: IDENTIFIER opt_type_argument_list
{
var lt = (LocatedToken) $1;
$$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
}
| IDENTIFIER generic_dimension
{
var lt = (LocatedToken) $1;
var sn = new SimpleName (lt.Value, (int) $2, lt.Location);
lbag.AddLocation (sn.TypeArguments, Lexer.GenericDimensionLocations);
$$ = sn;
}
;
//
// Generics arguments (any type, without attributes)
//
opt_type_argument_list
: /* empty */
| OP_GENERICS_LT type_arguments OP_GENERICS_GT
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "generics");
var list = locationListStack.Pop ();
list.Add (GetLocation ($1));
list.Add (GetLocation ($2));
lbag.AddLocation ($2, list);
$$ = $2;;
}
| 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;
locationListStack.Push (new List ());
}
| type_arguments COMMA type
{
TypeArguments type_args = (TypeArguments) $1;
type_args.Add ((FullNamedExpression) $3);
$$ = type_args;
locationListStack.Peek ().Add (GetLocation ($2));
}
;
//
// 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;
var lt = (LocatedToken) $1;
$$ = new MemberName (lt.Value, (TypeParameters)$3, lt.Location);
}
;
member_declaration_name
: method_declaration_name
{
MemberName mn = (MemberName)$1;
if (mn.TypeParameters != 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;
var lt = (LocatedToken) $2;
$$ = new MemberName (lt.Value, (TypeParameters) $3, (ATypeNameExpression) $1, lt.Location);
}
;
indexer_declaration_name
: THIS
{
lexer.parsing_generic_declaration = false;
$$ = new MemberName (TypeDefinition.DefaultIndexerName, GetLocation ($1));
}
| explicit_interface THIS
{
lexer.parsing_generic_declaration = false;
$$ = new MemberName (TypeDefinition.DefaultIndexerName, null, (ATypeNameExpression) $1, GetLocation ($2));
}
;
explicit_interface
: IDENTIFIER opt_type_argument_list DOT
{
var lt = (LocatedToken) $1;
$$ = new SimpleName (lt.Value, (TypeArguments) $2, lt.Location);
lbag.AddLocation ($$, GetLocation ($3));
}
| qualified_alias_member IDENTIFIER opt_type_argument_list DOT
{
var lt1 = (LocatedToken) $1;
var lt2 = (LocatedToken) $2;
$$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
lbag.AddLocation ($$, savedLocation, GetLocation ($4));
}
| explicit_interface IDENTIFIER opt_type_argument_list DOT
{
var lt = (LocatedToken) $2;
$$ = new MemberAccess ((ATypeNameExpression) $1, lt.Value, (TypeArguments) $3, lt.Location);
lbag.AddLocation ($$, GetLocation ($4));
}
;
opt_type_parameter_list
: /* empty */
| OP_GENERICS_LT_DECL type_parameters OP_GENERICS_GT
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "generics");
$$ = $2;
var list = locationListStack.Pop ();
list.Add (GetLocation ($1));
list.Add (GetLocation ($2));
lbag.AddLocation ($2, list);
}
;
type_parameters
: type_parameter
{
var tparams = new TypeParameters ();
tparams.Add ((TypeParameter)$1);
$$ = tparams;
locationListStack.Push (new List ());
}
| type_parameters COMMA type_parameter
{
var tparams = (TypeParameters) $1;
tparams.Add ((TypeParameter)$3);
$$ = tparams;
locationListStack.Peek ().Add (GetLocation ($2));
}
;
type_parameter
: opt_attributes opt_type_parameter_variance IDENTIFIER
{
var lt = (LocatedToken)$3;
var variance = (VarianceDecl) $2;
$$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, variance);
if (variance != null)
lbag.AddLocation ($$, savedLocation);
}
| error
{
if (GetTokenName (yyToken) == "type")
report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type");
else
Error_SyntaxError (yyToken);
$$ = new TypeParameter (MemberName.Null, null, null);
}
;
//
// All types where void is allowed
//
type_and_void
: type_expression_or_array
| VOID
{
$$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
}
;
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_invalid
;
simple_type
: type_expression
| void_invalid
;
parameter_type
: type_expression_or_array
| VOID
{
report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
$$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
}
;
type_expression_or_array
: type_expression
| type_expression rank_specifiers
{
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
}
;
type_expression
: namespace_or_type_expr opt_nullable
{
if ($2 != null) {
$$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
} else {
var sn = $1 as SimpleName;
if (sn != null && sn.Name == "var")
$$ = new VarExpr (sn.Location);
else
$$ = $1;
}
}
| namespace_or_type_expr pointer_stars
{
$$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
}
| builtin_type_expression
;
void_invalid
: VOID
{
Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
$$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
}
;
builtin_type_expression
: builtin_types opt_nullable
{
if ($2 != null)
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
}
| builtin_types pointer_stars
{
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
}
| VOID pointer_stars
{
$$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
}
;
type_list
: base_type_name
{
var types = new List (2);
types.Add ((FullNamedExpression) $1);
$$ = types;
}
| type_list COMMA base_type_name
{
var types = (List) $1;
types.Add ((FullNamedExpression) $3);
lbag.AddLocation (types, GetLocation ($2));
$$ = types;
}
;
base_type_name
: type
{
if ($1 is ComposedCast) {
report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
}
$$ = $1;
}
;
/*
* replaces all the productions for isolating the various
* simple types, but we need this to reuse it easily in variable_type
*/
builtin_types
: OBJECT { $$ = new TypeExpression (compiler.BuiltinTypes.Object, GetLocation ($1)); }
| STRING { $$ = new TypeExpression (compiler.BuiltinTypes.String, GetLocation ($1)); }
| BOOL { $$ = new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation ($1)); }
| DECIMAL { $$ = new TypeExpression (compiler.BuiltinTypes.Decimal, GetLocation ($1)); }
| FLOAT { $$ = new TypeExpression (compiler.BuiltinTypes.Float, GetLocation ($1)); }
| DOUBLE { $$ = new TypeExpression (compiler.BuiltinTypes.Double, GetLocation ($1)); }
| integral_type
;
integral_type
: SBYTE { $$ = new TypeExpression (compiler.BuiltinTypes.SByte, GetLocation ($1)); }
| BYTE { $$ = new TypeExpression (compiler.BuiltinTypes.Byte, GetLocation ($1)); }
| SHORT { $$ = new TypeExpression (compiler.BuiltinTypes.Short, GetLocation ($1)); }
| USHORT { $$ = new TypeExpression (compiler.BuiltinTypes.UShort, GetLocation ($1)); }
| INT { $$ = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation ($1)); }
| UINT { $$ = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation ($1)); }
| LONG { $$ = new TypeExpression (compiler.BuiltinTypes.Long, GetLocation ($1)); }
| ULONG { $$ = new TypeExpression (compiler.BuiltinTypes.ULong, GetLocation ($1)); }
| CHAR { $$ = new TypeExpression (compiler.BuiltinTypes.Char, GetLocation ($1)); }
;
//
// Expressions, section 7.5
//
primary_expression
: primary_expression_or_type
| literal
| array_creation_expression
| parenthesized_expression
| default_value_expression
| invocation_expression
| element_access
| this_access
| base_access
| post_increment_expression
| post_decrement_expression
| object_or_delegate_creation_expression
| anonymous_type_expression
| typeof_expression
| sizeof_expression
| checked_expression
| unchecked_expression
| pointer_member_access
| anonymous_method_expression
| undocumented_expressions
;
primary_expression_or_type
: simple_name_expr
| IDENTIFIER GENERATE_COMPLETION {
var lt = (LocatedToken) $1;
$$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
}
| member_access
;
literal
: boolean_literal
| LITERAL
| NULL { $$ = new NullLiteral (GetLocation ($1)); }
;
boolean_literal
: TRUE { $$ = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation ($1)); }
| FALSE { $$ = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation ($1)); }
;
//
// 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
;
//
// Use this production to accept closing parenthesis or
// performing completion
//
close_parens
: CLOSE_PARENS
| COMPLETE_COMPLETION
;
parenthesized_expression
: OPEN_PARENS expression CLOSE_PARENS
{
$$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
}
| OPEN_PARENS expression COMPLETE_COMPLETION
{
$$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
}
;
member_access
: primary_expression DOT identifier_inside_body opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| primary_expression DOT identifier_inside_body generic_dimension
{
var lt = (LocatedToken) $3;
var ma = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);
lbag.AddLocation (ma.TypeArguments, Lexer.GenericDimensionLocations);
$$ = ma;
lbag.AddLocation ($$, GetLocation ($2));
}
| primary_expression INTERR_OPERATOR DOT identifier_inside_body opt_type_argument_list
{
if (lang_version < LanguageVersion.V_6)
FeatureIsNotAvailable (GetLocation ($2), "null propagating operator");
var lt = (LocatedToken) $4;
$$ = new ConditionalMemberAccess ((Expression) $1, lt.Value, (TypeArguments) $5, lt.Location);
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
}
| builtin_types DOT identifier_inside_body opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| BASE DOT identifier_inside_body opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| AWAIT DOT identifier_inside_body opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess (new SimpleName ("await", ((LocatedToken) $1).Location), lt.Value, (TypeArguments) $4, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| qualified_alias_member identifier_inside_body opt_type_argument_list
{
var lt1 = (LocatedToken) $1;
var lt2 = (LocatedToken) $2;
$$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
lbag.AddLocation ($$, savedLocation, GetLocation ($2));
}
| qualified_alias_member identifier_inside_body generic_dimension
{
var lt1 = (LocatedToken) $1;
var lt2 = (LocatedToken) $2;
var qam = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
lbag.AddLocation (qam.TypeArguments, Lexer.GenericDimensionLocations);
$$ = qam;
lbag.AddLocation ($$, GetLocation ($2));
}
| primary_expression DOT GENERATE_COMPLETION {
$$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
}
| primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
var lt = (LocatedToken) $3;
$$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
}
| builtin_types DOT GENERATE_COMPLETION
{
$$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
}
| builtin_types DOT IDENTIFIER GENERATE_COMPLETION {
var lt = (LocatedToken) $3;
$$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
}
;
invocation_expression
: primary_expression open_parens_any opt_argument_list close_parens
{
$$ = new Invocation ((Expression) $1, (Arguments) $3);
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| primary_expression open_parens_any argument_list error
{
Error_SyntaxError (yyToken);
$$ = 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
: /* empty */ { $$ = null; }
| object_or_collection_initializer
;
object_or_collection_initializer
: OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
{
if ($2 == null) {
$$ = new CollectionOrObjectInitializers (GetLocation ($1));
} else {
$$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1));
}
lbag.AddLocation ($$, GetLocation ($3));
}
| OPEN_BRACE member_initializer_list COMMA CLOSE_BRACE
{
$$ = new CollectionOrObjectInitializers ((List) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
}
;
opt_member_initializer_list
: /* empty */ { $$ = null; }
| member_initializer_list
{
$$ = $1;
}
;
member_initializer_list
: member_initializer
{
var a = new List ();
a.Add ((Expression) $1);
$$ = a;
}
| member_initializer_list COMMA member_initializer
{
var a = (List)$1;
a.Add ((Expression) $3);
lbag.AddLocation (a, GetLocation ($2));
$$ = a;
}
| member_initializer_list error {
Error_SyntaxError (yyToken);
$$ = $1;
}
;
member_initializer
: IDENTIFIER ASSIGN initializer_value
{
var lt = (LocatedToken) $1;
$$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| AWAIT ASSIGN initializer_value
{
var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
$$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| GENERATE_COMPLETION
{
$$ = 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
{
if ($2 == null)
$$ = new CollectionElementInitializer (GetLocation ($1));
else {
$$ = new CollectionElementInitializer ((List)$2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
}
lbag.AddLocation ($$, GetLocation ($3));
}
| OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET ASSIGN initializer_value
{
if (lang_version < LanguageVersion.V_6)
FeatureIsNotAvailable (GetLocation ($1), "dictionary initializer");
$$ = new DictionaryElementInitializer ((List)$2, (Expression) $5, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
}
| OPEN_BRACE CLOSE_BRACE
{
report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
$$ = new CollectionElementInitializer (GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
}
;
initializer_value
: expression
| object_or_collection_initializer
;
opt_argument_list
: /* empty */ { $$ = null; }
| argument_list
;
argument_list
: argument_or_named_argument
{
Arguments list = new Arguments (4);
list.Add ((Argument) $1);
$$ = list;
}
| argument_list COMMA argument
{
Arguments list = (Arguments) $1;
if (list [list.Count - 1] is NamedArgument)
Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
list.Add ((Argument) $3);
lbag.AddLocation (list, GetLocation ($2));
$$ = list;
}
| argument_list COMMA named_argument
{
Arguments list = (Arguments) $1;
NamedArgument a = (NamedArgument) $3;
for (int i = 0; i < list.Count; ++i) {
NamedArgument na = list [i] as NamedArgument;
if (na != null && na.Name == a.Name)
report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
na.Name);
}
list.Add (a);
lbag.AddLocation (list, GetLocation ($2));
$$ = list;
}
| argument_list COMMA error
{
if (lexer.putback_char == -1)
lexer.putback (')'); // TODO: Wrong but what can I do
Error_SyntaxError (yyToken);
$$ = $1;
}
| COMMA error
{
report.Error (839, GetLocation ($1), "An argument is missing");
$$ = null;
}
;
argument
: expression
{
$$ = new Argument ((Expression) $1);
}
| non_simple_argument
;
argument_or_named_argument
: argument
| named_argument
;
non_simple_argument
: REF variable_reference
{
$$ = new Argument ((Expression) $2, Argument.AType.Ref);
lbag.AddLocation ($$, GetLocation ($1));
}
| OUT variable_reference
{
$$ = new Argument ((Expression) $2, Argument.AType.Out);
lbag.AddLocation ($$, GetLocation ($1));
}
| ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
{
$$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| ARGLIST OPEN_PARENS CLOSE_PARENS
{
$$ = new Argument (new Arglist (GetLocation ($1)));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
}
;
variable_reference
: expression
;
element_access
: primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
{
$$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($4));
}
| primary_expression INTERR_OPERATOR OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
{
if (lang_version < LanguageVersion.V_6)
FeatureIsNotAvailable (GetLocation ($2), "null propagating operator");
$$ = new ElementAccess ((Expression) $1, (Arguments) $4, GetLocation ($3)) {
ConditionalAccess = true
};
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($5));
}
| primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
{
Error_SyntaxError (yyToken);
$$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
}
| primary_expression OPEN_BRACKET_EXPR error
{
Error_SyntaxError (yyToken);
$$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
}
;
expression_list
: expression_or_error
{
var list = new List (4);
list.Add ((Expression) $1);
$$ = list;
}
| expression_list COMMA expression_or_error
{
var list = (List) $1;
list.Add ((Expression) $3);
lbag.AddLocation (list, GetLocation ($2));
$$ = list;
}
;
expression_list_arguments
: expression_list_argument
{
Arguments args = new Arguments (4);
args.Add ((Argument) $1);
$$ = args;
}
| expression_list_arguments COMMA expression_list_argument
{
Arguments args = (Arguments) $1;
if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
args.Add ((Argument) $3);
lbag.AddLocation (args, GetLocation ($2));
$$ = args;
}
;
expression_list_argument
: expression
{
$$ = new Argument ((Expression) $1);
}
| named_argument
;
this_access
: THIS
{
$$ = new This (GetLocation ($1));
}
;
base_access
: BASE OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
{
$$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($4));
}
| BASE OPEN_BRACKET error
{
Error_SyntaxError (yyToken);
$$ = new ElementAccess (null, null, GetLocation ($2));
}
;
post_increment_expression
: primary_expression OP_INC
{
$$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
}
;
post_decrement_expression
: primary_expression OP_DEC
{
$$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
}
;
object_or_delegate_creation_expression
: NEW new_expr_type open_parens_any opt_argument_list CLOSE_PARENS opt_object_or_collection_initializer
{
if ($6 != null) {
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "object initializers");
$$ = new NewInitialize ((FullNamedExpression) $2, (Arguments) $4, (CollectionOrObjectInitializers) $6, GetLocation ($1));
} else {
$$ = new New ((FullNamedExpression) $2, (Arguments) $4, GetLocation ($1));
}
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
}
| NEW new_expr_type object_or_collection_initializer
{
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "collection initializers");
$$ = new NewInitialize ((FullNamedExpression) $2, null, (CollectionOrObjectInitializers) $3, GetLocation ($1));
}
;
array_creation_expression
: NEW new_expr_type OPEN_BRACKET_EXPR expression_list CLOSE_BRACKET
opt_rank_specifier
opt_array_initializer
{
$$ = new ArrayCreation ((FullNamedExpression) $2, (List) $4,
new ComposedTypeSpecifier (((List) $4).Count, GetLocation ($3)) {
Next = (ComposedTypeSpecifier) $6
}, (ArrayInitializer) $7, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
}
| NEW new_expr_type rank_specifiers opt_array_initializer
{
if ($4 == null)
report.Error (1586, GetLocation ($1), "Array creation must have array size or array initializer");
$$ = new ArrayCreation ((FullNamedExpression) $2, (ComposedTypeSpecifier) $3, (ArrayInitializer) $4, GetLocation ($1));
}
| NEW rank_specifier array_initializer
{
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "implicitly typed arrays");
$$ = new ImplicitlyTypedArrayCreation ((ComposedTypeSpecifier) $2, (ArrayInitializer) $3, GetLocation ($1));
}
| NEW new_expr_type OPEN_BRACKET CLOSE_BRACKET OPEN_BRACKET_EXPR error CLOSE_BRACKET
{
report.Error (178, GetLocation ($6), "Invalid rank specifier, expecting `,' or `]'");
$$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1));
}
| NEW new_expr_type error
{
Error_SyntaxError (yyToken);
// It can be any of new expression, create the most common one
$$ = new New ((FullNamedExpression) $2, null, GetLocation ($1));
}
;
new_expr_type
: {
++lexer.parsing_type;
}
simple_type
{
--lexer.parsing_type;
$$ = $2;
}
;
anonymous_type_expression
: NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
{
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
$$ = new NewAnonymousType ((List) $3, current_container, GetLocation ($1));
// TODO: lbag comma location
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| NEW OPEN_BRACE GENERATE_COMPLETION
{
$$ = new EmptyCompletion ();
}
;
anonymous_type_parameters_opt_comma
: anonymous_type_parameters_opt
| anonymous_type_parameters COMMA
;
anonymous_type_parameters_opt
: { $$ = null; }
| anonymous_type_parameters
;
anonymous_type_parameters
: anonymous_type_parameter
{
var a = new List (4);
a.Add ((AnonymousTypeParameter) $1);
$$ = a;
}
| anonymous_type_parameters COMMA anonymous_type_parameter
{
var a = (List) $1;
a.Add ((AnonymousTypeParameter) $3);
lbag.AddLocation (a, GetLocation ($2));
$$ = a;
}
| COMPLETE_COMPLETION
{
$$ = new EmptyCompletion ();
}
| anonymous_type_parameter COMPLETE_COMPLETION
{
$$ = $1;
}
;
anonymous_type_parameter
: identifier_inside_body ASSIGN variable_initializer
{
var lt = (LocatedToken)$1;
$$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
lbag.AddLocation ($$, GetLocation ($2));
}
| identifier_inside_body
{
var lt = (LocatedToken)$1;
$$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
lt.Value, lt.Location);
}
| member_access
{
MemberAccess ma = (MemberAccess) $1;
$$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
}
| error
{
report.Error (746, lexer.Location,
"Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
$$ = null;
}
;
opt_rank_specifier
: /* empty */
| rank_specifiers
;
rank_specifiers
: rank_specifier
| rank_specifier rank_specifiers
{
((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
$$ = $1;
}
;
rank_specifier
: OPEN_BRACKET CLOSE_BRACKET
{
$$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
}
| OPEN_BRACKET dim_separators CLOSE_BRACKET
{
$$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
;
dim_separators
: COMMA
{
$$ = 2;
}
| dim_separators COMMA
{
$$ = ((int) $1) + 1;
}
;
opt_array_initializer
: /* empty */
{
$$ = null;
}
| array_initializer
{
$$ = $1;
}
;
array_initializer
: OPEN_BRACE CLOSE_BRACE
{
var ai = new ArrayInitializer (0, GetLocation ($1));
ai.VariableDeclaration = current_variable;
lbag.AddLocation (ai, GetLocation ($2));
$$ = ai;
}
| OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
{
var ai = new ArrayInitializer ((List) $2, GetLocation ($1));
ai.VariableDeclaration = current_variable;
if ($3 != null) {
lbag.AddLocation (ai, GetLocation ($3), GetLocation ($4));
} else {
lbag.AddLocation (ai, GetLocation ($4));
}
$$ = ai;
}
;
variable_initializer_list
: variable_initializer
{
var list = new List (4);
list.Add ((Expression) $1);
$$ = list;
}
| variable_initializer_list COMMA variable_initializer
{
var list = (List) $1;
list.Add ((Expression) $3);
lbag.AddLocation (list, GetLocation ($2));
$$ = list;
}
;
typeof_expression
: TYPEOF open_parens_any typeof_type_expression CLOSE_PARENS
{
$$ = new TypeOf ((FullNamedExpression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
;
typeof_type_expression
: type_and_void
| error
{
Error_TypeExpected (lexer.Location);
$$ = null;
}
;
generic_dimension
: GENERIC_DIMENSION
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "generics");
$$ = $1;
}
;
qualified_alias_member
: IDENTIFIER DOUBLE_COLON
{
var lt = (LocatedToken) $1;
if (lang_version == LanguageVersion.ISO_1)
FeatureIsNotAvailable (lt.Location, "namespace alias qualifier");
savedLocation = GetLocation ($2);
$$ = lt;
}
;
sizeof_expression
: SIZEOF open_parens_any type CLOSE_PARENS
{
$$ = 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
: CHECKED open_parens_any expression CLOSE_PARENS
{
$$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| CHECKED error
{
Error_SyntaxError (yyToken);
$$ = new CheckedExpr (null, GetLocation ($1));
}
;
unchecked_expression
: UNCHECKED open_parens_any expression CLOSE_PARENS
{
$$ = 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
: primary_expression OP_PTR IDENTIFIER opt_type_argument_list
{
var lt = (LocatedToken) $3;
$$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location);
}
;
anonymous_method_expression
: DELEGATE opt_anonymous_method_signature
{
start_anonymous (false, (ParametersCompiled) $2, false, GetLocation ($1));
}
block
{
$$ = end_anonymous ((ParametersBlock) $4);
if ((ParametersCompiled) $2 != ParametersCompiled.Undefined) {
lbag.AddLocation ($$, GetLocation ($1), PopLocation (), PopLocation ());
} else {
lbag.AddLocation ($$, GetLocation ($1));
}
}
| ASYNC DELEGATE opt_anonymous_method_signature
{
start_anonymous (false, (ParametersCompiled) $3, true, GetLocation ($1));
}
block
{
$$ = end_anonymous ((ParametersBlock) $5);
if ((ParametersCompiled) $3 != ParametersCompiled.Undefined) {
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), PopLocation (), PopLocation ());
} else {
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2));
}
}
;
opt_anonymous_method_signature
:
{
$$ = ParametersCompiled.Undefined;
}
| anonymous_method_signature
;
anonymous_method_signature
: OPEN_PARENS
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_formal_parameter_list CLOSE_PARENS
{
valid_param_mod = 0;
$$ = $3;
PushLocation (GetLocation ($3));
PushLocation (GetLocation ($1));
}
;
default_value_expression
: DEFAULT open_parens_any type CLOSE_PARENS
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($1), "default value expression");
$$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
;
unary_expression
: primary_expression
| BANG prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
}
| TILDE prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
}
| OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
{
$$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
| AWAIT prefixed_unary_expression
{
if (!async_block) {
if (current_anonymous_method is LambdaExpression) {
report.Error (4034, GetLocation ($1),
"The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
} else if (current_anonymous_method != null) {
report.Error (4035, GetLocation ($1),
"The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
} else if (interactive_async != null) {
current_block.Explicit.RegisterAsyncAwait ();
interactive_async = true;
} else {
report.Error (4033, GetLocation ($1),
"The `await' operator can only be used when its containing method is marked with the `async' modifier");
}
} else {
current_block.Explicit.RegisterAsyncAwait ();
}
$$ = 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));
}
;
//
// The idea to split this out is from Rhys' grammar
// to solve the problem with casts.
//
prefixed_unary_expression
: unary_expression
| PLUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
}
| MINUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
}
| OP_INC prefixed_unary_expression
{
$$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
}
| OP_DEC prefixed_unary_expression
{
$$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
}
| STAR prefixed_unary_expression
{
$$ = new Indirection ((Expression) $2, GetLocation ($1));
}
| BITWISE_AND 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
: prefixed_unary_expression
| multiplicative_expression STAR prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| multiplicative_expression DIV prefixed_unary_expression
{
$$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| multiplicative_expression PERCENT prefixed_unary_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
: multiplicative_expression
| additive_expression PLUS multiplicative_expression
{
$$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| additive_expression MINUS multiplicative_expression
{
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, 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 type
{
$$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
}
| additive_expression IS is_match_expr opt_identifier
{
var is_expr = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
if ($4 != null) {
if (lang_version != LanguageVersion.Experimental)
FeatureIsNotAvailable (GetLocation ($4), "type pattern matching");
var lt = (LocatedToken) $4;
is_expr.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
current_block.AddLocalName (is_expr.Variable);
}
$$ = is_expr;
}
| 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));
}
| AWAIT IS type
{
var lt = (LocatedToken) $1;
$$ = new Is (new SimpleName (lt.Value, lt.Location), (Expression) $3, GetLocation ($2));
}
| AWAIT AS type
{
var lt = (LocatedToken) $1;
$$ = new As (new SimpleName (lt.Value, lt.Location), (Expression) $3, GetLocation ($2));
}
;
is_match_expr
: match_type
| match_type rank_specifiers
{
if ($1 is VarExpr)
$1 = new SimpleName ("var", ((VarExpr) $1).Location);
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
}
| literal
| PLUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
}
| MINUS prefixed_unary_expression
{
$$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
}
;
match_type
: primary_expression_or_type opt_nullable
{
Expression expr = (Expression) $1;
if ($2 == null) {
SimpleName sn = expr as SimpleName;
if (sn != null && sn.Name == "var")
$$ = new VarExpr (sn.Location);
else
$$ = $1;
} else if (expr is ATypeNameExpression) {
$$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
} else {
Error_ExpectingTypeName (expr);
$$ = null;
}
}
| primary_expression_or_type pointer_stars
{
ATypeNameExpression expr = $1 as ATypeNameExpression;
if (expr != null) {
$$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
} else {
Error_ExpectingTypeName ((Expression)$1);
$$ = expr;
}
}
| builtin_type_expression
| void_invalid
;
shift_expression
: additive_expression
| shift_expression OP_SHIFT_LEFT additive_expression
{
$$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| shift_expression OP_SHIFT_RIGHT additive_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
: shift_expression
| relational_expression OP_LT shift_expression
{
$$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_GT shift_expression
{
$$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_LE shift_expression
{
$$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| relational_expression OP_GE shift_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
: relational_expression
| equality_expression OP_EQ relational_expression
{
$$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| equality_expression OP_NE relational_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
: equality_expression
| and_expression BITWISE_AND equality_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
: and_expression
| exclusive_or_expression CARRET and_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
: exclusive_or_expression
| inclusive_or_expression BITWISE_OR exclusive_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
: inclusive_or_expression
| conditional_and_expression OP_AND inclusive_or_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
: conditional_and_expression
| conditional_or_expression OP_OR conditional_and_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
: conditional_or_expression
| conditional_or_expression OP_COALESCING null_coalescing_expression
{
if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
$$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
conditional_expression
: null_coalescing_expression
| null_coalescing_expression INTERR expression COLON expression
{
$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($4));
}
| 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 ('}');
}
;
assignment_expression
: prefixed_unary_expression ASSIGN expression
{
$$ = new SimpleAssign ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_MULT_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_DIV_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_MOD_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_ADD_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SUB_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_AND_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_OR_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
| prefixed_unary_expression OP_XOR_ASSIGN expression
{
$$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
;
lambda_parameter_list
: lambda_parameter
{
var pars = new List (4);
pars.Add ((Parameter) $1);
parameterListCommas.Clear ();
$$ = pars;
}
| lambda_parameter_list COMMA lambda_parameter
{
var pars = (List) $1;
Parameter p = (Parameter)$3;
if (pars[0].GetType () != p.GetType ()) {
report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
}
pars.Add (p);
parameterListCommas.Add (GetLocation ($2));
$$ = pars;
}
;
lambda_parameter
: parameter_modifier parameter_type identifier_inside_body
{
var lt = (LocatedToken) $3;
$$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
}
| parameter_type identifier_inside_body
{
var lt = (LocatedToken) $2;
$$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
}
| IDENTIFIER
{
var lt = (LocatedToken) $1;
$$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
}
| AWAIT
{
var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
$$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
}
;
opt_lambda_parameter_list
: /* empty */ { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
| lambda_parameter_list {
var pars_list = (List) $1;
$$ = new ParametersCompiled (pars_list.ToArray ());
lbag.AddLocation ($$, parameterListCommas);
}
;
lambda_expression_body
: {
start_block (Location.Null);
}
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);
$$ = null;
}
;
lambda_expression
: IDENTIFIER ARROW
{
var lt = (LocatedToken) $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));
}
| AWAIT ARROW
{
var lt = (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 = (LocatedToken) $2;
Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
start_anonymous (true, new ParametersCompiled (p), true, lt.Location);
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $5);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
}
| OPEN_PARENS_LAMBDA
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_lambda_parameter_list CLOSE_PARENS ARROW
{
valid_param_mod = 0;
start_anonymous (true, (ParametersCompiled) $3, false, GetLocation ($1));
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $7);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4), GetLocation ($5));
}
| ASYNC OPEN_PARENS_LAMBDA
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_lambda_parameter_list CLOSE_PARENS ARROW
{
valid_param_mod = 0;
start_anonymous (true, (ParametersCompiled) $4, true, GetLocation ($1));
}
lambda_expression_body
{
$$ = end_anonymous ((ParametersBlock) $8);
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($5), GetLocation ($6));
}
;
expression
: assignment_expression
| non_assignment_expression
;
non_assignment_expression
: conditional_expression
| lambda_expression
| query_expression
| ARGLIST
{
$$ = new ArglistAccess (GetLocation ($1));
}
;
undocumented_expressions
: REFVALUE OPEN_PARENS non_assignment_expression COMMA type CLOSE_PARENS
{
$$ = new RefValueExpr ((Expression) $3, (FullNamedExpression) $5, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
}
| REFTYPE open_parens_any expression CLOSE_PARENS
{
$$ = new RefTypeExpr ((Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
| MAKEREF open_parens_any expression CLOSE_PARENS
{
$$ = new MakeRefExpr ((Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
;
constant_expression
: expression
;
boolean_expression
: expression
{
$$ = new BooleanExpression ((Expression) $1);
}
;
opt_primary_parameters
: /* empty */
{
$$ = null;
}
| primary_parameters
;
primary_parameters
: OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
$$ = $2;
// Cannot use opt_formal_parameter_list because it can be shared instance for empty parameters
lbag.AppendToMember (current_container, GetLocation ($1), GetLocation ($3));
if (lang_version < LanguageVersion.V_6)
FeatureIsNotAvailable (GetLocation ($1), "primary constructor");
}
;
opt_primary_parameters_with_class_base
: /* empty */
{
$$ = null;
}
| class_base
{
$$ = null;
}
| primary_parameters
{
$$ = $1;
}
| primary_parameters class_base
{
$$ = $1;
}
| primary_parameters class_base OPEN_PARENS
{
++lexer.parsing_block;
current_type.PrimaryConstructorBaseArgumentsStart = GetLocation ($3);
}
opt_argument_list CLOSE_PARENS
{
lbag.AppendToMember (current_container, GetLocation ($6));
current_type.PrimaryConstructorBaseArguments = (Arguments) $5;
--lexer.parsing_block;
$$ = $1;
}
;
//
// 10 classes
//
class_declaration
: opt_attributes
opt_modifiers
opt_partial
CLASS
{
}
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");
}
push_current_container (c, $3);
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($4));
valid_param_mod = ParameterModifierType.PrimaryConstructor;
}
opt_primary_parameters_with_class_base
opt_type_parameter_constraints_clauses
{
valid_param_mod = 0;
lexer.ConstraintsParsing = false;
if ($8 != null)
current_type.PrimaryConstructorParameters = (ParametersCompiled) $8;
if ($9 != null)
current_container.SetConstraints ((List) $9);
if (doc_support) {
current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
lexer.parsing_modifiers = true;
}
OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
{
--lexer.parsing_declaration;
if (doc_support)
Lexer.doc_state = XmlCommentState.Allowed;
}
opt_semicolon
{
if ($15 == null) {
lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13));
} else {
lbag.AppendToMember (current_container, GetLocation ($11), GetLocation ($13), GetLocation ($15));
}
$$ = pop_current_class ();
}
;
opt_partial
: /* empty */
{ $$ = null; }
| PARTIAL
{ $$ = $1; StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($1)); } // location
;
opt_modifiers
: /* empty */
{
mod_locations = null;
$$ = ModifierNone;
lexer.parsing_modifiers = false;
}
| modifiers
{
lexer.parsing_modifiers = false;
}
;
modifiers
: modifier
| modifiers modifier
{
var m1 = (Modifiers) $1;
var m2 = (Modifiers) $2;
if ((m1 & m2) != 0) {
report.Error (1004, lexer.Location - ModifiersExtensions.Name (m2).Length,
"Duplicate `{0}' modifier", ModifiersExtensions.Name (m2));
} else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
report.Error (107, lexer.Location - ModifiersExtensions.Name (m2).Length,
"More than one protection modifier specified");
}
$$ = m1 | m2;
}
;
modifier
: NEW
{
$$ = Modifiers.NEW;
StoreModifierLocation ($$, GetLocation ($1));
if (current_container.Kind == MemberKind.Namespace)
report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
}
| PUBLIC
{
$$ = Modifiers.PUBLIC;
StoreModifierLocation ($$, GetLocation ($1));
}
| PROTECTED
{
$$ = Modifiers.PROTECTED;
StoreModifierLocation ($$, GetLocation ($1));
}
| INTERNAL
{
$$ = Modifiers.INTERNAL;
StoreModifierLocation ($$, GetLocation ($1));
}
| PRIVATE
{
$$ = Modifiers.PRIVATE;
StoreModifierLocation ($$, GetLocation ($1));
}
| ABSTRACT
{
$$ = Modifiers.ABSTRACT;
StoreModifierLocation ($$, GetLocation ($1));
}
| SEALED
{
$$ = Modifiers.SEALED;
StoreModifierLocation ($$, GetLocation ($1));
}
| STATIC
{
$$ = Modifiers.STATIC;
StoreModifierLocation ($$, GetLocation ($1));
}
| READONLY
{
$$ = Modifiers.READONLY;
StoreModifierLocation ($$, GetLocation ($1));
}
| VIRTUAL
{
$$ = Modifiers.VIRTUAL;
StoreModifierLocation ($$, GetLocation ($1));
}
| OVERRIDE
{
$$ = Modifiers.OVERRIDE;
StoreModifierLocation ($$, GetLocation ($1));
}
| EXTERN
{
$$ = Modifiers.EXTERN;
StoreModifierLocation ($$, GetLocation ($1));
}
| VOLATILE
{
$$ = Modifiers.VOLATILE;
StoreModifierLocation ($$, GetLocation ($1));
}
| UNSAFE
{
$$ = Modifiers.UNSAFE;
StoreModifierLocation ($$, GetLocation ($1));
if (!settings.Unsafe)
Error_UnsafeCodeNotAllowed (GetLocation ($1));
}
| ASYNC
{
$$ = Modifiers.ASYNC;
StoreModifierLocation ($$, GetLocation ($1));
}
;
opt_class_base
: /* empty */
| class_base
;
class_base
: COLON type_list
{
current_type.SetBaseTypes ((List) $2);
lbag.AppendToMember (current_type, GetLocation ($1));
}
| COLON type_list error
{
Error_SyntaxError (yyToken);
current_type.SetBaseTypes ((List) $2);
}
;
opt_type_parameter_constraints_clauses
: /* empty */
| type_parameter_constraints_clauses
{
$$ = $1;
}
;
type_parameter_constraints_clauses
: type_parameter_constraints_clause
{
var constraints = new List (1);
constraints.Add ((Constraints) $1);
$$ = constraints;
}
| type_parameter_constraints_clauses type_parameter_constraints_clause
{
var constraints = (List) $1;
Constraints new_constraint = (Constraints)$2;
foreach (Constraints c in constraints) {
if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
report.Error (409, new_constraint.Location,
"A constraint clause has already been specified for type parameter `{0}'",
new_constraint.TypeParameter.Value);
}
}
constraints.Add (new_constraint);
$$ = constraints;
}
;
type_parameter_constraints_clause
: WHERE IDENTIFIER COLON type_parameter_constraints
{
var lt = (LocatedToken) $2;
$$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List) $4, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
| WHERE IDENTIFIER error
{
Error_SyntaxError (yyToken);
var lt = (LocatedToken) $2;
$$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1));
}
;
type_parameter_constraints
: type_parameter_constraint
{
var constraints = new List (1);
constraints.Add ((FullNamedExpression) $1);
$$ = constraints;
}
| type_parameter_constraints COMMA type_parameter_constraint
{
var constraints = (List) $1;
var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {
report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
}
prev = $3 as SpecialContraintExpr;
if (prev != null) {
if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");
} else {
prev = constraints [0] as SpecialContraintExpr;
if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {
report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
}
}
}
constraints.Add ((FullNamedExpression) $3);
lbag.AddLocation (constraints, GetLocation ($2));
$$ = constraints;
}
;
type_parameter_constraint
: type
{
if ($1 is ComposedCast)
report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
$$ = $1;
}
| NEW OPEN_PARENS CLOSE_PARENS
{
$$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
}
| CLASS
{
$$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
}
| STRUCT
{
$$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
}
;
opt_type_parameter_variance
: /* empty */
{
$$ = null;
}
| type_parameter_variance
{
if (lang_version <= LanguageVersion.V_3)
FeatureIsNotAvailable (lexer.Location, "generic type variance");
$$ = $1;
}
;
type_parameter_variance
: OUT
{
$$ = new VarianceDecl (Variance.Covariant, GetLocation ($1));
savedLocation = GetLocation ($1);
}
| IN
{
$$ = new VarianceDecl (Variance.Contravariant, GetLocation ($1));
savedLocation = GetLocation ($1);
}
;
//
// Statements (8.2)
//
//
// A block is "contained" on the following places:
// method_body
// property_declaration as part of the accessor body (get/set)
// operator_declaration
// constructor_declaration
// destructor_declaration
// event_declaration as part of add_accessor_declaration or remove_accessor_declaration
//
block
: OPEN_BRACE
{
++lexer.parsing_block;
start_block (GetLocation ($1));
}
opt_statement_list block_end
{
$$ = $4;
}
;
block_end
: CLOSE_BRACE
{
--lexer.parsing_block;
$$ = end_block (GetLocation ($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
{
--lexer.parsing_block;
$$ = end_block (GetLocation ($4));
} | CLOSE_BRACE
{
report.Error (1525, GetLocation ($1), "Unexpected symbol '}', expected '{'");
lexer.putback ('}');
$$ = end_block (GetLocation ($1));
}
;
block_prepared_strict
: OPEN_BRACE
{
++lexer.parsing_block;
current_block.StartLocation = GetLocation ($1);
}
opt_statement_list CLOSE_BRACE
{
--lexer.parsing_block;
$$ = end_block (GetLocation ($4));
}
;
opt_statement_list
: /* empty */
| statement_list
;
statement_list
: statement
| statement_list statement
;
statement
: block_variable_declaration
{
current_block.AddStatement ((Statement) $1);
}
| valid_declaration_statement
{
current_block.AddStatement ((Statement) $1);
}
| labeled_statement
// WORKAROUND:Remove that rule, if it is >really< fixed.
| IDENTIFIER error
{
Error_SyntaxError (yyToken);
var lt =(LocatedToken) $1;
var sn = new SimpleName (lt.Value, lt.Location);
current_block.AddStatement(new StatementErrorExpression (sn));
$$ = null;
}
////////
| error
{
Error_SyntaxError (yyToken);
$$ = null;
}
;
//
// The interactive_statement and its derivatives are only
// used to provide a special version of `expression_statement'
// that has a side effect of assigning the expression to
// $retval
//
interactive_statement_list
: interactive_statement
| interactive_statement_list interactive_statement
;
interactive_statement
: block_variable_declaration
{
current_block.AddStatement ((Statement) $1);
}
| interactive_valid_declaration_statement
{
current_block.AddStatement ((Statement) $1);
}
| labeled_statement
;
valid_declaration_statement
: block
| empty_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
| try_statement
| checked_statement
| unchecked_statement
| lock_statement
| using_statement
| unsafe_statement
| fixed_statement
;
interactive_valid_declaration_statement
: block
| empty_statement
| interactive_expression_statement
| selection_statement
| iteration_statement
| jump_statement
| try_statement
| checked_statement
| unchecked_statement
| lock_statement
| using_statement
| unsafe_statement
| fixed_statement
;
embedded_statement
: valid_declaration_statement
| block_variable_declaration
{
report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
$$ = null;
}
| labeled_statement
{
report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
$$ = null;
}
| error
{
Error_SyntaxError (yyToken);
$$ = new EmptyStatement (GetLocation ($1));
}
;
empty_statement
: SEMICOLON
{
// Uses lexer.Location because semicolon location is not kept in quick mode
$$ = new EmptyStatement (lexer.Location);
}
;
labeled_statement
: identifier_inside_body COLON
{
var lt = (LocatedToken) $1;
LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
lbag.AddLocation (labeled, GetLocation ($2));
current_block.AddLabel (labeled);
current_block.AddStatement (labeled);
}
statement
;
variable_type
: variable_type_simple
| variable_type_simple rank_specifiers
{
if ($1 is VarExpr)
$1 = new SimpleName ("var", ((VarExpr) $1).Location);
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
}
;
/*
* The following is from Rhys' grammar:
* > Types in local variable declarations must be recognized as
* > expressions to prevent reduce/reduce errors in the grammar.
* > The expressions are converted into types during semantic analysis.
*/
variable_type_simple
: primary_expression_or_type opt_nullable
{
// Ok, the above "primary_expression" is there to get rid of
// both reduce/reduce and shift/reduces in the grammar, it should
// really just be "type_name". If you use type_name, a reduce/reduce
// creeps up. If you use namespace_or_type_name (which is all we need
// really) two shift/reduces appear.
//
// So the super-trick is that primary_expression
// can only be either a SimpleName or a MemberAccess.
// The MemberAccess case arises when you have a fully qualified type-name like :
// Foo.Bar.Blah i;
// SimpleName is when you have
// Blah i;
Expression expr = (Expression) $1;
if ($2 == null) {
SimpleName sn = expr as SimpleName;
if (sn != null && sn.Name == "var")
$$ = new VarExpr (sn.Location);
else
$$ = $1;
} else if (expr is ATypeNameExpression) {
$$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
} else {
Error_ExpectingTypeName (expr);
$$ = null;
}
}
| primary_expression_or_type pointer_stars
{
ATypeNameExpression expr = $1 as ATypeNameExpression;
if (expr != null) {
$$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
} else {
Error_ExpectingTypeName ((Expression)$1);
$$ = expr;
}
}
| builtin_type_expression
| void_invalid
;
pointer_stars
: pointer_star
| pointer_star pointer_stars
{
((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
$$ = $1;
}
;
pointer_star
: STAR
{
$$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1));
}
;
identifier_inside_body
: IDENTIFIER
| AWAIT
{
$$ = Error_AwaitAsIdentifier ($1);
}
;
block_variable_declaration
: variable_type identifier_inside_body
{
var lt = (LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, lt.Location);
current_block.AddLocalName (li);
current_variable = new BlockVariable ((FullNamedExpression) $1, li);
}
opt_local_variable_initializer opt_variable_declarators semicolon_or_handle_error_close_brace
{
$$ = current_variable;
current_variable = null;
if ($4 != null)
lbag.AddLocation ($$, PopLocation (), GetLocation ($6));
else
lbag.AddLocation ($$, GetLocation ($6));
}
| CONST variable_type identifier_inside_body
{
var lt = (LocatedToken) $3;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
current_block.AddLocalName (li);
current_variable = new BlockConstant ((FullNamedExpression) $2, li);
}
const_variable_initializer opt_const_declarators SEMICOLON
{
if (current_variable.Initializer != null) {
lbag.AddLocation (current_variable, GetLocation ($1), savedLocation, GetLocation ($7));
} else {
lbag.AddLocation (current_variable, GetLocation ($1), GetLocation ($7));
}
$$ = current_variable;;
current_variable = null;
}
;
semicolon_or_handle_error_close_brace
: SEMICOLON
| CLOSE_BRACE {
// Redundant, but wont regress
report.Error (1525, lexer.Location, "Unexpected symbol }");
lexer.putback ('}');
$$ = $1;
}
;
opt_local_variable_initializer
: /* empty */
| ASSIGN block_variable_initializer
{
current_variable.Initializer = (Expression) $2;
PushLocation (GetLocation ($1));
$$ = current_variable;
}
| error
{
if (yyToken == Token.OPEN_BRACKET_EXPR) {
report.Error (650, lexer.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");
} else {
Error_SyntaxError (yyToken);
}
}
;
opt_variable_declarators
: /* empty */
| variable_declarators
;
opt_using_or_fixed_variable_declarators
: /* empty */
| variable_declarators
{
foreach (var d in current_variable.Declarators) {
if (d.Initializer == null)
Error_MissingInitializer (d.Variable.Location);
}
}
;
variable_declarators
: variable_declarator
| variable_declarators variable_declarator
;
variable_declarator
: COMMA identifier_inside_body
{
var lt = (LocatedToken) $2;
var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
var d = new BlockVariableDeclarator (li, null);
current_variable.AddDeclarator (d);
current_block.AddLocalName (li);
lbag.AddLocation (d, GetLocation ($1));
}
| COMMA identifier_inside_body ASSIGN block_variable_initializer
{
var lt = (LocatedToken) $2;
var li = new LocalVariable (current_variable.Variable, lt.Value, lt.Location);
var d = new BlockVariableDeclarator (li, (Expression) $4);
current_variable.AddDeclarator (d);
current_block.AddLocalName (li);
lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
}
;
const_variable_initializer
: /* empty */
{
report.Error (145, lexer.Location, "A const field requires a value to be provided");
}
| ASSIGN constant_initializer_expr
{
savedLocation = GetLocation ($1);
current_variable.Initializer = (Expression) $2;
}
;
opt_const_declarators
: /* empty */
| const_declarators
;
const_declarators
: const_declarator
| const_declarators const_declarator
;
const_declarator
: COMMA identifier_inside_body ASSIGN constant_initializer_expr
{
var lt = (LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, lt.Location);
var d = new BlockVariableDeclarator (li, (Expression) $4);
current_variable.AddDeclarator (d);
current_block.AddLocalName (li);
lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
}
;
block_variable_initializer
: variable_initializer
| STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
{
$$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
}
| STACKALLOC simple_type
{
report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
$$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));
}
;
expression_statement
: statement_expression SEMICOLON
{
$$ = $1;
lbag.AddStatement ($$, GetLocation ($2));
}
| statement_expression COMPLETE_COMPLETION { $$ = $1; }
| statement_expression CLOSE_BRACE
{
$$ = $1;
report.Error (1002, GetLocation ($2), "; expected");
lexer.putback ('}');
}
;
interactive_expression_statement
: interactive_statement_expression SEMICOLON { $$ = $1; }
| interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
;
//
// We have to do the wrapping here and not in the case above,
// because statement_expression is used for example in for_statement
//
statement_expression
: expression
{
ExpressionStatement s = $1 as ExpressionStatement;
if (s == null) {
var expr = $1 as Expression;
$$ = new StatementErrorExpression (expr);
} else {
$$ = new StatementExpression (s);
}
}
;
interactive_statement_expression
: expression
{
Expression expr = (Expression) $1;
$$ = new StatementExpression (new OptionalAssign (expr, lexer.Location));
}
| error
{
Error_SyntaxError (yyToken);
$$ = new EmptyStatement (GetLocation ($1));
}
;
selection_statement
: if_statement
| switch_statement
;
if_statement
: IF open_parens_any boolean_expression CLOSE_PARENS
embedded_statement
{
if ($5 is EmptyStatement)
Warning_EmptyStatement (GetLocation ($5));
$$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| IF open_parens_any boolean_expression CLOSE_PARENS
embedded_statement ELSE embedded_statement
{
$$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
if ($5 is EmptyStatement)
Warning_EmptyStatement (GetLocation ($5));
if ($7 is EmptyStatement)
Warning_EmptyStatement (GetLocation ($7));
}
| IF open_parens_any boolean_expression error
{
Error_SyntaxError (yyToken);
$$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
switch_statement
: SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE
{
start_block (GetLocation ($5));
}
opt_switch_sections CLOSE_BRACE
{
$$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1));
end_block (GetLocation ($8));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($5), GetLocation ($8));
}
| SWITCH open_parens_any expression error
{
Error_SyntaxError (yyToken);
$$ = new Switch ((Expression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
opt_switch_sections
: /* empty */
{
report.Warning (1522, 1, current_block.StartLocation, "Empty switch block");
}
| switch_sections
;
switch_sections
: switch_section
| switch_sections switch_section
| error
{
Error_SyntaxError (yyToken);
}
;
switch_section
: switch_labels statement_list
;
switch_labels
: switch_label
{
var label = (SwitchLabel) $1;
label.SectionStart = true;
current_block.AddStatement (label);
}
| switch_labels switch_label
{
current_block.AddStatement ((Statement) $2);
}
;
switch_label
: CASE constant_expression COLON
{
$$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
| CASE constant_expression error
{
Error_SyntaxError (yyToken);
$$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
}
| DEFAULT_COLON
{
$$ = new SwitchLabel (null, GetLocation ($1));
}
;
iteration_statement
: while_statement
| do_statement
| for_statement
| foreach_statement
;
while_statement
: WHILE open_parens_any boolean_expression CLOSE_PARENS embedded_statement
{
if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($5));
$$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| WHILE open_parens_any boolean_expression error
{
Error_SyntaxError (yyToken);
$$ = new While ((BooleanExpression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
do_statement
: DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
{
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
}
| DO embedded_statement error
{
Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
}
| DO embedded_statement WHILE open_parens_any boolean_expression error
{
Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
}
;
for_statement
: FOR open_parens_any
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
For f = new For (GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, current_block.StartLocation);
$$ = f;
}
for_statement_cont
{
$$ = $4;
}
;
// Has to use be extra rule to recover started block
for_statement_cont
: opt_for_initializer SEMICOLON
{
For f = (For) $0;
f.Initializer = (Statement) $1;
lbag.AddLocation (f, GetLocation ($2));
$$ = f;
}
for_statement_condition
{
$$ = $4;
}
| opt_for_initializer CLOSE_PARENS {
report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'");
For f = (For) $0;
f.Initializer = (Statement) $1;
lbag.AddLocation (f, GetLocation ($2));
$$ = end_block (GetLocation ($2));
}
;
for_statement_condition
: opt_for_condition SEMICOLON
{
For f = (For) $0;
f.Condition = (BooleanExpression) $1;
lbag.AddLocation (f, GetLocation ($2));
$$ = f;
}
for_statement_end
{
$$ = $4;
}
| boolean_expression CLOSE_PARENS {
report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'");
For f = (For) $0;
f.Condition = (BooleanExpression) $1;
lbag.AddLocation (f, GetLocation ($2));
$$ = end_block (GetLocation ($2));
}
;
for_statement_end
: opt_for_iterator CLOSE_PARENS
embedded_statement
{
For f = (For) $0;
f.Iterator = (Statement) $1;
if ($3 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($3));
f.Statement = (Statement) $3;
lbag.AddLocation (f, GetLocation ($2));
$$ = end_block (GetLocation ($2));
}
| error
{
Error_SyntaxError (yyToken);
$$ = end_block (current_block.StartLocation);
}
;
opt_for_initializer
: /* empty */ { $$ = new EmptyStatement (lexer.Location); }
| for_initializer
;
for_initializer
: variable_type identifier_inside_body
{
var lt = (LocatedToken) $2;
var li = new LocalVariable (current_block, lt.Value, lt.Location);
current_block.AddLocalName (li);
current_variable = new BlockVariable ((FullNamedExpression) $1, li);
}
opt_local_variable_initializer opt_variable_declarators
{
$$ = current_variable;
if ($4 != null)
lbag.AddLocation (current_variable, PopLocation ());
current_variable = null;
}
| statement_expression_list
;
opt_for_condition
: /* empty */ { $$ = null; }
| boolean_expression
;
opt_for_iterator
: /* empty */ { $$ = new EmptyStatement (lexer.Location); }
| for_iterator
;
for_iterator
: statement_expression_list
;
statement_expression_list
: statement_expression
| statement_expression_list COMMA statement_expression
{
var sl = $1 as StatementList;
if (sl == null) {
sl = new StatementList ((Statement) $1, (Statement) $3);
lbag.AddStatement (sl, GetLocation ($2));
} else {
sl.Add ((Statement) $3);
lbag.AddLocation (sl, GetLocation ($2));
}
$$ = sl;
}
;
foreach_statement
: FOREACH open_parens_any type error
{
report.Error (230, GetLocation ($1), "Type and identifier are both required in a foreach statement");
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($4));
}
| FOREACH open_parens_any type identifier_inside_body error
{
Error_SyntaxError (yyToken);
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = (LocatedToken) $4;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
current_block.AddLocalName (li);
Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($5));
}
| FOREACH open_parens_any type identifier_inside_body IN expression CLOSE_PARENS
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = (LocatedToken) $4;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
current_block.AddLocalName (li);
$$ = li;
}
embedded_statement
{
if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($9));
Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, current_block, GetLocation ($1));
lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
end_block (GetLocation ($7));
$$ = f;
}
| FOREACH open_parens_any type identifier_inside_body error
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = $4 as LocatedToken;
var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null;
Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($5));
}
| FOREACH open_parens_any type error
{
Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = f;
}
;
jump_statement
: break_statement
| continue_statement
| goto_statement
| return_statement
| throw_statement
| yield_statement
;
break_statement
: BREAK SEMICOLON
{
$$ = new Break (GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
continue_statement
: CONTINUE SEMICOLON
{
$$ = new Continue (GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
| CONTINUE error
{
Error_SyntaxError (yyToken);
$$ = new Continue (GetLocation ($1));
}
;
goto_statement
: GOTO identifier_inside_body SEMICOLON
{
var lt = (LocatedToken) $2;
$$ = new Goto (lt.Value, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
}
| GOTO CASE constant_expression SEMICOLON
{
$$ = new GotoCase ((Expression) $3, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| GOTO DEFAULT SEMICOLON
{
$$ = new GotoDefault (GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
}
;
return_statement
: RETURN opt_expression SEMICOLON
{
$$ = new Return ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| RETURN expression error
{
Error_SyntaxError (yyToken);
$$ = new Return ((Expression) $2, GetLocation ($1));
}
| RETURN error
{
Error_SyntaxError (yyToken);
$$ = new Return (null, GetLocation ($1));
}
;
throw_statement
: THROW opt_expression SEMICOLON
{
$$ = new Throw ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| THROW expression error
{
Error_SyntaxError (yyToken);
$$ = new Throw ((Expression) $2, GetLocation ($1));
}
| THROW error
{
Error_SyntaxError (yyToken);
$$ = new Throw (null, GetLocation ($1));
}
;
yield_statement
: identifier_inside_body RETURN opt_expression SEMICOLON
{
var lt = (LocatedToken) $1;
string s = lt.Value;
if (s != "yield"){
report.Error (1003, lt.Location, "; expected");
} else if ($3 == null) {
report.Error (1627, GetLocation ($4), "Expression expected after yield return");
} else if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (lt.Location, "iterators");
}
current_block.Explicit.RegisterIteratorYield ();
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| identifier_inside_body RETURN expression error
{
Error_SyntaxError (yyToken);
var lt = (LocatedToken) $1;
string s = lt.Value;
if (s != "yield"){
report.Error (1003, lt.Location, "; expected");
} else if ($3 == null) {
report.Error (1627, GetLocation ($4), "Expression expected after yield return");
} else if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (lt.Location, "iterators");
}
current_block.Explicit.RegisterIteratorYield ();
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2));
}
| identifier_inside_body BREAK SEMICOLON
{
var lt = (LocatedToken) $1;
string s = lt.Value;
if (s != "yield"){
report.Error (1003, lt.Location, "; expected");
} else if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (lt.Location, "iterators");
}
current_block.ParametersBlock.TopBlock.IsIterator = true;
$$ = new YieldBreak (lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
}
;
opt_expression
: /* empty */
| expression
;
try_statement
: TRY block catch_clauses
{
$$ = new TryCatch ((Block) $2, (List) $3, GetLocation ($1), false);
}
| TRY block FINALLY block
{
$$ = new TryFinally ((Statement) $2, (ExplicitBlock) $4, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| TRY block catch_clauses FINALLY block
{
$$ = new TryFinally (new TryCatch ((Block) $2, (List) $3, GetLocation ($1), true), (ExplicitBlock) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($4));
}
| TRY block error
{
Error_SyntaxError (1524, yyToken);
$$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
}
;
catch_clauses
: catch_clause
{
var l = new List (2);
l.Add ((Catch) $1);
$$ = l;
}
| catch_clauses catch_clause
{
var l = (List) $1;
Catch c = (Catch) $2;
var prev_catch = l [l.Count - 1];
if (prev_catch.IsGeneral && prev_catch.Filter == null) {
report.Error (1017, c.loc, "Try statement already has an empty catch block");
}
l.Add (c);
$$ = l;
}
;
opt_identifier
: /* empty */
| identifier_inside_body
;
catch_clause
: CATCH opt_catch_filter block
{
var c = new Catch ((ExplicitBlock) $3, GetLocation ($1));
c.Filter = (CatchFilterExpression) $2;
$$ = c;
}
| CATCH open_parens_any type opt_identifier CLOSE_PARENS
{
start_block (GetLocation ($2));
var c = new Catch ((ExplicitBlock) current_block, GetLocation ($1));
c.TypeExpression = (FullNamedExpression) $3;
if ($4 != null) {
var lt = (LocatedToken) $4;
c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
current_block.AddLocalName (c.Variable);
}
lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
$$ = c;
}
opt_catch_filter block_prepared
{
((Catch) $6).Filter = (CatchFilterExpression) $7;
$$ = $6;
}
| CATCH open_parens_any error
{
if (yyToken == Token.CLOSE_PARENS) {
report.Error (1015, lexer.Location,
"A type that derives from `System.Exception', `object', or `string' expected");
} else {
Error_SyntaxError (yyToken);
}
$$ = 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 = (LocatedToken) $4;
c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
}
if ($4 != null) {
var lt = (LocatedToken) $4;
c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
}
lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
$$ = c;
}
;
opt_catch_filter
: /* empty */
| IF open_parens_any expression CLOSE_PARENS
{
if (lang_version <= LanguageVersion.V_5)
FeatureIsNotAvailable (GetLocation ($1), "exception filter");
$$ = new CatchFilterExpression ((Expression) $3, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
}
;
checked_statement
: CHECKED block
{
$$ = new Checked ((Block) $2, GetLocation ($1));
}
;
unchecked_statement
: UNCHECKED block
{
$$ = new Unchecked ((Block) $2, GetLocation ($1));
}
;
unsafe_statement
: UNSAFE
{
if (!settings.Unsafe)
Error_UnsafeCodeNotAllowed (GetLocation ($1));
} block {
$$ = new Unsafe ((Block) $3, GetLocation ($1));
}
;
lock_statement
: LOCK open_parens_any expression CLOSE_PARENS embedded_statement
{
if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($5));
$$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| LOCK open_parens_any expression error
{
Error_SyntaxError (yyToken);
$$ = new Lock ((Expression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
fixed_statement
: FIXED open_parens_any variable_type identifier_inside_body
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = (LocatedToken) $4;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location);
current_block.AddLocalName (li);
current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li);
}
using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS
{
$$ = current_variable;
current_variable = null;
}
embedded_statement
{
if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($10));
Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2), GetLocation ($8));
$$ = end_block (GetLocation ($8));
}
;
using_statement
: USING open_parens_any variable_type identifier_inside_body
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = (LocatedToken) $4;
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location);
current_block.AddLocalName (li);
current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li);
}
using_initialization CLOSE_PARENS
{
$$ = current_variable;
current_variable = null;
}
embedded_statement
{
if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($9));
Using u = new Using ((Using.VariableDeclaration) $8, (Statement) $9, GetLocation ($1));
lbag.AddStatement (u, GetLocation ($2), GetLocation ($7));
current_block.AddStatement (u);
$$ = end_block (GetLocation ($7));
}
| USING open_parens_any expression CLOSE_PARENS embedded_statement
{
if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($5));
$$ = new Using ((Expression) $3, (Statement) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
}
| USING open_parens_any expression error
{
Error_SyntaxError (yyToken);
$$ = new Using ((Expression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
;
using_initialization
: using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators
| error
{
// It has to be here for the parent to safely restore artificial block
Error_SyntaxError (yyToken);
}
;
using_or_fixed_variable_initializer
: /* empty */
{
Error_MissingInitializer (lexer.Location);
}
| ASSIGN variable_initializer
{
current_variable.Initializer = (Expression) $2;
lbag.AddLocation (current_variable, GetLocation ($1));
$$ = current_variable;
}
;
// LINQ
query_expression
: first_from_clause query_body
{
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;
}
| nested_from_clause query_body
{
Linq.AQueryClause from = $1 as Linq.AQueryClause;
from.Tail.Next = (Linq.AQueryClause)$2;
$$ = from;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
// Bubble up COMPLETE_COMPLETION productions
| first_from_clause COMPLETE_COMPLETION {
lexer.query_parsing = false;
$$ = $1;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
| nested_from_clause COMPLETE_COMPLETION {
$$ = $1;
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
;
first_from_clause
: FROM_FIRST identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var lt = (LocatedToken) $2;
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1));
lbag.AddLocation (clause, GetLocation ($3));
$$ = new Linq.QueryExpression (clause);
}
| FROM_FIRST type identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var lt = (LocatedToken) $3;
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
IdentifierType = (FullNamedExpression)$2
};
lbag.AddLocation (clause, GetLocation ($4));
$$ = new Linq.QueryExpression (clause);
}
;
nested_from_clause
: FROM identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var lt = (LocatedToken) $2;
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1));
lbag.AddLocation (clause, GetLocation ($3));
$$ = new Linq.QueryExpression (clause);
}
| FROM type identifier_inside_body IN expression
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
var lt = (LocatedToken) $3;
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
var clause = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
IdentifierType = (FullNamedExpression)$2
};
lbag.AddLocation (clause, GetLocation ($4));
$$ = new Linq.QueryExpression (clause);
}
;
from_clause
: FROM identifier_inside_body IN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
expression_or_error
{
var lt = (LocatedToken) $2;
var sn = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
lbag.AddLocation ($$, GetLocation ($3));
}
| FROM type identifier_inside_body IN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
expression_or_error
{
var lt = (LocatedToken) $3;
var sn = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
IdentifierType = (FullNamedExpression)$2
};
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
lbag.AddLocation ($$, GetLocation ($4));
}
;
query_body
: query_body_clauses select_or_group_clause opt_query_continuation
{
Linq.AQueryClause head = (Linq.AQueryClause)$2;
if ($3 != null)
head.Next = (Linq.AQueryClause)$3;
if ($1 != null) {
Linq.AQueryClause clause = (Linq.AQueryClause)$1;
clause.Tail.Next = head;
head = clause;
}
$$ = head;
}
| select_or_group_clause opt_query_continuation
{
Linq.AQueryClause head = (Linq.AQueryClause)$2;
if ($1 != null) {
Linq.AQueryClause clause = (Linq.AQueryClause)$1;
clause.Tail.Next = head;
head = clause;
}
$$ = head;
}
| query_body_clauses COMPLETE_COMPLETION
| query_body_clauses error
{
report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
$$ = $1;
}
| error
{
Error_SyntaxError (yyToken);
$$ = null;
}
;
select_or_group_clause
: SELECT
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
expression_or_error
{
$$ = new Linq.Select ((Linq.QueryBlock)current_block, (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 ((Linq.QueryBlock)current_block);
}
expression_or_error
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
by_expression
{
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
| query_body_clauses query_body_clause
{
((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
$$ = $1;
}
;
query_body_clause
: from_clause
| let_clause
| where_clause
| join_clause
| orderby_clause
;
let_clause
: LET identifier_inside_body ASSIGN
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
expression_or_error
{
var lt = (LocatedToken) $2;
var sn = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
}
;
where_clause
: WHERE
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
}
expression_or_error
{
$$ = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
;
join_clause
: JOIN identifier_inside_body IN
{
if (linq_clause_blocks == null)
linq_clause_blocks = new Stack ();
current_block = new Linq.QueryBlock (current_block, lexer.Location);
linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
expression_or_error ON
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
current_block = new Linq.QueryBlock (current_block, lexer.Location);
linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
expression_or_error 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, lexer.Location);
}
expression_or_error opt_join_into
{
current_block.AddStatement (new ContextualReturn ((Expression) $11));
current_block.SetEndLocation (lexer.Location);
var outer_selector = linq_clause_blocks.Pop ();
var block = linq_clause_blocks.Pop ();
var lt = (LocatedToken) $2;
var sn = new Linq.RangeVariable (lt.Value, lt.Location);
Linq.RangeVariable into;
if ($12 == null) {
into = sn;
$$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
} else {
//
// Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
//
var parent = block.Parent;
while (parent is Linq.QueryBlock) {
parent = parent.Parent;
}
current_block.Parent = parent;
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
lt = (LocatedToken) $12;
into = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), opt_intoStack.Pop ());
}
current_block = block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (into);
}
| JOIN type identifier_inside_body IN
{
if (linq_clause_blocks == null)
linq_clause_blocks = new Stack ();
current_block = new Linq.QueryBlock (current_block, lexer.Location);
linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
expression_or_error ON
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
current_block = new Linq.QueryBlock (current_block, lexer.Location);
linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
expression_or_error 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, lexer.Location);
}
expression_or_error opt_join_into
{
current_block.AddStatement (new ContextualReturn ((Expression) $12));
current_block.SetEndLocation (lexer.Location);
var outer_selector = linq_clause_blocks.Pop ();
var block = linq_clause_blocks.Pop ();
var lt = (LocatedToken) $3;
var sn = new Linq.RangeVariable (lt.Value, lt.Location);
Linq.RangeVariable into;
if ($13 == null) {
into = sn;
$$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
IdentifierType = (FullNamedExpression)$2
};
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
} else {
//
// Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
//
var parent = block.Parent;
while (parent is Linq.QueryBlock) {
parent = parent.Parent;
}
current_block.Parent = parent;
((Linq.QueryBlock)current_block).AddRangeVariable (sn);
lt = (LocatedToken) $13;
into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO:
$$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) {
IdentifierType = (FullNamedExpression)$2
};
lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), opt_intoStack.Pop ());
}
current_block = block.Parent;
((Linq.QueryBlock)current_block).AddRangeVariable (into);
}
;
opt_join_into
: /* empty */
| INTO identifier_inside_body
{
opt_intoStack.Push (GetLocation ($1));
$$ = $2;
}
;
orderby_clause
: ORDERBY
{
current_block = new Linq.QueryBlock (current_block, lexer.Location);
lbag.AddLocation (current_block, GetLocation ($1));
}
orderings
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
$$ = $3;
}
;
orderings
: order_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)$4;
$$ = $1;
}
;
orderings_then_by
: then_by
| orderings_then_by COMMA
{
current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location);
}
then_by
{
((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
$$ = $1;
}
;
order_by
: expression
{
$$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression ASCENDING
{
$$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
lbag.AddLocation ($$, GetLocation ($2));
}
| expression DESCENDING
{
$$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);
lbag.AddLocation ($$, GetLocation ($2));
}
;
then_by
: expression
{
$$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
}
| expression ASCENDING
{
$$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);
lbag.AddLocation ($$, GetLocation ($2));
}
| expression DESCENDING
{
$$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);
lbag.AddLocation ($$, GetLocation ($2));
}
;
opt_query_continuation
: /* empty */
| 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
// different identifiers.
current_block.SetEndLocation (GetLocation ($1));
current_block = current_block.Parent;
current_block = new Linq.QueryBlock (current_block, lexer.Location);
if (linq_clause_blocks == null)
linq_clause_blocks = new Stack ();
linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
}
query_body
{
var current_block = linq_clause_blocks.Pop ();
var lt = (LocatedToken) $2;
var rv = new Linq.RangeVariable (lt.Value, lt.Location);
$$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) {
next = (Linq.AQueryClause)$4
};
}
;
//
// Support for using the compiler as an interactive parser
//
// The INTERACTIVE_PARSER token is first sent to parse our
// productions; If the result is a Statement, the parsing
// is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
// to setup the blocks in advance.
//
// This setup is here so that in the future we can add
// support for other constructs (type parsing, namespaces, etc)
// that do not require a block to be setup in advance
//
interactive_parsing
: EVAL_STATEMENT_PARSER EOF
| EVAL_USING_DECLARATIONS_UNIT_PARSER using_directives opt_COMPLETE_COMPLETION
| EVAL_STATEMENT_PARSER
{
current_container = current_type = new Class (current_container, new MemberName (""), Modifiers.PUBLIC, null);
// (ref object retval)
Parameter [] mpar = new Parameter [1];
mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
ParametersCompiled pars = new ParametersCompiled (mpar);
var mods = Modifiers.PUBLIC | Modifiers.STATIC;
if (settings.Unsafe)
mods |= Modifiers.UNSAFE;
current_local_parameters = pars;
var method = new InteractiveMethod (
current_type,
new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
mods,
pars);
current_type.AddMember (method);
oob_stack.Push (method);
interactive_async = false;
++lexer.parsing_block;
start_block (lexer.Location);
}
interactive_statement_list opt_COMPLETE_COMPLETION
{
--lexer.parsing_block;
var method = (InteractiveMethod) oob_stack.Pop ();
method.Block = (ToplevelBlock) end_block(lexer.Location);
if (interactive_async == true) {
method.ChangeToAsync ();
}
InteractiveResult = (Class) pop_current_class ();
current_local_parameters = null;
}
| EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit
;
interactive_compilation_unit
: opt_extern_alias_directives opt_using_directives
| opt_extern_alias_directives opt_using_directives namespace_or_type_declarations
;
opt_COMPLETE_COMPLETION
: /* nothing */
| COMPLETE_COMPLETION
;
close_brace_or_complete_completion
: CLOSE_BRACE
| COMPLETE_COMPLETION
;
//
// XML documentation code references micro parser
//
documentation_parsing
: DOC_SEE doc_cref
{
module.DocumentationBuilder.ParsedName = (MemberName) $2;
}
;
doc_cref
: doc_type_declaration_name opt_doc_method_sig
{
module.DocumentationBuilder.ParsedParameters = (List)$2;
}
| builtin_types opt_doc_method_sig
{
module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
module.DocumentationBuilder.ParsedParameters = (List)$2;
$$ = null;
}
| VOID opt_doc_method_sig
{
module.DocumentationBuilder.ParsedBuiltinType = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
module.DocumentationBuilder.ParsedParameters = (List)$2;
$$ = null;
}
| builtin_types DOT IDENTIFIER opt_doc_method_sig
{
module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
module.DocumentationBuilder.ParsedParameters = (List)$4;
var lt = (LocatedToken) $3;
$$ = new MemberName (lt.Value);
}
| doc_type_declaration_name DOT THIS
{
$$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
}
| doc_type_declaration_name DOT THIS OPEN_BRACKET
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_doc_parameters CLOSE_BRACKET
{
module.DocumentationBuilder.ParsedParameters = (List)$6;
$$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
}
| EXPLICIT OPERATOR type opt_doc_method_sig
{
var p = (List)$4 ?? new List (1);
p.Add (new DocumentationParameter ((FullNamedExpression) $3));
module.DocumentationBuilder.ParsedParameters = p;
module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit;
$$ = null;
}
| IMPLICIT OPERATOR type opt_doc_method_sig
{
var p = (List)$4 ?? new List (1);
p.Add (new DocumentationParameter ((FullNamedExpression) $3));
module.DocumentationBuilder.ParsedParameters = p;
module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit;
$$ = null;
}
| OPERATOR overloadable_operator opt_doc_method_sig
{
var p = (List)$3;
module.DocumentationBuilder.ParsedParameters = p;
module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2;
$$ = null;
}
;
doc_type_declaration_name
: type_declaration_name
| doc_type_declaration_name DOT type_declaration_name
{
$$ = new MemberName (((MemberName) $1), (MemberName) $3);
}
;
opt_doc_method_sig
: /* empty */
| OPEN_PARENS
{
valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
}
opt_doc_parameters CLOSE_PARENS
{
$$ = $3;
}
;
opt_doc_parameters
: /* empty */
{
$$ = new List (0);
}
| doc_parameters
;
doc_parameters
: doc_parameter
{
var parameters = new List ();
parameters.Add ((DocumentationParameter) $1);
$$ = parameters;
}
| doc_parameters COMMA doc_parameter
{
var parameters = $1 as List;
parameters.Add ((DocumentationParameter) $3);
$$ = parameters;
}
;
doc_parameter
: opt_parameter_modifier parameter_type
{
if ($1 != null)
$$ = new DocumentationParameter ((Parameter.Modifier) $1, (FullNamedExpression) $2);
else
$$ = new DocumentationParameter ((FullNamedExpression) $2);
}
;
%%
//
// A class used to hold info about an operator declarator
//
class OperatorDeclaration {
public readonly Operator.OpType optype;
public readonly FullNamedExpression ret_type;
public readonly Location location;
public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
{
optype = op;
this.ret_type = ret_type;
this.location = location;
}
}
void Error_ExpectingTypeName (Expression expr)
{
if (expr is Invocation){
report.Error (1002, expr.Location, "Expecting `;'");
} else {
expr.Error_InvalidExpressionStatement (report);
}
}
void Error_ParameterModifierNotValid (string modifier, Location loc)
{
report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
modifier);
}
void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
{
report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
Parameter.GetModifierSignature (mod));
}
void Error_TypeExpected (Location loc)
{
report.Error (1031, loc, "Type expected");
}
void Error_UnsafeCodeNotAllowed (Location loc)
{
report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
}
void Warning_EmptyStatement (Location loc)
{
report.Warning (642, 3, loc, "Possible mistaken empty statement");
}
void Error_NamedArgumentExpected (NamedArgument a)
{
report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
}
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 LocatedToken ("await", GetLocation (token));
}
return token;
}
void push_current_container (TypeDefinition tc, object partial_token)
{
if (module.Evaluator != null){
tc.Definition.Modifiers = tc.ModFlags = (tc.ModFlags & ~Modifiers.AccessibilityMask) | Modifiers.PUBLIC;
if (undo == null)
undo = new Undo ();
undo.AddTypeContainer (current_container, tc);
}
if (partial_token != null)
current_container.AddPartial (tc);
else
current_container.AddTypeContainer (tc);
++lexer.parsing_declaration;
current_container = tc;
current_type = tc;
}
TypeContainer pop_current_class ()
{
var retval = current_container;
current_container = current_container.Parent;
current_type = current_type.Parent as TypeDefinition;
return retval;
}
[System.Diagnostics.Conditional ("FULL_AST")]
void StoreModifierLocation (object token, Location loc)
{
if (lbag == null)
return;
if (mod_locations == null)
mod_locations = new List> ();
mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
}
List> GetModifierLocations ()
{
var result = mod_locations;
mod_locations = null;
return result;
}
[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 (int token, string a, Location l)
{
switch (a) {
case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
return a;
}
if (!Tokenizer.IsValidIdentifier (a)) {
Error_SyntaxError (token);
} else {
report.Warning (658, 1, l,
"`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
}
return string.Empty;
}
static bool IsUnaryOperator (Operator.OpType op)
{
switch (op) {
case Operator.OpType.LogicalNot:
case Operator.OpType.OnesComplement:
case Operator.OpType.Increment:
case Operator.OpType.Decrement:
case Operator.OpType.True:
case Operator.OpType.False:
case Operator.OpType.UnaryPlus:
case Operator.OpType.UnaryNegation:
return true;
}
return false;
}
void syntax_error (Location l, string msg)
{
report.Error (1003, l, "Syntax error, " + msg);
}
Tokenizer lexer;
public Tokenizer Lexer {
get {
return lexer;
}
}
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
: this (reader, file, file.Compiler.Report, session)
{
}
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
{
this.file = file;
current_container = current_namespace = file;
this.module = file.Module;
this.compiler = file.Compiler;
this.settings = compiler.Settings;
this.report = report;
lang_version = settings.Version;
yacc_verbose_flag = settings.VerboseParserFlag;
doc_support = settings.DocumentationFile != null;
lexer = new Tokenizer (reader, file, session, report);
oob_stack = new Stack ();
lbag = session.LocationsBag;
use_global_stacks = session.UseJayGlobalArrays;
parameters_bucket = session.ParametersStack;
}
public void parse ()
{
eof_token = Token.EOF;
try {
if (yacc_verbose_flag > 1)
yyparse (lexer, new yydebug.yyDebugSimple ());
else
yyparse (lexer);
Tokenizer tokenizer = lexer as Tokenizer;
tokenizer.cleanup ();
} catch (Exception e){
if (e is yyParser.yyUnexpectedEof) {
Error_SyntaxError (yyToken);
UnexpectedEOF = true;
return;
}
if (e is yyParser.yyException) {
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)
throw;
report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
}
}
}
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, GetTokenName (yyToken));
else
report.Error (error, loc, msg);
}
string ConsumeStoredComment ()
{
string s = tmpComment;
tmpComment = null;
Lexer.doc_state = XmlCommentState.Allowed;
return s;
}
void FeatureIsNotAvailable (Location loc, string feature)
{
report.FeatureIsNotAvailable (compiler, loc, feature);
}
Location GetLocation (object obj)
{
var lt = obj as LocatedToken;
if (lt != null)
return lt.Location;
var mn = obj as MemberName;
if (mn != null)
return mn.Location;
var expr = obj as Expression;
if (expr != null)
return expr.Location;
return lexer.Location;
}
void start_block (Location loc)
{
if (current_block == null) {
current_block = new ToplevelBlock (compiler, current_local_parameters, loc);
parsing_anonymous_method = false;
} else if (parsing_anonymous_method) {
current_block = new ParametersBlock (current_block, current_local_parameters, loc);
parsing_anonymous_method = false;
} else {
current_block = new ExplicitBlock (current_block, loc, Location.Null);
}
}
Block
end_block (Location loc)
{
Block retval = current_block.Explicit;
retval.SetEndLocation (loc);
current_block = retval.Parent;
return retval;
}
void start_anonymous (bool isLambda, ParametersCompiled parameters, bool isAsync, Location loc)
{
oob_stack.Push (current_anonymous_method);
oob_stack.Push (current_local_parameters);
oob_stack.Push (current_variable);
oob_stack.Push (async_block);
current_local_parameters = parameters;
if (isLambda) {
if (lang_version <= LanguageVersion.ISO_2)
FeatureIsNotAvailable (loc, "lambda expressions");
current_anonymous_method = new LambdaExpression (loc);
} else {
if (lang_version == LanguageVersion.ISO_1)
FeatureIsNotAvailable (loc, "anonymous methods");
current_anonymous_method = new AnonymousMethodExpression (loc);
}
current_anonymous_method.IsAsync = isAsync;
async_block = isAsync;
// Force the next block to be created as a ToplevelBlock
parsing_anonymous_method = true;
}
/*
* 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 (ParametersBlock anon_block)
{
AnonymousMethodExpression retval;
if (async_block)
anon_block.IsAsync = true;
current_anonymous_method.Block = anon_block;
retval = current_anonymous_method;
async_block = (bool) oob_stack.Pop ();
current_variable = (BlockVariable) oob_stack.Pop ();
current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
return retval;
}
void Error_SyntaxError (int token)
{
Error_SyntaxError (0, token);
}
void Error_SyntaxError (int error_code, int token)
{
Error_SyntaxError (error_code, token, "Unexpected symbol");
}
void Error_SyntaxError (int error_code, int token, string msg)
{
Lexer.CompleteOnEOF = false;
// An error message has been reported by tokenizer
if (token == Token.ERROR)
return;
// Avoid duplicit error message after unterminated string literals
if (token == Token.LITERAL && lexer.Location.Column == 0)
return;
string symbol = GetSymbolName (token);
string expecting = GetExpecting ();
var loc = lexer.Location - symbol.Length;
if (error_code == 0) {
if (expecting == "`identifier'") {
if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) {
report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol);
return;
}
error_code = 1001;
expecting = "identifier";
} else if (expecting == "`)'") {
error_code = 1026;
} else {
error_code = 1525;
}
}
if (string.IsNullOrEmpty (expecting))
report.Error (error_code, loc, "{1} `{0}'", symbol, msg);
else
report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg);
}
string GetExpecting ()
{
int [] tokens = yyExpectingTokens (yyExpectingState);
var names = new List (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 ? "'" : count < 3 ? "' " : "', ");
}
return sb.ToString ();
}
string GetSymbolName (int token)
{
switch (token){
case Token.LITERAL:
return ((Constant)lexer.Value).GetValue ().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.ASYNC:
return "async";
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:
case Token.EXTERN_ALIAS:
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.REFVALUE:
return "__refvalue";
case Token.REFTYPE:
return "__reftype";
case Token.MAKEREF:
return "__makeref";
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:
case Token.OPEN_BRACKET_EXPR:
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:
return "value";
case Token.IDENTIFIER:
case Token.AWAIT:
return "identifier";
case Token.EOF:
return "end-of-file";
// All of these are internal.
case Token.NONE:
case Token.ERROR:
case Token.FIRST_KEYWORD:
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 */
}