// great spot to put an `error' because you can reproduce it with this input:
// "public X { }"
//
+// Possible optimization:
+// Run memory profiler with parsing only, and consider dropping
+// arraylists where not needed. Some pieces can use linked lists.
//
using System.Text;
using System.IO;
Namespace current_namespace;
TypeContainer current_container;
+ IIteratorContainer iterator_container;
+
// <summary>
// Current block is used to add statements as we find
// them.
// Switch stack.
//
Stack switch_stack;
+
+ //
+ // The current file.
+ //
+ SourceFile file;
%}
%token EOF
%token VOLATILE
%token WHILE
+/* v2 tokens */
+%token YIELD
+
/* C# keywords which are not really keywords */
%token GET "get"
%token SET "set"
if (attrs != null) {
foreach (AttributeSection asec in attrs.AttributeSections)
if (asec.Target == "assembly")
- RootContext.AddGlobalAttribute (
- current_container, asec, lexer.Location);
+ RootContext.AddGlobalAttributeSection (current_container, asec);
+ else
+ Report.Error(1518, Lexer.Location,
+ "Attributes cannot be applied to namespaces."
+ + " Expected class, delegate, enum, interface, or struct");
}
- current_namespace = RootContext.Tree.RecordNamespace (current_namespace, name, (string) $3);
+ current_namespace = RootContext.Tree.RecordNamespace (current_namespace, file, (string) $3);
}
namespace_body opt_semicolon
{
}
current_namespace.DeclarationFound = true;
}
- | namespace_declaration
+ | namespace_declaration {
+ current_namespace.DeclarationFound = true;
+ }
;
type_declaration
AttributeSection sect = (AttributeSection) $1;
if (sect.Target == "assembly")
- RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
+ RootContext.AddGlobalAttributeSection (current_container, sect);
- $$ = new Attributes ((AttributeSection) $1, lexer.Location);
+ $$ = new Attributes ((AttributeSection) $1);
}
| attribute_sections attribute_section
{
AttributeSection sect = (AttributeSection) $2;
if (sect.Target == "assembly")
- RootContext.AddGlobalAttribute (current_container, sect, lexer.Location);
+ RootContext.AddGlobalAttributeSection (current_container, sect);
if ($1 != null) {
attrs = (Attributes) $1;
- attrs.AddAttribute (sect);
+ attrs.AddAttributeSection (sect);
}
$$ = attrs;
;
attribute_section
- : OPEN_BRACKET attribute_target_specifier attribute_list CLOSE_BRACKET
+ : OPEN_BRACKET attribute_target_specifier attribute_list opt_comma CLOSE_BRACKET
{
string target = null;
$$ = new AttributeSection (target, (ArrayList) $3);
}
- | OPEN_BRACKET attribute_list CLOSE_BRACKET
+ | OPEN_BRACKET attribute_list opt_comma CLOSE_BRACKET
{
$$ = new AttributeSection (null, (ArrayList) $2);
}
;
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;
}
;
Constructor c = (Constructor) $3;
c.Block = (Block) $4;
c.OptAttributes = (Attributes) $1;
+ c.ModFlags = (int) $2;
- if ((c.ModFlags & Modifiers.STATIC) != 0){
- c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, 0, c.Location);
-
- if ((c.ModFlags & Modifiers.Accessibility) != 0) {
- Report.Error (
- 515, c.Location,
- "Access modifiers are not allowed on static constructors");
- }
-
- if (c.Initializer != null){
- Report.Error (
- 514, c.Location,
- "Static constructors can not have an explicit this or base " +
- "constructor invocations");
- }
-
- if (!c.Parameters.Empty){
- Report.Error (
- 132, c.Location, "Static constructors should not have parameters");
+ if (c.Name == current_container.Basename){
+ if ((c.ModFlags & Modifiers.STATIC) != 0){
+ if ((c.ModFlags & Modifiers.Accessibility) != 0){
+ Report.Error (
+ 515, c.Location, String.Format (
+ "`{0}.{1}': static constructor can not have access modifiers",
+ c.Name, current_container.Name));
+ }
+
+ c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
+
+ if (c.Initializer != null){
+ Report.Error (
+ 514, c.Location,
+ "Static constructors can not have an explicit this or base " +
+ "constructor invocations");
+ }
+
+ if (!c.Parameters.Empty){
+ Report.Error (
+ 132, c.Location, "Static constructors should not have parameters");
+ }
+ } else {
+ c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
}
} else {
- c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
+ // We let another layer check the validity of the constructor.
+ Console.WriteLine ("{0} and {1}", c.Name, current_container.Basename);
}
-
+
CheckDef (current_container.AddConstructor (c), c.Name, c.Location);
current_local_parameters = null;
$$ = 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
// 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);
}
}
;
// 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;
: 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;
| goto_statement
| return_statement
| throw_statement
+ | yield_statement
;
break_statement
}
;
+yield_statement
+ : 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
fixed_statement
: FIXED OPEN_PARENS
- pointer_type fixed_pointer_declarators
+ 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;
// 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;
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;
}
}
-public CSharpParser (StreamReader reader, string name, ArrayList defines)
+public CSharpParser (StreamReader reader, SourceFile file, ArrayList defines)
{
- current_namespace = new Namespace (null, "");
- this.name = name;
+ current_namespace = new Namespace (null, file, "");
+ this.name = file.Name;
+ this.file = file;
current_container = RootContext.Tree.Types;
current_container.Namespace = current_namespace;
oob_stack = new Stack ();
switch_stack = new Stack ();
- lexer = new Tokenizer (reader, name, defines);
+ lexer = new Tokenizer (reader, file, defines);
}
public override void parse ()
yyparse (lexer, new yydebug.yyDebugSimple ());
else
yyparse (lexer);
+ Tokenizer tokenizer = lexer as Tokenizer;
+ tokenizer.cleanup ();
} catch (Exception e){
// Please do not remove this, it is used during debugging
// of the grammar
//
- Console.WriteLine (lexer.location + " : Parsing error ");
+ Report.Error (-25, lexer.Location, ": Parsing error ");
Console.WriteLine (e);
}
}