IIteratorContainer iterator_container;
- // <summary>
- // Current block is used to add statements as we find
- // them.
- // </summary>
-
+ /// <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;
%}
: 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, lexer.Location);
+ 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
| 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
}
opt_attribute_arguments
{
- $$ = new Attribute ((string) $1, (ArrayList) $3, (Location) $2);
+ $$ = new Attribute ((string) ($1).ToString (), (ArrayList) $3, (Location) $2);
}
;
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
;
member_name
- : qualified_identifier
+ : qualified_identifier { $$ = ($1).ToString (); }
;
property_declaration
{
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
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
}
}
- Method d = new Method (
+ Method d = new Destructor (
current_container, TypeManager.system_void_expr, m, "Finalize",
new Parameters (null, null, l), (Attributes) $1, l);
{
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
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);
}
;
: 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
// 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
: 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;
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;
}
;
$$ = 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");
}
$$ = 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");
}
}
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
;
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);
}
// <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){
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);
}
}