/// The C# Parser
/// </summary>
public class CSharpParser : GenericParser {
- Namespace current_namespace;
- TypeContainer current_container;
+ NamespaceEntry current_namespace;
+ TypeContainer current_container;
- // <summary>
- // Current block is used to add statements as we find
- // them.
- // </summary>
+ IIteratorContainer iterator_container;
+ /// <summary>
+ /// Current block is used to add statements as we find
+ /// them.
+ /// </summary>
Block current_block;
- // <summary>
- // Current interface is used by the various declaration
- // productions in the interface declaration to "add"
- // the interfaces as we find them.
- // </summary>
+ /// <summary>
+ /// If true, creates a toplevel block in the block production
+ /// This is flagged by the delegate creation
+ /// </summary>
+ bool create_toplevel_block;
+
+ /// <summary>
+ /// <summary>
+ /// Current interface is used by the various declaration
+ /// productions in the interface declaration to "add"
+ /// the interfaces as we find them.
+ /// </summary>
Interface current_interface;
- // <summary>
- // This is used by the unary_expression code to resolve
- // a name against a parameter.
- // </summary>
+ /// <summary>
+ /// This is used by the unary_expression code to resolve
+ /// a name against a parameter.
+ /// </summary>
Parameters current_local_parameters;
- // <summary>
- // Using during property parsing to describe the implicit
- // value parameter that is passed to the "set" and "get"accesor
- // methods (properties and indexers).
- // </summary>
+ /// <summary>
+ /// Using during property parsing to describe the implicit
+ /// value parameter that is passed to the "set" and "get"accesor
+ /// methods (properties and indexers).
+ /// </summary>
Expression implicit_value_parameter_type;
Parameters indexer_parameters;
- // <summary>
- // Used to determine if we are parsing the get/set pair
- // of an indexer or a property
- // </summmary>
+ /// <summary>
+ /// Used to determine if we are parsing the get/set pair
+ /// of an indexer or a property
+ /// </summmary>
bool parsing_indexer;
- //
- // An out-of-band stack.
- //
+ ///
+ /// An out-of-band stack.
+ ///
Stack oob_stack;
- //
- // Switch stack.
- //
+ ///
+ /// Switch stack.
+ ///
Stack switch_stack;
- //
- // The current file.
- //
+ ///
+ /// The current file.
+ ///
SourceFile file;
%}
/*
*These are the C# keywords
*/
+%token FIRST_KEYWORD
%token ABSTRACT
%token AS
%token ADD
%token VOLATILE
%token WHILE
+/* v2 tokens */
+%token YIELD
+
/* C# keywords which are not really keywords */
%token GET "get"
%token SET "set"
+%left LAST_KEYWORD
+
/* C# single character operators/punctuation. */
%token OPEN_BRACE "{"
%token CLOSE_BRACE "}"
%token LITERAL_STRING "string literal"
%token IDENTIFIER
+%token CLOSE_PARENS_CAST
+%token CLOSE_PARENS_NO_CAST
+%token CLOSE_PARENS_OPEN_PARENS
+%token CLOSE_PARENS_MINUS
/* Add precedence rules to solve dangling else s/r conflict */
%nonassoc LOWPREC
: USING IDENTIFIER ASSIGN
namespace_or_type_name SEMICOLON
{
- current_namespace.UsingAlias ((string) $2, (string) $4, lexer.Location);
+ current_namespace.UsingAlias ((string) $2, (string) ($4).ToString (), lexer.Location);
+ }
+ | USING error {
+ CheckIdentifierToken (yyToken);
}
;
+ " Expected class, delegate, enum, interface, or struct");
}
- current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3);
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) ($3).ToString (), lexer.Location);
}
namespace_body opt_semicolon
{
;
qualified_identifier
- : IDENTIFIER
+ : IDENTIFIER { $$ = new QualifiedIdentifier ((string) $1); }
| qualified_identifier DOT IDENTIFIER {
- $$ = (($1).ToString ()) + "." + ($3.ToString ()); }
+ $$ = new QualifiedIdentifier ((QualifiedIdentifier) $1, (string) $3);
+ }
;
namespace_name
- : namespace_or_type_name
+ : namespace_or_type_name { $$ = ($1).ToString (); }
;
namespace_body
}
current_namespace.DeclarationFound = true;
}
- | namespace_declaration
+ | namespace_declaration {
+ current_namespace.DeclarationFound = true;
+ }
+
+ | field_declaration {
+ Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
+ }
+ | method_declaration {
+ Report.Error (116, lexer.Location, "A namespace can only contain types and namespace declarations");
+ }
;
type_declaration
// Enable this when we have handled all errors, because this acts as a generic fallback
//
// | error {
+// Console.WriteLine ("Token=" + yyToken);
// Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
// }
;
attribute_list
: attribute
{
- ArrayList attrs = new ArrayList ();
+ ArrayList attrs = new ArrayList (4);
attrs.Add ($1);
$$ = attrs;
}
opt_attribute_arguments
{
- $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+ $$ = new Attribute ((string) ($1).ToString (), (ArrayList) $3, (Location) $2);
}
;
if ($1 == null)
$$ = null;
else {
- ArrayList args = new ArrayList ();
+ ArrayList args = new ArrayList (4);
args.Add ($1);
$$ = args;
}
| positional_argument_list COMMA named_argument_list
{
- ArrayList args = new ArrayList ();
+ ArrayList args = new ArrayList (4);
args.Add ($1);
args.Add ($3);
}
| named_argument_list
{
- ArrayList args = new ArrayList ();
+ ArrayList args = new ArrayList (4);
args.Add (null);
args.Add ($1);
positional_argument_list
: expression
{
- ArrayList args = new ArrayList ();
+ ArrayList args = new ArrayList (4);
args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
$$ = args;
named_argument_list
: named_argument
{
- ArrayList args = new ArrayList ();
+ ArrayList args = new ArrayList (4);
args.Add ($1);
$$ = args;
Struct new_struct;
string full_struct_name = MakeName ((string) $4);
- new_struct = new Struct (current_container, full_struct_name, (int) $2,
- (Attributes) $1, lexer.Location);
+ new_struct = new Struct (current_namespace, current_container, full_struct_name,
+ (int) $2, (Attributes) $1, lexer.Location);
current_container = new_struct;
- current_container.Namespace = current_namespace;
RootContext.Tree.RecordDecl (full_struct_name, new_struct);
}
opt_class_base
CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
$$ = new_struct;
}
+ | opt_attributes opt_modifiers STRUCT error {
+ CheckIdentifierToken (yyToken);
+ }
;
struct_body
constant_declarators
: constant_declarator
{
- ArrayList constants = new ArrayList ();
+ ArrayList constants = new ArrayList (4);
constants.Add ($1);
$$ = constants;
}
CheckDef (current_container.AddField (field), field.Name, l);
}
}
+ | opt_attributes
+ opt_modifiers
+ VOID
+ variable_declarators
+ SEMICOLON {
+ Report.Error (670, lexer.Location, "void type is not allowed for fields");
+ }
;
variable_declarators
: variable_declarator
{
- ArrayList decl = new ArrayList ();
+ ArrayList decl = new ArrayList (4);
decl.Add ($1);
$$ = decl;
}
;
method_declaration
- : method_header
+ : method_header {
+ iterator_container = (IIteratorContainer) $1;
+ }
method_body
{
Method method = (Method) $1;
- Block b = (Block) $2;
+ Block b = (Block) $3;
const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
if (b == null){
}
}
- method.Block = (Block) $2;
+ method.Block = (Block) $3;
CheckDef (current_container.AddMethod (method), method.Name, method.Location);
current_local_parameters = null;
+ iterator_container = null;
}
;
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method ((Expression) $3, (int) $2, (string) $4,
+ Method method = new Method (current_container, (Expression) $3, (int) $2, (string) $4,
(Parameters) $6, (Attributes) $1, lexer.Location);
current_local_parameters = (Parameters) $6;
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method (TypeManager.system_void_expr, (int) $2, (string) $4,
- (Parameters) $6, (Attributes) $1, lexer.Location);
+ Method method = new Method (current_container, TypeManager.system_void_expr, (int) $2,
+ (string) $4, (Parameters) $6, (Attributes) $1,
+ lexer.Location);
current_local_parameters = (Parameters) $6;
$$ = method;
}
+ | opt_attributes
+ opt_modifiers
+ type
+ modifiers member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+ {
+ Report.Error (1585, lexer.Location,
+ String.Format ("Modifier {0} should appear before type",
+ Modifiers.Name ((int) $4)));
+ Method method = new Method (current_container, TypeManager.system_void_expr, 0,
+ (string) $5, (Parameters) $7, (Attributes) $1,
+ lexer.Location);
+
+ current_local_parameters = (Parameters) $7;
+ $$ = method;
+ }
;
method_body
fixed_parameters
: fixed_parameter
{
- ArrayList pars = new ArrayList ();
+ ArrayList pars = new ArrayList (4);
pars.Add ($1);
$$ = pars;
{
$$ = new Parameter ((Expression) $3, (string) $4, (Parameter.Modifier) $2, (Attributes) $1);
}
+ | opt_attributes
+ opt_parameter_modifier
+ type
+ error {
+ CheckIdentifierToken (yyToken);
+ $$ = null;
+ }
;
opt_parameter_modifier
$$ = new Parameter ((Expression) $3, (string) $4, Parameter.Modifier.PARAMS, (Attributes) $1);
note ("type must be a single-dimension array type");
}
+ | opt_attributes PARAMS type error {
+ CheckIdentifierToken (yyToken);
+ $$ = null;
+ }
;
member_name
- : qualified_identifier
+ : qualified_identifier { $$ = ($1).ToString (); }
;
property_declaration
Accessor set_block = (Accessor) pair.Second;
Location loc = (Location) $6;
- prop = new Property ((Expression) $3, (string) $4, (int) $2, get_block, set_block,
- (Attributes) $1, loc);
+ prop = new Property (current_container, (Expression) $3, (string) $4, (int) $2,
+ get_block, set_block, (Attributes) $1, loc);
CheckDef (current_container.AddProperty (prop), prop.Name, loc);
implicit_value_parameter_type = null;
Interface new_interface;
string full_interface_name = MakeName ((string) $4);
- new_interface = new Interface (current_container, full_interface_name, (int) $2,
- (Attributes) $1, lexer.Location);
+ new_interface = new Interface (current_namespace, current_container, full_interface_name,
+ (int) $2, (Attributes) $1, lexer.Location);
if (current_interface != null) {
Location l = lexer.Location;
Report.Error (-2, l, "Internal compiler error: interface inside interface");
}
current_interface = new_interface;
- new_interface.Namespace = current_namespace;
RootContext.Tree.RecordDecl (full_interface_name, new_interface);
}
opt_interface_base
CheckDef (current_container.AddInterface (new_interface),
new_interface.Name, new_interface.Location);
}
+ | opt_attributes opt_modifiers INTERFACE error {
+ CheckIdentifierToken (yyToken);
+ }
;
opt_interface_base
interface_type_list
: interface_type
{
- ArrayList interfaces = new ArrayList ();
+ ArrayList interfaces = new ArrayList (4);
- interfaces.Add ($1);
+ interfaces.Add (($1).ToString ());
$$ = interfaces;
}
| interface_type_list COMMA interface_type
{
ArrayList interfaces = (ArrayList) $1;
- interfaces.Add ($3);
+ interfaces.Add (($3).ToString ());
$$ = interfaces;
}
;
}
| interface_event_declaration
{
- InterfaceEvent e = (InterfaceEvent) $1;
-
- CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
+ if ($1 != null){
+ InterfaceEvent e = (InterfaceEvent) $1;
+ CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
+ }
}
| interface_indexer_declaration
{
;
opt_new
- : /* empty */ { $$ = false; }
- | NEW { $$ = true; }
+ : opt_modifiers
+ {
+ int val = (int) $1;
+
+ val = Modifiers.Check (Modifiers.NEW, val, 0, lexer.Location);
+ $$ = (bool) (val != 0);
+ }
;
interface_method_declaration
(gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
lexer.Location);
}
+ | opt_attributes
+ opt_new
+ type error {
+ CheckIdentifierToken (yyToken);
+ $$ = null;
+ }
;
interface_accesors
$$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
lexer.Location);
}
+ | opt_attributes opt_new EVENT type error {
+ CheckIdentifierToken (yyToken);
+ $$ = null;
+ }
+ | opt_attributes opt_new EVENT type IDENTIFIER ASSIGN {
+ Report.Error (68, lexer.Location, "Event declarations on interfaces can not be initialized.");
+ $$ = null;
+ }
+ | opt_attributes opt_new EVENT type IDENTIFIER OPEN_BRACE event_accessor_declarations CLOSE_BRACE {
+ Report.Error (69, lexer.Location, "Event accessors not valid on interfaces");
+ $$ = null;
+ }
;
interface_indexer_declaration
opt_constructor_initializer
{
Location l = (Location) oob_stack.Pop ();
- $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $6, l);
+ $$ = new Constructor (current_container, (string) $1, (Parameters) $3,
+ (ConstructorInitializer) $6, l);
}
;
{
$$ = new ConstructorThisInitializer ((ArrayList) $4, current_local_parameters, lexer.Location);
}
+ | COLON error {
+ Report.Error (1018, lexer.Location, "Keyword this or base expected");
+ $$ = null;
+ }
;
+opt_finalizer
+ : /* EMPTY */ { $$ = 0; }
+ | UNSAFE { $$ = Modifiers.UNSAFE; }
+ | EXTERN { $$ = Modifiers.EXTERN; }
+ ;
+
destructor_declaration
- : opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
+ : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
{
- if ((string) $3 != current_container.Basename){
+ if ((string) $4 != current_container.Basename){
Report.Error (574, lexer.Location, "Name of destructor must match name of class");
} else if (!(current_container is Class)){
Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
} else {
Location l = lexer.Location;
- int m;
+ int m = (int) $2;
if (!RootContext.StdLib && current_container.Name == "System.Object")
- m = Modifiers.PROTECTED | Modifiers.VIRTUAL;
+ m |= Modifiers.PROTECTED | Modifiers.VIRTUAL;
else
- m = Modifiers.PROTECTED | Modifiers.OVERRIDE;
-
- Method d = new Method (
- TypeManager.system_void_expr, m, "Finalize",
+ m |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
+
+ if ((m & Modifiers.UNSAFE) != 0){
+ if (!RootContext.Unsafe){
+ Report.Error (227, l,
+ "Unsafe code requires the --unsafe command " +
+ "line option to be specified");
+ }
+ }
+
+ Method d = new Destructor (
+ current_container, TypeManager.system_void_expr, m, "Finalize",
new Parameters (null, null, l), (Attributes) $1, l);
- d.Block = (Block) $6;
+ d.Block = (Block) $7;
CheckDef (current_container.AddMethod (d), d.Name, d.Location);
}
}
{
Location loc = (Location) oob_stack.Pop ();
- Pair pair = (Pair) $8;
- Accessor add_accessor = null;
- Accessor rem_accessor = null;
-
- if (pair.First != null)
- add_accessor = (Accessor) pair.First;
- if (pair.Second != null)
- rem_accessor = (Accessor) pair.Second;
-
- Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
- (Attributes) $1, loc);
-
- CheckDef (current_container.AddEvent (e), e.Name, loc);
- implicit_value_parameter_type = null;
+ if ($8 == null){
+ Report.Error (65, lexer.Location, "Event must have both add and remove accesors");
+ $$ = null;
+ } else {
+ Pair pair = (Pair) $8;
+ Accessor add_accessor = null;
+ Accessor rem_accessor = null;
+
+ if (pair.First != null)
+ add_accessor = (Accessor) pair.First;
+ if (pair.Second != null)
+ rem_accessor = (Accessor) pair.Second;
+
+ Event e = new Event ((Expression) $4, (string) $5, null, (int) $2, add_accessor, rem_accessor,
+ (Attributes) $1, loc);
+
+ CheckDef (current_container.AddEvent (e), e.Name, loc);
+ implicit_value_parameter_type = null;
+ }
}
;
{
$$ = new Pair ($2, $1);
}
+ | add_accessor_declaration { $$ = null; }
+ | remove_accessor_declaration { $$ = null; }
;
add_accessor_declaration
$$ = new Accessor ((Block) $4, (Attributes) $1);
lexer.EventParsing = true;
}
+ | opt_attributes ADD error {
+ Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+ $$ = null;
+ }
;
remove_accessor_declaration
$$ = new Accessor ((Block) $4, (Attributes) $1);
lexer.EventParsing = true;
}
+ | opt_attributes REMOVE error {
+ Report.Error (73, lexer.Location, "Add or remove accessor must have a body");
+ $$ = null;
+ }
;
indexer_declaration
Accessor get_block = (Accessor) pair.First;
Accessor set_block = (Accessor) pair.Second;
- indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
- get_block, set_block, (Attributes) $1, loc);
+ indexer = new Indexer (current_container, decl.type, decl.interface_type, (int) $2,
+ decl.param_list, get_block, set_block, (Attributes) $1, loc);
// Note that there is no equivalent of CheckDef for this case
// We shall handle this in semantic analysis
if (pars.FixedParameters == null && pars.ArrayParameter == null){
Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
}
- $$ = new IndexerDeclaration ((Expression) $1, (string) $2, pars);
+ $$ = new IndexerDeclaration ((Expression) $1, (string) ($2).ToString (), pars);
}
;
Location enum_location = lexer.Location;
string full_name = MakeName ((string) $4);
- Enum e = new Enum (current_container, (Expression) $5, (int) $2, full_name,
- (Attributes) $1, enum_location);
+ Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
+ full_name, (Attributes) $1, enum_location);
foreach (VariableDeclaration ev in (ArrayList) $6) {
Location loc = (Location) ev.Location;
ev.identifier, loc);
}
- e.Namespace = current_namespace;
-
CheckDef (current_container.AddEnum (e), full_name, enum_location);
RootContext.Tree.RecordDecl (full_name, e);
;
opt_enum_member_declarations
- : /* empty */ { $$ = new ArrayList (); }
+ : /* empty */ { $$ = new ArrayList (4); }
| enum_member_declarations opt_comma { $$ = $1; }
;
enum_member_declarations
: enum_member_declaration
{
- ArrayList l = new ArrayList ();
+ ArrayList l = new ArrayList (4);
l.Add ($1);
$$ = l;
SEMICOLON
{
Location l = lexer.Location;
- Delegate del = new Delegate (current_container, (Expression) $4, (int) $2,
- MakeName ((string) $5), (Parameters) $7,
+ Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
+ (int) $2, MakeName ((string) $5), (Parameters) $7,
(Attributes) $1, l);
- del.Namespace = current_namespace;
CheckDef (current_container.AddDelegate (del), del.Name, l);
}
| opt_attributes
{
Location l = lexer.Location;
Delegate del = new Delegate (
- current_container,
+ current_namespace, current_container,
TypeManager.system_void_expr, (int) $2, MakeName ((string) $5),
(Parameters) $7, (Attributes) $1, l);
- del.Namespace = current_namespace;
CheckDef (current_container.AddDelegate (del), del.Name, l);
}
;
: qualified_identifier
;
+type_name_expression
+ : IDENTIFIER { $$ = new SimpleName ((string) $1, lexer.Location);}
+ | type_name_expression DOT IDENTIFIER {
+ $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+ }
+ ;
+
/*
* Before you think of adding a return_type, notice that we have been
* using two rules in the places where it matters (one rule using type
* gets rid of a shift/reduce couple
*/
type
- : type_name { /* class_type */
+ : type_name_expression { /* class_type */
/*
This does interfaces, delegates, struct_types, class_types,
parent classes, and more! 4.2
*/
- $$ = DecomposeQI ((string) $1, lexer.Location);
}
| builtin_types
| array_type
type_list
: type
{
- ArrayList types = new ArrayList ();
+ ArrayList types = new ArrayList (4);
types.Add ($1);
$$ = types;
// 7.5.1: Literals
}
- | qualified_identifier
- {
- string name = (string) $1;
-
- $$ = null;
- $$ = DecomposeQI (name, lexer.Location);
- }
+ | IDENTIFIER { $$ = new SimpleName ((string) $1, lexer.Location); }
| parenthesized_expression
| member_access
| invocation_expression
| checked_expression
| unchecked_expression
| pointer_member_access
+ | anonymous_method_expression
;
literal
: LITERAL_INTEGER {
object v = lexer.Value;
- if (v is int)
- $$ = new IntLiteral ((Int32) v);
- else if (v is uint)
+ if (v is int){
+ int i = (int) v;
+
+ if (i == 0)
+ $$ = IntLiteral.Zero;
+ else if (i == 1)
+ $$ = IntLiteral.One;
+ else
+ $$ = new IntLiteral (i);
+ } else if (v is uint)
$$ = new UIntLiteral ((UInt32) v);
else if (v is long)
$$ = new LongLiteral ((Int64) v);
| FALSE { $$ = new BoolLiteral (false); }
;
-parenthesized_expression
+parenthesized_expression_0
: OPEN_PARENS expression CLOSE_PARENS
- { $$ = $2; }
+ {
+ $$ = $2;
+ lexer.Deambiguate_CloseParens ();
+ // After this, the next token returned is one of
+ // CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
+ // or CLOSE_PARENS_MINUS.
+ }
;
+parenthesized_expression
+ : parenthesized_expression_0 CLOSE_PARENS_NO_CAST
+ {
+ $$ = $1;
+ }
+ | parenthesized_expression_0 CLOSE_PARENS_MINUS
+ {
+ // If a parenthesized expression is followed by a minus, we need to wrap
+ // the expression inside a ParenthesizedExpression for the CS0075 check
+ // in Binary.DoResolve().
+ $$ = new ParenthesizedExpression ((Expression) $1, lexer.Location);
+ }
+ ;;
+
member_access
: primary_expression DOT IDENTIFIER
{
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
}
- ;
+ | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
+ {
+ $$ = new Invocation ((Expression) $1, new ArrayList (), lexer.Location);
+ }
+ | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS primary_expression
+ {
+ $$ = new InvocationOrCast ((Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
opt_argument_list
: /* empty */ { $$ = null; }
argument_list
: argument
{
- ArrayList list = new ArrayList ();
+ ArrayList list = new ArrayList (4);
list.Add ($1);
$$ = list;
}
list.Add ($3);
$$ = list;
}
+ | argument_list error {
+ CheckToken (1026, yyToken, ", or ) expected");
+ }
;
argument
// Blah i;
Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
+ if (expr is ComposedCast){
+ $$ = new ComposedCast (expr, (string) $2, lexer.Location);
+ } else if (!(expr is SimpleName || expr is MemberAccess)){
Error_ExpectingTypeName (lexer.Location, expr);
$$ = TypeManager.system_object_expr;
} else {
// So we extract the string corresponding to the SimpleName
// or MemberAccess
//
- $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
+ $$ = new ComposedCast (expr, (string) $2, lexer.Location);
}
}
;
expression_list
: expression
{
- ArrayList list = new ArrayList ();
+ ArrayList list = new ArrayList (4);
list.Add ($1);
$$ = list;
}
{
$$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
}
+ | BASE error {
+ Report.Error (175, "Use of keyword `base' is not valid in this context");
+ $$ = null;
+ }
;
post_increment_expression
array_initializer
: OPEN_BRACE CLOSE_BRACE
{
- ArrayList list = new ArrayList ();
+ ArrayList list = new ArrayList (4);
$$ = list;
}
| OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
variable_initializer_list
: variable_initializer
{
- ArrayList list = new ArrayList ();
+ ArrayList list = new ArrayList (4);
list.Add ($1);
$$ = list;
}
;
typeof_expression
- : TYPEOF OPEN_PARENS type CLOSE_PARENS
+ : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
+ {
+ $$ = new TypeOfVoid (lexer.Location);
+ }
+ | TYPEOF OPEN_PARENS type CLOSE_PARENS
{
$$ = new TypeOf ((Expression) $3, lexer.Location);
}
deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lexer.Location);
$$ = new MemberAccess (deref, (string) $3, lexer.Location);
}
+ ;
+
+anonymous_method_expression
+ : DELEGATE opt_anonymous_method_signature {
+ oob_stack.Push (current_local_parameters);
+ current_local_parameters = (Parameters)$2;
+ create_toplevel_block = true;
+ } block {
+ create_toplevel_block = false;
+ if (!RootContext.V2){
+ Report.Error (-213, lexer.Location, "Anonymous methods are only supported in V2");
+ $$ = null;
+ } else
+ $$ = new AnonymousMethod ((Parameters) $2, (Block) $4, lexer.Location);
+ current_local_parameters = (Parameters) oob_stack.Pop ();
+ }
+ ;
+
+opt_anonymous_method_signature
+ : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
+ | anonymous_method_signature
+ ;
+
+anonymous_method_signature
+ : OPEN_PARENS opt_anonymous_method_parameter_list CLOSE_PARENS
+ {
+ if ($2 == null)
+ $$ = Parameters.EmptyReadOnlyParameters;
+ else {
+ ArrayList par_list = (ArrayList) $2;
+ Parameter [] pars = new Parameter [par_list.Count];
+ par_list.CopyTo (pars);
+ $$ = new Parameters (pars, null, lexer.Location);
+ }
+ }
+ ;
+
+opt_anonymous_method_parameter_list
+ : /* empty */ { $$ = null; }
+ | anonymous_method_parameter_list { $$ = $1; }
+ ;
+
+anonymous_method_parameter_list
+ : anonymous_method_parameter
+ {
+ ArrayList a = new ArrayList (4);
+ a.Add ($1);
+ $$ = a;
+ }
+ | anonymous_method_parameter_list COMMA anonymous_method_parameter
+ {
+ ArrayList a = (ArrayList) $1;
+ a.Add ($3);
+ $$ = a;
+ }
+ ;
+
+anonymous_method_parameter
+ : opt_parameter_modifier type IDENTIFIER {
+ $$ = new Parameter ((Expression) $2, (string) $2, (Parameter.Modifier) $1, null);
+ }
+ ;
unary_expression
: primary_expression
| cast_expression
;
-cast_expression
- : OPEN_PARENS expression CLOSE_PARENS unary_expression
+cast_list
+ : parenthesized_expression_0 CLOSE_PARENS_CAST unary_expression
{
- $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
+ $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
}
- | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
+ | parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS cast_expression
+ {
+ $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+ }
+ ;
+
+cast_expression
+ : cast_list
+ | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
{
- $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
+ $$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
}
;
name = MakeName ((string) $4);
- new_class = new Class (current_container, name, (int) $2,
+ new_class = new Class (current_namespace, current_container, name, (int) $2,
(Attributes) $1, lexer.Location);
current_container = new_class;
- current_container.Namespace = current_namespace;
RootContext.Tree.RecordDecl (name, new_class);
}
opt_class_base
block
: OPEN_BRACE
{
- current_block = new Block (current_block, current_local_parameters,
- lexer.Location, Location.Null);
+ if (current_block == null || create_toplevel_block){
+ current_block = new ToplevelBlock (current_local_parameters, lexer.Location);
+ } else {
+ current_block = new Block (current_block, current_local_parameters,
+ lexer.Location, Location.Null);
+ }
}
opt_statement_list CLOSE_BRACE
{
}
| embedded_statement
{
- Statement s = (Statement) $1;
-
-
current_block.AddStatement ((Statement) $1);
}
| labeled_statement
empty_statement
: SEMICOLON
{
- $$ = new EmptyStatement ();
+ $$ = EmptyStatement.Value;
}
;
if ($1 != null){
DictionaryEntry de = (DictionaryEntry) $1;
- $$ = declare_local_constant ((Expression) de.Key, (VariableDeclaration) de.Value);
+ $$ = declare_local_constants ((Expression) de.Key, (ArrayList) de.Value);
}
}
;
// Blah i;
Expression expr = (Expression) $1;
- if (!(expr is SimpleName || expr is MemberAccess)) {
+ if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
Error_ExpectingTypeName (lexer.Location, expr);
$$ = null;
} else {
// So we extract the string corresponding to the SimpleName
// or MemberAccess
//
+
if ((string) $2 == "")
$$ = $1;
else
Expression expr = (Expression) $1;
Location l = lexer.Location;
- if (!(expr is SimpleName || expr is MemberAccess)) {
+ if (!(expr is SimpleName || expr is MemberAccess || expr is ComposedCast)) {
Error_ExpectingTypeName (l, expr);
$$ = null;
;
local_constant_declaration
- : CONST local_variable_type constant_declarator
+ : CONST local_variable_type constant_declarators
{
if ($2 != null)
$$ = new DictionaryEntry ($2, $3);
| pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
| error {
Report.Error (1002, lexer.Location, "Expecting `;'");
+ $$ = null;
}
;
$$ = new If ((Expression) $1, (Statement) $3, l);
if (RootContext.WarningLevel >= 3){
- if ($3 is EmptyStatement)
+ if ($3 == EmptyStatement.Value)
Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
}
switch_sections
: switch_section
{
- ArrayList sections = new ArrayList ();
+ ArrayList sections = new ArrayList (4);
sections.Add ($1);
$$ = sections;
switch_section
: switch_labels
{
- current_block = new Block (current_block, lexer.Location, lexer.Location);
+ current_block = current_block.CreateSwitchBlock (lexer.Location);
}
statement_list
{
switch_labels
: switch_label
{
- ArrayList labels = new ArrayList ();
+ ArrayList labels = new ArrayList (4);
labels.Add ($1);
$$ = labels;
$$ = new While ((Expression) $4, (Statement) $6, l);
if (RootContext.WarningLevel >= 3){
- if ($6 is EmptyStatement)
+ if ($6 == EmptyStatement.Value)
Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
}
}
foreach (VariableDeclaration decl in var_declarators){
- VariableInfo vi;
+ LocalInfo vi;
vi = current_block.AddVariable (
type, decl.identifier, current_local_parameters, decl.Location);
For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
if (RootContext.WarningLevel >= 3){
- if ($10 is EmptyStatement)
+ if ($10 == EmptyStatement.Value)
Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
}
;
opt_for_initializer
- : /* empty */ { $$ = new EmptyStatement (); }
+ : /* empty */ { $$ = EmptyStatement.Value; }
| for_initializer
;
;
opt_for_iterator
- : /* empty */ { $$ = new EmptyStatement (); }
+ : /* empty */ { $$ = EmptyStatement.Value; }
| for_iterator
;
: statement_expression
{
// CHANGE: was `null'
- Block b = new Block (current_block, true);
+ Block b = new Block (current_block, Block.Flags.Implicit);
b.AddStatement ((Statement) $1);
$$ = b;
{
oob_stack.Push (current_block);
- Block foreach_block = new Block (current_block, true);
+ Block foreach_block = new Block (current_block, Block.Flags.Implicit);
LocalVariableReference v = null;
Location l = lexer.Location;
- VariableInfo vi;
+ LocalInfo vi;
vi = foreach_block.AddVariable ((Expression) $3, (string) $4, current_local_parameters, l);
if (vi != null) {
| goto_statement
| return_statement
| throw_statement
+ | yield_statement
;
break_statement
}
;
+yield_statement
+ : YIELD RETURN expression SEMICOLON
+ {
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new Yield ((Expression) $3, lexer.Location);
+ }
+ }
+ | YIELD expression SEMICOLON
+ {
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new Yield ((Expression) $2, lexer.Location);
+ }
+ }
+ | YIELD BREAK SEMICOLON
+ {
+ if (iterator_container == null){
+ Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ $$ = null;
+ } else {
+ iterator_container.SetYields ();
+ $$ = new YieldBreak (lexer.Location);
+ }
+ }
+ ;
+
opt_expression
: /* empty */
| expression
: TRY block catch_clauses
{
Catch g = null;
- ArrayList s = new ArrayList ();
+ ArrayList s = new ArrayList (4);
foreach (Catch cc in (ArrayList) $3) {
if (cc.IsGeneral)
| TRY block opt_catch_clauses FINALLY block
{
Catch g = null;
- ArrayList s = new ArrayList ();
+ ArrayList s = new ArrayList (4);
ArrayList catch_list = (ArrayList) $3;
if (catch_list != null){
catch_clauses
: catch_clause
{
- ArrayList l = new ArrayList ();
+ ArrayList l = new ArrayList (4);
l.Add ($1);
$$ = l;
id = (string) cc.Value;
if (id != null){
- ArrayList one = new ArrayList ();
+ ArrayList one = new ArrayList (4);
Location loc = lexer.Location;
one.Add (new VariableDeclaration (id, null, loc));
type fixed_pointer_declarators
CLOSE_PARENS
{
- Block assign_block = new Block (current_block, true);
+ Block assign_block = new Block (current_block, Block.Flags.Implicit);
ArrayList list = (ArrayList) $4;
Expression type = (Expression) $3;
Location l = lexer.Location;
for (int i = 0; i < top; i++){
Pair p = (Pair) list [i];
- VariableInfo v;
+ LocalInfo v;
v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
if (v == null)
embedded_statement
{
Location l = (Location) oob_stack.Pop ();
- Block assign_block = (Block) oob_stack.Pop ();
-
- ArrayList list = (ArrayList) $4;
- int top = list.Count;
+ oob_stack.Pop ();
$$ = new Fixed ((Expression) $3, (ArrayList) $4, (Statement) $7, l);
}
fixed_pointer_declarators
: fixed_pointer_declarator {
- ArrayList declarators = new ArrayList ();
+ ArrayList declarators = new ArrayList (4);
declarators.Add ($1);
$$ = declarators;
}
Expression type = (Expression) de.Key;
ArrayList var_declarators = (ArrayList) de.Value;
- ArrayList vars = new ArrayList ();
+ ArrayList vars = new ArrayList (4);
foreach (VariableDeclaration decl in var_declarators){
- VariableInfo vi = current_block.AddVariable (
+ LocalInfo vi = current_block.AddVariable (
type, decl.identifier,
current_local_parameters, decl.Location);
if (vi == null)
// <summary>
// A class used to hold info about an indexer declarator
// </summary>
-
public class IndexerDeclaration {
public Expression type;
public string interface_type;
// <summary>
// A class used to hold info about an operator declarator
// </summary>
-
public class OperatorDeclaration {
public Operator.OpType optype;
public Expression ret_type, arg1type, arg2type;
}
+public class QualifiedIdentifier {
+ public string s;
+ public QualifiedIdentifier prev;
+
+ public QualifiedIdentifier (string s)
+ {
+ this.s = s;
+ prev = null;
+ }
+
+ public QualifiedIdentifier (QualifiedIdentifier prev, string s)
+ {
+ this.s = s;
+ this.prev = prev;
+ }
+
+ public override string ToString ()
+ {
+ if (prev == null)
+ return s;
+
+ // Common cases
+
+ if (prev.prev == null)
+ return prev.s + "." + s;
+ if (prev.prev.prev == null)
+ return prev.prev.s + "." + prev.s + "." + s;
+
+ // Uncommon cases.
+ QualifiedIdentifier ptr = this.prev;
+ int count = 1;
+ while (ptr != null){
+ count++;
+ ptr = ptr.prev;
+ }
+ string [] ss = new string [count];
+ ptr = this;
+ for (int i = count; i-- > 0;){
+ ss [i] = ptr.s;
+ ptr = ptr.prev;
+ }
+ return String.Join (".", ss, 0, ss.Length);
+ }
+}
+
void Error_ExpectingTypeName (Location l, Expression expr)
{
if (expr is Invocation){
string
MakeName (string class_name)
{
- string ns = current_namespace.Name;
+ string ns = current_namespace.FullName;
string container_name = current_container.Name;
if (container_name == ""){
// in the current declaration space
// </summary>
void
-CheckDef (AdditionResult result, string name, Location l)
+CheckDef (DeclSpace.AdditionResult result, string name, Location l)
{
- if (result == AdditionResult.Success)
+ if (result == DeclSpace.AdditionResult.Success)
return;
switch (result){
- case AdditionResult.NameExists:
+ case DeclSpace.AdditionResult.NameExists:
Report.Error (102, l, "The container `" + current_container.Name +
"' already contains a definition for `"+
name + "'");
// This is handled only for static Constructors, because
// in reality we handle these by the semantic analysis later
//
- case AdditionResult.MethodExists:
+ case DeclSpace.AdditionResult.MethodExists:
Report.Error (
111, l, "Class `"+current_container.Name+
"' already defines a member called '" +
name + "' with the same parameter types (more than one default constructor)");
break;
- case AdditionResult.EnclosingClash:
+ case DeclSpace.AdditionResult.EnclosingClash:
Report.Error (542, l, "Member names cannot be the same as their enclosing type");
break;
- case AdditionResult.NotAConstructor:
+ case DeclSpace.AdditionResult.NotAConstructor:
Report.Error (1520, l, "Class, struct, or interface method must have a return type");
break;
+
+ case DeclSpace.AdditionResult.Error:
+ // Error has already been reported.
+ break;
}
}
{
if (result)
return;
- CheckDef (AdditionResult.NameExists, name, l);
+ CheckDef (DeclSpace.AdditionResult.NameExists, name, l);
}
-Expression DecomposeQI (string name, Location loc)
+Expression DecomposeQI (QualifiedIdentifier qi, Location loc)
{
Expression o;
- if (name.IndexOf ('.') == -1){
- return new SimpleName (name, loc);
- } else {
- int pos = name.LastIndexOf (".");
- string left = name.Substring (0, pos);
- string right = name.Substring (pos + 1);
-
- o = DecomposeQI (left, loc);
-
- return new MemberAccess (o, right, loc);
+ if (qi.prev == null)
+ return new SimpleName (qi.s, loc);
+ else {
+ o = DecomposeQI (qi.prev, loc);
+ return new MemberAccess (o, qi.s, loc);
}
}
// This is necessary because local_variable_type admits primary_expression
// as the type of the variable. So we do some extra checking
// </summary>
+#if false
string GetQualifiedIdentifier (Expression expr)
{
if (expr is SimpleName)
throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
}
+#endif
Block declare_local_variables (Expression type, ArrayList variable_declarators, Location loc)
{
// int j = 1; int k = j + 1;
//
if (current_block.Used) {
- implicit_block = new Block (current_block, true, loc, Location.Null);
+ implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
implicit_block.AddChildVariableNames (current_block);
} else
implicit_block = current_block;
if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
if (decl.expression_or_array_initializer != null){
if (inits == null)
- inits = new ArrayList ();
+ inits = new ArrayList (4);
inits.Add (decl);
}
}
return implicit_block;
}
-Block declare_local_constant (Expression type, VariableDeclaration decl)
+Block declare_local_constants (Expression type, ArrayList declarators)
{
Block implicit_block;
if (current_block.Used)
- implicit_block = new Block (current_block, true);
+ implicit_block = new Block (current_block, Block.Flags.Implicit);
else
implicit_block = current_block;
- if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
- current_local_parameters, decl.Location))){
+ foreach (VariableDeclaration decl in declarators){
+ implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+ current_local_parameters, decl.Location);
}
return implicit_block;
}
}
-public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines)
+public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
{
- current_namespace = new Namespace (null, file, "");
+ current_namespace = new NamespaceEntry (null, file, null, Location.Null);
this.name = file.Name;
this.file = file;
current_container = RootContext.Tree.Types;
- current_container.Namespace = current_namespace;
+ current_container.NamespaceEntry = current_namespace;
oob_stack = new Stack ();
switch_stack = new Stack ();
// Please do not remove this, it is used during debugging
// of the grammar
//
- Report.Error (-25, lexer.Location, ": Parsing error ");
Console.WriteLine (e);
+ Report.Error (-25, lexer.Location, "Parsing error");
+ if (Driver.parser_verbose)
+ Console.WriteLine (e);
}
}
+void CheckToken (int error, int yyToken, string msg)
+{
+ if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){
+ Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()));
+ return;
+ }
+ Report.Error (error, lexer.Location, msg);
+}
+
+void CheckIdentifierToken (int yyToken)
+{
+ CheckToken (1041, yyToken, "Identifier expected");
+}
+
/* end end end */
}