%{
//
+// OPTIMIZATION:
+// This loop is pointless:
+// while (current_block != prev_block)
+// current_block = current_block.Parent;
+//
// cs-parser.jay: The Parser for the C# compiler
//
// Author: Miguel de Icaza (miguel@gnu.org)
+// Ravi Pratap (ravi@ximian.com)
//
// Licensed under the terms of the GNU GPL
//
// </summmary>
bool parsing_indexer;
- // <summary>
- // Used to record all types defined
- // </summary>
- Tree tree;
-
//
// An out-of-band stack.
//
Stack oob_stack;
-
- RootContext rc;
-
%}
%token EOF
%token ABSTRACT
%token AS
%token ADD
+%token ASSEMBLY
%token BASE
%token BOOL
%token BREAK
%token SEALED
%token SHORT
%token SIZEOF
+%token STACKALLOC
%token STATIC
%token STRING
%token STRUCT
%token USING
%token VIRTUAL
%token VOID
+%token VOLATILE
%token WHILE
/* C# keywords which are not really keywords */
%nonassoc HIGHPREC
%start compilation_unit
-/*%start namespace_declaration */
%%
compilation_unit
- : opt_using_directives opt_namespace_member_declarations EOF
- {
- // Check that using comes only before namespace elements
- }
+ : outer_declarations opt_EOF
+ | outer_declarations attribute_sections opt_EOF
+ | attribute_sections opt_EOF
+ ;
+
+opt_EOF
+ : /* empty */
+ | EOF
;
+outer_declarations
+ : outer_declaration
+ | outer_declarations outer_declaration
+ ;
+
+outer_declaration
+ : using_directive
+ | namespace_member_declaration
+ ;
+
using_directives
: using_directive
| using_directives using_directive
: USING IDENTIFIER ASSIGN
namespace_or_type_name SEMICOLON
{
- current_namespace.UsingAlias ((string) $2, (string) $4);
+ current_namespace.UsingAlias ((string) $2, (string) $4, lexer.Location);
}
;
}
;
-// namespace_declarations
-// : namespace_declaration
-// | namespace_declarations namespace_declaration
-
+//
+// Strictly speaking, namespaces don't have attributes but
+// we parse global attributes along with namespace declarations and then
+// detach them
+//
namespace_declaration
- : NAMESPACE qualified_identifier
- {
- current_namespace = tree.RecordNamespace (current_namespace, (string) $2);
- }
+ : opt_attributes NAMESPACE qualified_identifier
+ {
+ Attributes attrs = (Attributes) $1;
+
+ if (attrs != null) {
+ foreach (AttributeSection asec in attrs.AttributeSections)
+ if (asec.Target == "assembly")
+ RootContext.AddGlobalAttribute (asec, lexer.Location);
+ }
+
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $3);
+ }
namespace_body opt_semicolon
{
current_namespace = current_namespace.Parent;
namespace_member_declaration
: type_declaration
{
- int mod_flags = 0;
string name = "";
+ int mod_flags;
if ($1 is Class){
Class c = (Class) $1;
} else
break;
- //
- // We remove this error until we can
- //if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
- // error (1527, "Namespace elements cant be explicitly " +
- // "declared private or protected in `" + name + "'");
- //}
+ if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+ Report.Error (
+ 1527, lexer.Location,
+ "Namespace elements cant be explicitly " +
+ "declared private or protected in `" + name + "'");
+ }
}
| namespace_declaration
;
| struct_declaration
| interface_declaration
| enum_declaration
- | delegate_declaration
+ | delegate_declaration
+//
+// Enable this when we have handled all errors, because this acts as a generic fallback
+//
+// | error {
+// Report.Error (1518, lexer.Location, "Expected class, struct, interface, enum or delegate");
+// }
;
//
// Attributes 17.2
//
+
opt_attributes
- : /* empty */ { $$ = null; }
- | attribute_section opt_attributes
+ : /* empty */
+ | attribute_sections { $$ = $1; }
+ ;
+
+attribute_sections
+ : attribute_section
+ {
+ AttributeSection sect = (AttributeSection) $1;
+
+ if (sect.Target == "assembly")
+ RootContext.AddGlobalAttribute (sect, lexer.Location);
+
+ $$ = new Attributes ((AttributeSection) $1, lexer.Location);
+ }
+ | attribute_sections attribute_section
{
- Attributes attrs;
-
- if ($2 != null) {
- attrs = (Attributes) $2;
- attrs.AddAttribute ((AttributeSection) $1);
- } else
- attrs = new Attributes ((AttributeSection) $1);
+ Attributes attrs = null;
+ AttributeSection sect = (AttributeSection) $2;
+
+ if (sect.Target == "assembly")
+ RootContext.AddGlobalAttribute (sect, lexer.Location);
+
+ if ($1 != null) {
+ attrs = (Attributes) $1;
+ attrs.AddAttribute (sect);
+ }
$$ = attrs;
}
attribute_arguments
- : positional_argument_list
+ : opt_positional_argument_list
{
- ArrayList args = new ArrayList ();
- args.Add ($1);
+ if ($1 == null)
+ $$ = null;
+ else {
+ ArrayList args = new ArrayList ();
+ args.Add ($1);
- $$ = args;
+ $$ = args;
+ }
}
| positional_argument_list COMMA named_argument_list
{
;
+opt_positional_argument_list
+ : /* empty */ { $$ = null; }
+ | positional_argument_list
+ ;
+
positional_argument_list
: expression
{
Struct new_struct;
string full_struct_name = MakeName ((string) $4);
- new_struct = new Struct (rc, current_container, full_struct_name, (int) $2,
+ new_struct = new Struct (current_container, full_struct_name, (int) $2,
(Attributes) $1, lexer.Location);
current_container = new_struct;
current_container.Namespace = current_namespace;
- tree.RecordStruct (full_struct_name, new_struct);
+ RootContext.Tree.RecordDecl (full_struct_name, new_struct);
}
opt_struct_interfaces
struct_body
Struct new_struct = (Struct) current_container;
current_container = current_container.Parent;
- CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
+ CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
$$ = new_struct;
}
;
SEMICOLON
{
foreach (VariableDeclaration constant in (ArrayList) $5){
- Constant c = new Constant (
+ Location l = constant.Location;
+
+ Const c = new Const (
(string) $4, (string) constant.identifier,
- (Expression) constant.expression_or_array_initializer, (int) $2, (Attributes) $1,
- constant.Location);
+ (Expression) constant.expression_or_array_initializer, (int) $2,
+ (Attributes) $1, l);
- CheckDef (current_container.AddConstant (c), c.Name);
+ CheckDef (current_container.AddConstant (c), c.Name, l);
}
}
;
int mod = (int) $2;
foreach (VariableDeclaration var in (ArrayList) $4){
+ Location l = var.Location;
+
Field field = new Field (type, mod, var.identifier,
- var.expression_or_array_initializer, (Attributes) $1, var.Location);
+ var.expression_or_array_initializer,
+ (Attributes) $1, l);
- CheckDef (current_container.AddField (field), field.Name);
+ CheckDef (current_container.AddField (field), field.Name, l);
}
}
;
$$ = $1;
}
| array_initializer
- {
+ {
$$ = $1;
- }
+ }
+ | STACKALLOC type OPEN_BRACKET expression CLOSE_BRACKET
+ {
+ $$ = new StackAlloc ((string) $2, (Expression) $4, lexer.Location);
+ }
;
method_declaration
{
Method method = (Method) $1;
Block b = (Block) $2;
-
+ const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
if (b == null){
- if ((method.ModFlags & (Modifiers.EXTERN | Modifiers.ABSTRACT)) == 0){
+ if ((method.ModFlags & extern_abstract) == 0){
Report.Error (
- 501, lexer.Location, "`" +
- current_container.Name + "." + method.Name + "'" +
+ 501, lexer.Location, current_container.MakeName (method.Name) +
"must declare a body because it is not marked abstract or extern");
}
+ } else {
+ if ((method.ModFlags & Modifiers.EXTERN) != 0){
+ Report.Error (
+ 179, lexer.Location, current_container.MakeName (method.Name) +
+ " is declared extern, but has a body");
+ }
}
method.Block = (Block) $2;
- CheckDef (current_container.AddMethod (method), method.Name);
+ CheckDef (current_container.AddMethod (method), method.Name, method.Location);
current_local_parameters = null;
}
;
+opt_error_modifier
+ : /* empty */
+ | modifiers
+ {
+ int m = (int) $1;
+ int i = 1;
+
+ while (m != 0){
+ if ((i & m) != 0){
+ Report.Error (
+ 1585, lexer.Location, "Member modifier `" +
+ Modifiers.Name (i) + "' must precede member type and name");
+ }
+ m &= ~i;
+ i = i << 1;
+ }
+ }
+ ;
+
method_header
: opt_attributes
opt_modifiers
Parameter [] pars = new Parameter [pars_list.Count];
pars_list.CopyTo (pars);
- $$ = new Parameters (pars, null);
+ $$ = new Parameters (pars, null, lexer.Location);
}
| fixed_parameters COMMA parameter_array
{
Parameter [] pars = new Parameter [pars_list.Count];
pars_list.CopyTo (pars);
- $$ = new Parameters (pars, (Parameter) $3);
+ $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
}
| parameter_array
{
- $$ = new Parameters (null, (Parameter) $1);
+ $$ = new Parameters (null, (Parameter) $1, lexer.Location);
}
;
{
implicit_value_parameter_type = (string) $3;
- lexer.properties = true;
+ lexer.PropertyParsing = true;
$$ = lexer.Location;
}
accessor_declarations
{
- lexer.properties = false;
+ lexer.PropertyParsing = false;
}
CLOSE_BRACE
{
Property prop;
- DictionaryEntry pair = (DictionaryEntry) $7;
+ Pair pair = (Pair) $7;
Block get_block = null;
Block set_block = null;
- if (pair.Key != null)
- get_block = (Block) pair.Key;
- if (pair.Value != null)
- set_block = (Block) pair.Value;
+ if (pair.First != null)
+ get_block = (Block) pair.First;
+ if (pair.Second != null)
+ set_block = (Block) pair.Second;
+ Location loc = (Location) $6;
prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block,
- (Attributes) $1, (Location) $6);
+ (Attributes) $1, loc);
- CheckDef (current_container.AddProperty (prop), prop.Name);
+ CheckDef (current_container.AddProperty (prop), prop.Name, loc);
implicit_value_parameter_type = null;
}
;
accessor_declarations
: get_accessor_declaration opt_set_accessor_declaration
{
- $$ = new DictionaryEntry ($1, $2);
+ $$ = new Pair ($1, $2);
}
| set_accessor_declaration opt_get_accessor_declaration
{
- $$ = new DictionaryEntry ($2, $1);
+ $$ = new Pair ($2, $1);
}
;
current_local_parameters = null;
else
current_local_parameters = indexer_parameters;
-
-
+ lexer.PropertyParsing = false;
}
accessor_body
{
$$ = $4;
current_local_parameters = null;
+ lexer.PropertyParsing = true;
}
;
fp.CopyTo (args, 0);
args [count] = implicit_value_parameter;
}
- current_local_parameters = new Parameters (args, null);
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.PropertyParsing = false;
}
accessor_body
{
$$ = $4;
current_local_parameters = null;
+ lexer.PropertyParsing = true;
}
;
accessor_body
: block
- | SEMICOLON { $$ = new Block (null); }
+ | SEMICOLON { $$ = null; }
;
interface_declaration
Interface new_interface;
string full_interface_name = MakeName ((string) $4);
- new_interface = new Interface (rc, current_container, full_interface_name, (int) $2,
+ new_interface = new Interface (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;
- tree.RecordInterface (full_interface_name, new_interface);
+ new_interface.Namespace = current_namespace;
+ RootContext.Tree.RecordDecl (full_interface_name, new_interface);
}
opt_interface_base
- interface_body
+ interface_body opt_semicolon
{
Interface new_interface = (Interface) current_interface;
new_interface.Bases = (ArrayList) $6;
current_interface = null;
- CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
+ CheckDef (current_container.AddInterface (new_interface),
+ new_interface.Name, new_interface.Location);
}
;
{
InterfaceMethod m = (InterfaceMethod) $1;
- CheckDef (current_interface.AddMethod (m), m.Name);
+ CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
}
| interface_property_declaration
{
InterfaceProperty p = (InterfaceProperty) $1;
- CheckDef (current_interface.AddProperty (p), p.Name);
+ CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
}
| interface_event_declaration
{
InterfaceEvent e = (InterfaceEvent) $1;
- CheckDef (current_interface.AddEvent (e), e.Name);
+ CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
}
| interface_indexer_declaration
{
InterfaceIndexer i = (InterfaceIndexer) $1;
- CheckDef (current_interface.AddIndexer (i), "indexer");
+ CheckDef (current_interface.AddIndexer (i), "indexer", i.Location);
}
;
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
+ $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2,
+ (Parameters) $6, (Attributes) $1, lexer.Location);
}
| opt_attributes opt_new VOID IDENTIFIER
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6, (Attributes) $1);
+ $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6,
+ (Attributes) $1, lexer.Location);
}
;
opt_new
type IDENTIFIER
OPEN_BRACE
- { lexer.properties = true; }
+ { lexer.PropertyParsing = true; }
interface_accesors
- { lexer.properties = false; }
+ { lexer.PropertyParsing = false; }
CLOSE_BRACE
{
int gs = (int) $7;
$$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2,
- (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1);
+ (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
+ lexer.Location);
}
;
: opt_attributes opt_new type THIS
OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
OPEN_BRACE
- { lexer.properties = true; }
+ { lexer.PropertyParsing = true; }
interface_accesors
- { lexer.properties = false; }
+ { lexer.PropertyParsing = false; }
CLOSE_BRACE
{
int a_flags = (int) $10;
bool do_get = (a_flags & 1) == 1;
bool do_set = (a_flags & 2) == 2;
- $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set, (bool) $2, (Attributes) $1);
+ $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set,
+ (bool) $2, (Attributes) $1, lexer.Location);
}
;
operator_declaration
- : opt_attributes opt_modifiers operator_declarator block
+ : opt_attributes opt_modifiers operator_declarator operator_body
{
OperatorDeclaration decl = (OperatorDeclaration) $3;
}
;
+operator_body
+ : block
+ | SEMICOLON { $$ = null; }
+ ;
operator_declarator
: type OPERATOR overloadable_operator
OPEN_PARENS type IDENTIFIER CLOSE_PARENS
pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
- current_local_parameters = new Parameters (pars, null);
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
$$ = new OperatorDeclaration (op, (string) $1, (string) $5, (string) $6,
null, null, lexer.Location);
pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
pars [1] = new Parameter ((string) $8, (string) $9, Parameter.Modifier.NONE, null);
- current_local_parameters = new Parameters (pars, null);
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
$$ = new OperatorDeclaration ((Operator.OpType) $3, (string) $1, (string) $5, (string) $6,
(string) $8, (string) $9, lexer.Location);
pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
- current_local_parameters = new Parameters (pars, null);
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
$$ = new OperatorDeclaration (Operator.OpType.Implicit, (string) $3, (string) $5, (string) $6,
null, null, lexer.Location);
pars [0] = new Parameter ((string) $5, (string) $6, Parameter.Modifier.NONE, null);
- current_local_parameters = new Parameters (pars, null);
+ current_local_parameters = new Parameters (pars, null, lexer.Location);
$$ = new OperatorDeclaration (Operator.OpType.Explicit, (string) $3, (string) $5, (string) $6,
null, null, lexer.Location);
: opt_attributes
opt_modifiers
constructor_declarator
- block
+ constructor_body
{
Constructor c = (Constructor) $3;
c.Block = (Block) $4;
if ((c.ModFlags & Modifiers.STATIC) != 0){
if ((c.ModFlags & Modifiers.Accessibility) != 0) {
- Location l = lexer.Location;
- Report.Error (515, l, "Access modifiers are not allowed on static constructors");
+ Report.Error (
+ 515, c.Location,
+ "Access modifiers are not allowed on static constructors");
}
if (c.Initializer != null){
- Location l = lexer.Location;
- Report.Error (514, l, "Static constructors can not have an explicit this or base constructor invocations");
+ Report.Error (
+ 514, c.Location,
+ "Static constructors can not have an explicit this or base " +
+ "constructor invocations");
}
if (!c.Parameters.Empty){
- Location l = lexer.Location;
- Report.Error (103, l, "Static constructors should not have parameters");
+ Report.Error (
+ 132, c.Location, "Static constructors should not have parameters");
}
}
- CheckDef (current_container.AddConstructor (c), c.Name);
+ CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
current_local_parameters = null;
}
constructor_declarator
: IDENTIFIER
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
- opt_constructor_initializer
{
- Location l = lexer.Location;
+ oob_stack.Push (lexer.Location);
- $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $5, l);
-
current_local_parameters = (Parameters) $3;
}
+ opt_constructor_initializer
+ {
+ Location l = (Location) oob_stack.Pop ();
+ $$ = new Constructor ((string) $1, (Parameters) $3, (ConstructorInitializer) $6, l);
+ }
+ ;
+
+constructor_body
+ : block
+ | SEMICOLON { $$ = null; }
;
opt_constructor_initializer
destructor_declaration
: opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
{
- if ((string) $3 != current_container.Name){
+ if ((string) $3 != 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;
+
Method d = new Method (
- "System.Void", 0, "Finalize",
- new Parameters (null, null), (Attributes) $1, lexer.Location);
+ "System.Void",
+ Modifiers.PROTECTED | Modifiers.OVERRIDE,
+ "Finalize",
+ new Parameters (null, null, l), (Attributes) $1, l);
d.Block = (Block) $6;
- CheckDef (current_container.AddMethod (d), d.Name);
+ CheckDef (current_container.AddMethod (d), d.Name, d.Location);
}
}
;
{
foreach (VariableDeclaration var in (ArrayList) $5) {
- // FIXME : Is this right ?
Event e = new Event ((string) $4, var.identifier, var.expression_or_array_initializer,
(int) $2, null, null, (Attributes) $1, lexer.Location);
- CheckDef (current_container.AddEvent (e), e.Name);
+ CheckDef (current_container.AddEvent (e), e.Name, e.Location);
}
}
| opt_attributes
opt_modifiers
- EVENT type member_name
- OPEN_BRACE event_accessor_declarations CLOSE_BRACE
- {
- DictionaryEntry pair = (DictionaryEntry) $7;
+ EVENT type member_name
+ OPEN_BRACE
+ {
+ implicit_value_parameter_type = (string) $4;
+ lexer.EventParsing = true;
+ oob_stack.Push (lexer.Location);
+ }
+ event_accessor_declarations
+ {
+ lexer.EventParsing = false;
+ }
+ CLOSE_BRACE
+ {
+ Location loc = (Location) oob_stack.Pop ();
+
+ Pair pair = (Pair) $8;
Block add_block = null;
Block rem_block = null;
- if (pair.Key != null)
- add_block = (Block) pair.Key;
- if (pair.Value != null)
- rem_block = (Block) pair.Value;
+ if (pair.First != null)
+ add_block = (Block) pair.First;
+ if (pair.Second != null)
+ rem_block = (Block) pair.Second;
Event e = new Event ((string) $4, (string) $5, null, (int) $2, add_block, rem_block,
- (Attributes) $1, lexer.Location);
+ (Attributes) $1, loc);
- CheckDef (current_container.AddEvent (e), e.Name);
- }
+ CheckDef (current_container.AddEvent (e), e.Name, loc);
+ implicit_value_parameter_type = null;
+ }
;
event_accessor_declarations
: add_accessor_declaration remove_accessor_declaration
{
- $$ = new DictionaryEntry ($1, $2);
+ $$ = new Pair ($1, $2);
}
| remove_accessor_declaration add_accessor_declaration
{
- $$ = new DictionaryEntry ($2, $1);
+ $$ = new Pair ($2, $1);
}
;
add_accessor_declaration
- : opt_attributes ADD block
+ : opt_attributes ADD
+ {
+ Parameter [] args = new Parameter [1];
+ Parameter implicit_value_parameter = new Parameter (
+ implicit_value_parameter_type, "value",
+ Parameter.Modifier.NONE, null);
+
+ args [0] = implicit_value_parameter;
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.EventParsing = false;
+ }
+ block
{
- $$ = $3;
+ $$ = $4;
+ lexer.EventParsing = true;
}
;
remove_accessor_declaration
- : opt_attributes REMOVE block
- {
- $$ = $3;
- }
+ : opt_attributes REMOVE
+ {
+ Parameter [] args = new Parameter [1];
+ Parameter implicit_value_parameter = new Parameter (
+ implicit_value_parameter_type, "value",
+ Parameter.Modifier.NONE, null);
+
+ args [0] = implicit_value_parameter;
+
+ current_local_parameters = new Parameters (args, null, lexer.Location);
+ lexer.EventParsing = false;
+ }
+ block
+ {
+ $$ = $4;
+ lexer.EventParsing = true;
+ }
;
indexer_declaration
implicit_value_parameter_type = decl.type;
- lexer.properties = true;
+ lexer.PropertyParsing = true;
parsing_indexer = true;
indexer_parameters = decl.param_list;
}
accessor_declarations
{
- lexer.properties = false;
+ lexer.PropertyParsing = false;
parsing_indexer = false;
}
CLOSE_BRACE
Indexer indexer;
IndexerDeclaration decl = (IndexerDeclaration) $3;
- DictionaryEntry pair = (DictionaryEntry) $6;
+ Pair pair = (Pair) $6;
Block get_block = null;
Block set_block = null;
- if (pair.Key != null)
- get_block = (Block) pair.Key;
- if (pair.Value != null)
- set_block = (Block) pair.Value;
+ if (pair.First != null)
+ get_block = (Block) pair.First;
+ if (pair.Second != null)
+ set_block = (Block) pair.Second;
indexer = new Indexer (decl.type, decl.interface_type, (int) $2, decl.param_list,
get_block, set_block, (Attributes) $1, (Location) $5);
;
indexer_declarator
- : type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
+ : type THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
{
- $$ = new IndexerDeclaration ((string) $1, null, (Parameters) $4);
+ Parameters pars = (Parameters) $4;
+
+ if (pars.FixedParameters == null){
+ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
+ }
+
+ $$ = new IndexerDeclaration ((string) $1, null, pars);
}
- | type interface_type DOT THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
+ | type qualified_identifier DOT THIS OPEN_BRACKET opt_formal_parameter_list CLOSE_BRACKET
{
- $$ = new IndexerDeclaration ((string) $1, (string) $2, (Parameters) $6);
+ Parameters pars = (Parameters) $6;
+
+ if (pars.FixedParameters == null){
+ Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
+ }
+ $$ = new IndexerDeclaration ((string) $1, (string) $2, pars);
}
;
enum_declaration
: opt_attributes
opt_modifiers
- ENUM IDENTIFIER
+ ENUM IDENTIFIER
opt_enum_base
enum_body
opt_semicolon
{
- string name = (string) $4;
- Enum e = new Enum (rc, (string) $5, (int) $2, name, (Attributes) $1, lexer.Location);
+ Location enum_location = lexer.Location;
+
+ string full_name = MakeName ((string) $4);
+ Enum e = new Enum (
+ current_container, (string) $5, (int) $2, full_name,
+ (Attributes) $1, enum_location);
foreach (VariableDeclaration ev in (ArrayList) $6){
+ Location loc = (Location) ev.Location;
+
CheckDef (e.AddEnumMember (ev.identifier,
(Expression) ev.expression_or_array_initializer,
- (Location) ev.Location),
- ev.identifier);
+ loc),
+ ev.identifier, loc);
}
- CheckDef (current_container.AddEnum (e), name);
+ e.Namespace = current_namespace;
+
+ CheckDef (current_container.AddEnum (e), full_name, enum_location);
+ RootContext.Tree.RecordDecl (full_name, e);
+
}
;
opt_modifiers
DELEGATE type
IDENTIFIER OPEN_PARENS
- formal_parameter_list
+ opt_formal_parameter_list
CLOSE_PARENS
SEMICOLON
{
- Delegate del = new Delegate (rc, (string) $4, (int) $2,
+ Location l = lexer.Location;
+ Delegate del = new Delegate (current_container, (string) $4, (int) $2,
MakeName ((string) $5), (Parameters) $7,
- (Attributes) $1, lexer.Location);
+ (Attributes) $1, l);
- CheckDef (current_container.AddDelegate (del), del.Name);
+ del.Namespace = current_namespace;
+ CheckDef (current_container.AddDelegate (del), del.Name, l);
}
| opt_attributes
opt_modifiers
DELEGATE VOID
IDENTIFIER OPEN_PARENS
- formal_parameter_list
+ opt_formal_parameter_list
CLOSE_PARENS
SEMICOLON
{
- Delegate del = new Delegate (rc, "System.Void", (int) $2, (string) $5, (Parameters) $7,
- (Attributes) $1, lexer.Location);
+ Location l = lexer.Location;
+ Delegate del = new Delegate (
+ current_container,
+ "System.Void", (int) $2, MakeName ((string) $5), (Parameters) $7,
+ (Attributes) $1, l);
- CheckDef (current_container.AddDelegate (del), del.Name);
+ del.Namespace = current_namespace;
+ CheckDef (current_container.AddDelegate (del), del.Name, l);
}
;
}
| builtin_types
| array_type
+ | pointer_type
+ ;
+
+
+pointer_type
+ : type STAR
+ {
+ //
+ // Note that here only unmanaged types are allowed but we
+ // can't perform checks during this phase - we do it during
+ // semantic analysis.
+ //
+ $$ = (string) $1 + "*";
+ }
+ | VOID STAR
+ {
+ $$ = "System.Void*";
+ }
;
non_expression_type
{
$$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
+ | non_expression_type STAR
+ {
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+ }
| expression rank_specifiers
{
$$ = new ComposedCast ((Expression) $1, (string) $2, lexer.Location);
}
+ | expression STAR
+ {
+ $$ = new ComposedCast ((Expression) $1, "*", lexer.Location);
+ }
;
type_list
| LONG { $$ = "System.Int64"; }
| ULONG { $$ = "System.UInt64"; }
| CHAR { $$ = "System.Char"; }
+ | VOID { $$ = "System.Void"; }
;
interface_type
| sizeof_expression
| checked_expression
| unchecked_expression
+ | pointer_member_access
+ // TODO: pointer_element_access
+ // TODO: sizeof-expression
;
literal
}
| predefined_type DOT IDENTIFIER
{
- $$ = new SimpleName ((string) $1 + "." + (string) $3, lexer.Location);
+ $$ = new MemberAccess (new SimpleName ((string) $1, lexer.Location), (string) $3, lexer.Location);
}
;
Report.Error (1, l, "THIS IS CRAZY");
}
$$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
-
}
;
{
$$ = new ElementAccess ((Expression) $1, (ArrayList) $3, lexer.Location);
}
+ | primary_expression rank_specifiers
+ {
+ // 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 (!(expr is SimpleName || expr is MemberAccess)) {
+ Location l = lexer.Location;
+ Report.Error (-1, l, "Invalid Type definition");
+ $$ = "System.Object";
+ }
+
+ //
+ // So we extract the string corresponding to the SimpleName
+ // or MemberAccess
+ //
+ $$ = new SimpleName (GetQualifiedIdentifier (expr) + (string) $2, lexer.Location);
+ }
;
expression_list
}
| BASE OPEN_BRACKET expression_list CLOSE_BRACKET
{
- $$ = new BaseIndexerAccess ((ArrayList) $3);
+ $$ = new BaseIndexerAccess ((ArrayList) $3, lexer.Location);
}
;
{
$$ = new ArrayCreation ((string) $2, (string) $3, (ArrayList) $4, lexer.Location);
}
+ | NEW type error
+ {
+ Report.Error (1526, lexer.Location, "new expression requires () or [] after type");
+ }
;
opt_rank_specifier
typeof_expression
: TYPEOF OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((string) $3);
+ $$ = new TypeOf ((string) $3, lexer.Location);
}
;
sizeof_expression
: SIZEOF OPEN_PARENS type CLOSE_PARENS {
- $$ = new SizeOf ((string) $3);
+ $$ = new SizeOf ((string) $3, lexer.Location);
note ("Verify type is unmanaged");
note ("if (5.8) builtin, yield constant expression");
}
;
+pointer_member_access
+ : primary_expression OP_PTR IDENTIFIER
+ {
+ Expression deref;
+
+ deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lexer.Location);
+ $$ = new MemberAccess (deref, (string) $3, lexer.Location);
+ }
+
unary_expression
: primary_expression
| BANG prefixed_unary_expression
{
$$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
}
- | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
+ | OPEN_PARENS non_expression_type CLOSE_PARENS prefixed_unary_expression
{
$$ = new Cast ((Expression) $2, (Expression) $4, lexer.Location);
}
}
| relational_expression IS type
{
- $$ = new Is ((Expression) $1, (string) $3);
+ $$ = new Is ((Expression) $1, (string) $3, lexer.Location);
}
| relational_expression AS type
{
- $$ = new As ((Expression) $1, (string) $3);
+ $$ = new As ((Expression) $1, (string) $3, lexer.Location);
}
;
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Multiply,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Multiply,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_DIV_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Division,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Division,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_MOD_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Modulus,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Modulus,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_ADD_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Addition,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Addition,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_SUB_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.Subtraction,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.Subtraction,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.LeftShift,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.LeftShift,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.RightShift,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.RightShift,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_AND_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.BitwiseAnd,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.BitwiseAnd,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_OR_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.BitwiseOr,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.BitwiseOr,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
| prefixed_unary_expression OP_XOR_ASSIGN expression
{
Location l = lexer.Location;
- $$ = new Assign ((Expression) $1,
- new Binary (Binary.Operator.ExclusiveOr,
- (Expression) $1,
- (Expression) $3, l), l);
+ $$ = new CompoundAssign (
+ (Expression) $1,
+ new Binary (Binary.Operator.ExclusiveOr,
+ (Expression) $1,
+ (Expression) $3, l),
+ (Expression) $3, l);
}
;
CLASS IDENTIFIER
{
Class new_class;
- string full_class_name = MakeName ((string) $4);
+ string name;
- new_class = new Class (rc, current_container, full_class_name, (int) $2,
+ name = MakeName ((string) $4);
+
+ new_class = new Class (current_container, name, (int) $2,
(Attributes) $1, lexer.Location);
current_container = new_class;
current_container.Namespace = current_namespace;
- tree.RecordClass (full_class_name, new_class);
+ RootContext.Tree.RecordDecl (name, new_class);
}
opt_class_base
class_body
new_class.Bases = (ArrayList) $6;
current_container = current_container.Parent;
- CheckDef (current_container.AddClass (new_class), new_class.Name);
+ CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
$$ = new_class;
}
if ((m1 & m2) != 0) {
Location l = lexer.Location;
- Report.Error (1002, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
+ Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
}
$$ = (int) (m1 | m2);
}
| VIRTUAL { $$ = Modifiers.VIRTUAL; }
| OVERRIDE { $$ = Modifiers.OVERRIDE; }
| EXTERN { $$ = Modifiers.EXTERN; }
+ | VOLATILE { $$ = Modifiers.VOLATILE; }
+ | UNSAFE { $$ = Modifiers.UNSAFE; }
;
opt_class_base
block
: OPEN_BRACE
{
- current_block = new Block (current_block);
+ current_block = new Block (current_block, lexer.Location, Location.Null);
}
opt_statement_list CLOSE_BRACE
{
while (current_block.Implicit)
current_block = current_block.Parent;
$$ = current_block;
+ current_block.SetEndLocation (lexer.Location);
current_block = current_block.Parent;
}
;
current_block.AddStatement ((Statement) $1);
}
- | labeled_statement
- {
- current_block.AddStatement ((Statement) $1);
- }
+ | labeled_statement
;
embedded_statement
| unchecked_statement
| lock_statement
| using_statement
+ | unsafe_statement
+ | fixed_statement
;
empty_statement
;
labeled_statement
- : IDENTIFIER COLON statement
+ : IDENTIFIER COLON
{
- string lab = (String) $1;
- Block block;
+ LabeledStatement labeled = new LabeledStatement ((string) $1);
- block = new Block (current_block, lab);
- block.AddStatement ((Statement) $3);
- $$ = block;
-
- if (!current_block.AddLabel (lab, block)){
+ if (!current_block.AddLabel ((string) $1, labeled)){
Location l = lexer.Location;
- Report.Error (140, l, "The label '" + lab + "' is a duplicate");
- $$ = $3;
+ Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
}
+ current_block.AddStatement (labeled);
}
+ statement
;
declaration_statement
}
;
-// FIXME : How can the type of a local variable be void ? I don't quite see ;-)
-// | VOID
-// {
-// // FIXME: this is a string that represents the type
-// // Figure out something to make this work.
-// $$ = "void";
-// }
-// ;
+local_variable_pointer_type
+ : primary_expression STAR
+ {
+ Expression expr = (Expression) $1;
+ if (!(expr is SimpleName || expr is MemberAccess)) {
+ Location l = lexer.Location;
+ Report.Error (-1, l, "Invalid Type definition");
+ $$ = "System.Object";
+ }
+
+ $$ = GetQualifiedIdentifier (expr) + "*";
+ }
+ | builtin_types STAR
+ {
+ $$ = (string) $1 + "*";
+ }
+ | VOID STAR
+ {
+ $$ = "System.Void*";
+ }
+ | local_variable_pointer_type STAR
+ {
+ $$ = (string) $1 + "*";
+ }
+ ;
local_variable_declaration
: local_variable_type variable_declarators
{
$$ = new DictionaryEntry ($1, $2);
}
- ;
+ | local_variable_pointer_type opt_rank_specifier variable_declarators
+ {
+ $$ = new DictionaryEntry ((string) $1 + (string) $2, $3);
+ }
+ ;
local_constant_declaration
: CONST local_variable_type constant_declarator
// because statement_expression is used for example in for_statement
//
statement_expression
- : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
- | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1); }
+ : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | post_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | post_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | pre_increment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
+ | pre_decrement_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
| error {
Report.Error (1002, lexer.Location, "Expecting `;'");
}
;
if_statement
- : IF OPEN_PARENS boolean_expression CLOSE_PARENS
+ : if_statement_open if_statement_rest
+ {
+ $$ = $2;
+ }
+ ;
+
+if_statement_open
+ : IF OPEN_PARENS
+ {
+ oob_stack.Push (lexer.Location);
+ }
+ ;
+
+if_statement_rest
+ : boolean_expression CLOSE_PARENS
embedded_statement
{
- $$ = new If ((Expression) $3, (Statement) $5);
+ Location l = (Location) oob_stack.Pop ();
+
+ $$ = new If ((Expression) $1, (Statement) $3, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($3 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
+
}
- | IF OPEN_PARENS boolean_expression CLOSE_PARENS
+ | boolean_expression CLOSE_PARENS
embedded_statement ELSE embedded_statement
{
- $$ = new If ((Expression) $3, (Statement) $5, (Statement) $7);
+ Location l = (Location) oob_stack.Pop ();
+
+ $$ = new If ((Expression) $1, (Statement) $3, (Statement) $5, l);
}
;
;
opt_switch_sections
- : /* empty */ { $$ = new ArrayList (); }
+ : /* empty */
+ {
+ Report.Error (1522, lexer.Location, "Empty switch block");
+ }
| switch_sections
;
switch_label
: CASE constant_expression COLON { $$ = new SwitchLabel ((Expression) $2, lexer.Location); }
| DEFAULT COLON { $$ = new SwitchLabel (null, lexer.Location); }
+ | error {
+ Report.Error (
+ 1523, lexer.Location,
+ "The keyword case or default must precede code in switch block");
+ }
;
iteration_statement
;
while_statement
- : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement
+ : WHILE OPEN_PARENS
{
- $$ = new While ((Expression) $3, (Statement) $5);
+ oob_stack.Push (lexer.Location);
+ }
+ boolean_expression CLOSE_PARENS embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ $$ = new While ((Expression) $4, (Statement) $6, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($6 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
}
;
: DO embedded_statement
WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON
{
- $$ = new Do ((Statement) $2, (Expression) $5);
+ $$ = new Do ((Statement) $2, (Expression) $5, lexer.Location);
}
;
ArrayList var_declarators = (ArrayList) de.Value;
foreach (VariableDeclaration decl in var_declarators){
- if (!current_block.AddVariable (type, decl.identifier, decl.Location)){
- Report.Error (128, decl.Location,
- "A local variable `" + decl.identifier + "' is already" +
- "defined in this scope");
- }
- }
- Location l = lexer.Location;
- foreach (VariableDeclaration decl in var_declarators){
+ VariableInfo vi;
- Expression expr;
- if (decl.expression_or_array_initializer is Expression){
- expr = (Expression) decl.expression_or_array_initializer;
-
+ vi = current_block.AddVariable (
+ type, decl.identifier, current_local_parameters, decl.Location);
+ if (vi == null){
+ Report.Error (128, decl.Location,
+ "A local variable `" + decl.identifier +
+ "' is already defined in this scope");
} else {
-
- ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+ Location l = lexer.Location;
+ Expression expr;
+ if (decl.expression_or_array_initializer is Expression){
+ expr = (Expression) decl.expression_or_array_initializer;
+
+ } else {
+
+ ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+
+ string base_type = type.Substring (0, type.IndexOf ("["));
+ string rank = type.Substring (type.IndexOf ("["));
+
+ expr = new ArrayCreation (base_type, rank, init, decl.Location);
+ }
- string base_type = type.Substring (0, type.IndexOf ("["));
- string rank = type.Substring (type.IndexOf ("["));
+ LocalVariableReference var;
+ var = new LocalVariableReference (
+ assign_block, decl.identifier, l);
- expr = new ArrayCreation (base_type, rank, init, decl.Location);
+ Assign a = new Assign (var, expr, decl.Location);
+
+ assign_block.AddStatement (new StatementExpression (a, lexer.Location));
}
-
- LocalVariableReference var;
- var = new LocalVariableReference (
- assign_block, decl.identifier, l);
-
- Assign a = new Assign (var, expr, decl.Location);
-
- assign_block.AddStatement (new StatementExpression (a));
}
+
$3 = null;
}
+ oob_stack.Push (lexer.Location);
}
opt_for_condition SEMICOLON
opt_for_iterator CLOSE_PARENS
embedded_statement
{
- For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10);
+ Location l = (Location) oob_stack.Pop ();
+
+ For f = new For ((Statement) $3, (Expression) $6, (Statement) $8, (Statement) $10, l);
+
+ if (RootContext.WarningLevel >= 3){
+ if ($10 is EmptyStatement)
+ Report.Warning (642, lexer.Location, "Possibly mistaken empty statement");
+ }
current_block.AddStatement (f);
while (current_block.Implicit)
;
opt_for_condition
- : /* empty */ { $$ = new BoolLiteral (true); }
+ : /* empty */ { $$ = null; }
| boolean_expression
;
statement_expression_list
: statement_expression
{
- Block b = new Block (null, true);
+ // CHANGE: was `null'
+ Block b = new Block (current_block, true);
b.AddStatement ((Statement) $1);
$$ = b;
}
expression CLOSE_PARENS
{
+ oob_stack.Push (current_block);
+
Block foreach_block = new Block (current_block, true);
LocalVariableReference v;
Location l = lexer.Location;
+ VariableInfo vi;
- foreach_block.AddVariable ((string) $3, (string) $4, l);
- v = new LocalVariableReference (foreach_block, (string) $4, l);
+ vi = foreach_block.AddVariable ((string) $3, (string) $4, current_local_parameters, l);
+ if (vi == null){
+ Report.Error (
+ 128, l, "A local variable `" + (string) $4 + "' is already "+
+ "defined in this scope");
+ }
- current_block.AddStatement (foreach_block);
+ v = new LocalVariableReference (foreach_block, (string) $4, l);
current_block = foreach_block;
- oob_stack.Push (foreach_block);
oob_stack.Push (v);
+ oob_stack.Push (current_block);
}
embedded_statement
{
- LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
Block foreach_block = (Block) oob_stack.Pop ();
+ LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+ Block prev_block = (Block) oob_stack.Pop ();
Location l = (Location) oob_stack.Pop ();
- $$ = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+ current_block = prev_block;
+
+ Foreach f = new Foreach ((string) $3, v, (Expression) $7, (Statement) $10, l);
+ foreach_block.AddStatement (f);
+
+ $$ = foreach_block;
}
;
goto_statement
: GOTO IDENTIFIER SEMICOLON
{
- $$ = new Goto ((string) $2, lexer.Location);
+ $$ = new Goto (current_block, (string) $2, lexer.Location);
}
| GOTO CASE constant_expression SEMICOLON
{
throw_statement
: THROW opt_expression SEMICOLON
{
- $$ = new Throw ((Expression) $2);
+ $$ = new Throw ((Expression) $2, lexer.Location);
}
;
{
Catch g = null;
ArrayList s = new ArrayList ();
-
- foreach (Catch cc in (ArrayList) $3) {
- if (cc.Type == null)
- g = cc;
- else
- s.Add (cc);
+ ArrayList catch_list = (ArrayList) $3;
+
+ if (catch_list != null){
+ foreach (Catch cc in catch_list) {
+ if (cc.Type == null)
+ g = cc;
+ else
+ s.Add (cc);
+ }
}
$$ = new Try ((Block) $2, s, g, (Block) $5);
}
+ | TRY block error
+ {
+ Report.Error (1524, lexer.Location, "Expected catch or finally");
+ }
;
opt_catch_clauses
}
- $$ = new Catch (type, id , (Block) $4);
+ $$ = new Catch (type, id , (Block) $4, lexer.Location);
}
;
}
;
+unsafe_statement
+ : UNSAFE
+ {
+ if (!RootContext.Unsafe){
+ Report.Error (227, lexer.Location,
+ "Unsafe code can only be used if --unsafe is used");
+ }
+ } block {
+ $$ = new Unsafe ((Block) $3);
+ }
+ ;
+
+fixed_statement
+ : FIXED OPEN_PARENS
+ pointer_type fixed_pointer_declarators
+ CLOSE_PARENS
+ {
+ Block assign_block = new Block (current_block, true);
+ ArrayList list = (ArrayList) $4;
+ string type = (string) $3;
+ Location l = lexer.Location;
+ int top = list.Count;
+
+ for (int i = 0; i < top; i++){
+ Pair p = (Pair) list [i];
+ VariableInfo v;
+
+ v = current_block.AddVariable (type, (string) p.First,current_local_parameters, l);
+ if (v == null){
+ Report.Error (
+ 128, l, "A local variable `" + (string) p.First + "' is already "+
+ "defined in this scope");
+ }
+ v.ReadOnly = true;
+ p.First = v;
+ list [i] = p;
+ }
+ current_block.AddStatement (assign_block);
+ current_block = assign_block;
+ oob_stack.Push (assign_block);
+ oob_stack.Push (l);
+ }
+ embedded_statement
+ {
+ Location l = (Location) oob_stack.Pop ();
+ Block assign_block = (Block) oob_stack.Pop ();
+
+ ArrayList list = (ArrayList) $4;
+ int top = list.Count;
+
+ $$ = new Fixed ((string) $3, (ArrayList) $4, (Statement) $7, l);
+ }
+ ;
+
+fixed_pointer_declarators
+ : fixed_pointer_declarator {
+ ArrayList declarators = new ArrayList ();
+ declarators.Add ($1);
+ $$ = declarators;
+ }
+ | fixed_pointer_declarators COMMA fixed_pointer_declarator
+ {
+ ArrayList declarators = (ArrayList) $1;
+ declarators.Add ($3);
+ $$ = declarators;
+ }
+ ;
+
+fixed_pointer_declarator
+ : IDENTIFIER ASSIGN expression
+ {
+ $$ = new Pair ($1, $3);
+ }
+ ;
+
lock_statement
: LOCK OPEN_PARENS expression CLOSE_PARENS
{
ArrayList var_declarators = (ArrayList) de.Value;
foreach (VariableDeclaration decl in var_declarators){
- if (!current_block.AddVariable (type, decl.identifier, decl.Location)){
+ if (current_block.AddVariable (
+ type, decl.identifier,
+ current_local_parameters, decl.Location) == null){
Report.Error (128, decl.Location,
"A local variable `" + decl.identifier + "' is already" +
"defined in this scope");
vars.Add (new DictionaryEntry (var, expr));
// Assign a = new Assign (var, expr, decl.Location);
- // assign_block.AddStatement (new StatementExpression (a));
+ // assign_block.AddStatement (new StatementExpression (a, lexer.Location));
}
$3 = new DictionaryEntry (type, vars);
}
// in the current declaration space
// </summary>
void
-CheckDef (DeclSpace.AdditionResult result, string name)
+CheckDef (AdditionResult result, string name, Location l)
{
- if (result == DeclSpace.AdditionResult.Success)
+ if (result == AdditionResult.Success)
return;
- Location l = lexer.Location;
-
switch (result){
- case DeclSpace.AdditionResult.NameExists:
- Report.Error (102, l, "The namespace `" + current_container.Name +
+ case AdditionResult.NameExists:
+ Report.Error (102, l, "The container `" + current_container.Name +
"' already contains a definition for `"+
name + "'");
break;
-// NEED TO HANDLE THIS IN SEMANTIC ANALYSIS:
-//
-// case DeclSpace.AdditionResult.MethodDuplicated:
-// error (111, "Class `"+current_container.Name+
-// "' already defines a member called '" +
-// name + "' with the same parameter types");
-// break;
-
- case DeclSpace.AdditionResult.EnclosingClash:
+ //
+ // This is handled only for static Constructors, because
+ // in reality we handle these by the semantic analysis later
+ //
+ case 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:
Report.Error (542, l, "Member names cannot be the same as their enclosing type");
break;
- case DeclSpace.AdditionResult.NotAConstructor:
+ case AdditionResult.NotAConstructor:
Report.Error (1520, l, "Class, struct, or interface method must have a return type");
break;
}
}
void
-CheckDef (bool result, string name)
+CheckDef (bool result, string name, Location l)
{
if (result)
return;
- CheckDef (DeclSpace.AdditionResult.NameExists, name);
+ CheckDef (AdditionResult.NameExists, name, l);
}
+//
+// This routine should be removed soon. I am in the process of making
+// changes to never keep anything but SimpleNames during parsing, as
+// that breaks some kinds of code (documented in the ChangeLog).
+//
Expression
SimpleLookup (string name, Location loc)
{
// as `expression' is allowed in argument_lists, which
// do not exist inside a block.
//
- if (current_block != null){
- if (current_block.IsVariableDefined (name))
- return new LocalVariableReference (current_block, name, loc);
- }
if (current_local_parameters != null){
int idx;
else if (expr is MemberAccess)
return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
else
- throw new Exception ("Expr has to be either SimpleName or MemberAccess !");
+ throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
}
// int j = 1; int k = j + 1;
//
if (current_block.Used)
- implicit_block = new Block (current_block, true);
+ implicit_block = new Block (current_block, true, loc, Location.Null);
else
implicit_block = current_block;
foreach (VariableDeclaration decl in variable_declarators){
- if (implicit_block.AddVariable (type, decl.identifier, decl.Location)){
+
+ 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 ();
assign = new Assign (var, expr, decl.Location);
- implicit_block.AddStatement (new StatementExpression (assign));
+ implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
}
return implicit_block;
implicit_block = current_block;
if (!(implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
- decl.Location))){
+ current_local_parameters, decl.Location))){
Report.Error (128, decl.Location, "A local variable `" + decl.identifier +
"' is already defined in this scope");
}
default :
Location l = lexer.Location;
- Report.Error (658, l, "Invalid attribute target");
+ Report.Error (658, l, "`" + a + "' is an invalid attribute target");
break;
}
}
}
-public CSharpParser(RootContext rc, string name, System.IO.Stream input)
+public CSharpParser (string name, System.IO.Stream input, ArrayList defines)
{
current_namespace = new Namespace (null, "");
- this.rc = rc;
- this.tree = rc.Tree;
this.name = name;
this.input = input;
- current_container = tree.Types;
+ current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
oob_stack = new Stack ();
- lexer = new Tokenizer (input, name);
+ lexer = new Tokenizer (input, name, defines);
}
public override int parse ()
{
- StringBuilder value = new StringBuilder ();
-
global_errors = 0;
try {
if (yacc_verbose_flag)
return global_errors;
}
-
/* end end end */
}