public class CSharpParser {
NamespaceEntry current_namespace;
TypeContainer current_container;
- TypeContainer current_class;
+ DeclSpace current_class;
IIteratorContainer iterator_container;
/// Hack to help create non-typed array initializer
/// </summary>
public static Expression current_array_type;
+ Expression pushed_current_array_type;
/// <summary>
/// Used to determine if we are parsing the get/set pair
}
current_namespace = new NamespaceEntry (
- current_namespace, file, name.GetName (), name.Location);
+ current_namespace, file, name.GetName ());
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer;
}
namespace_body opt_semicolon
{
current_namespace = current_namespace.Parent;
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer;
}
;
: attribute_name opt_attribute_arguments
{
MemberName mname = (MemberName) $1;
- ArrayList arguments = (ArrayList) $2;
+ object[] arguments = (object[]) $2;
MemberName left = mname.Left;
string identifier = mname.Name;
if ($1 == null)
$$ = null;
else {
- ArrayList args = new ArrayList (4);
- args.Add ($1);
-
- $$ = args;
+ $$ = new object [] { $1, null };
}
}
- | positional_argument_list COMMA named_argument_list
+ | positional_argument_list COMMA named_argument_list
{
- ArrayList args = new ArrayList (4);
- args.Add ($1);
- args.Add ($3);
-
- $$ = args;
+ $$ = new object[] { $1, $3 };
}
- | named_argument_list
+ | named_argument_list
{
- ArrayList args = new ArrayList (4);
- args.Add (null);
- args.Add ($1);
-
- $$ = args;
+ $$ = new object [] { null, $1 };
}
- ;
+ ;
opt_positional_argument_list
STRUCT member_name
{
MemberName name = MakeName ((MemberName) $5);
- if ($3 != null) {
- ClassPart part = PartialContainer.CreatePart (
- current_namespace, current_class, name, (int) $2,
- (Attributes) $1, Kind.Struct, (Location) $3);
+ push_current_class (new Struct (
+ current_namespace, current_class, name, (int) $2,
+ (Attributes) $1), false, $3);
- current_container = part.PartialContainer;
- current_class = part;
- } else {
- current_class = new Struct (
- current_namespace, current_class, name, (int) $2,
- (Attributes) $1);
-
- current_container.AddClassOrStruct (current_class);
- current_container = current_class;
- RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
- }
}
opt_class_base
{
if ($7 != null)
- current_class.Bases = (ArrayList) $7;
+ current_container.AddBasesForPart (current_class, (ArrayList) $7);
if (RootContext.Documentation != null)
- current_class.DocComment = Lexer.consume_doc_comment ();
+ current_container.DocComment = Lexer.consume_doc_comment ();
}
struct_body
{
Expression type = (Expression) $3;
int mod = (int) $2;
+ current_array_type = null;
+
foreach (VariableDeclaration var in (ArrayList) $4){
Field field = new Field (current_class, type, mod, var.identifier,
(Attributes) $1, var.Location);
Expression type = (Expression) $4;
int mod = (int) $2;
+ current_array_type = null;
+
foreach (VariableDeclaration var in (ArrayList) $5) {
FixedField field = new FixedField (current_class, type, mod, var.identifier,
(Expression)var.expression_or_array_initializer, (Attributes) $1, var.Location);
VOID
variable_declarators
SEMICOLON {
+ current_array_type = null;
Report.Error (670, (Location) $3, "Fields cannot have void type");
}
;
{
$$ = new StackAlloc ((Expression) $2, (Expression) $4, (Location) $1);
}
+ | ARGLIST
+ {
+ $$ = new ArglistAccess ((Location) $1);
+ }
| STACKALLOC type
{
Report.Error (1575, (Location) $1, "A stackalloc expression requires [] after type");
$$ = new Parameters (pars, true);
}
- | parameter_array COMMA fixed_parameters
+ | parameter_array COMMA error
{
if ($1 != null)
Report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
$$ = null;
}
- | ARGLIST COMMA fixed_parameters
+ | fixed_parameters COMMA parameter_array COMMA error
+ {
+ if ($3 != null)
+ Report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
+ $$ = null;
+ }
+ | ARGLIST COMMA error
{
Report.Error (257, (Location) $1, "An __arglist parameter must be the last parameter in a formal parameter list");
$$ = null;
}
+ | fixed_parameters COMMA ARGLIST COMMA error
+ {
+ Report.Error (257, (Location) $3, "An __arglist parameter must be the last parameter in a formal parameter list");
+ $$ = null;
+ }
| parameter_array
{
$$ = new Parameters (new Parameter[] { (Parameter) $1 } );
{
MemberName name = MakeName ((MemberName) $5);
- if ($3 != null) {
- ClassPart part = PartialContainer.CreatePart (
- current_namespace, current_class, name, (int) $2,
- (Attributes) $1, Kind.Interface, (Location) $3);
-
- current_container = part.PartialContainer;
- current_class = part;
- } else {
- current_class = new Interface (
- current_namespace, current_class, name, (int) $2,
- (Attributes) $1);
-
- current_container.AddInterface (current_class);
- current_container = current_class;
- RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
- }
+ push_current_class (new Interface (
+ current_namespace, current_class, name, (int) $2,
+ (Attributes) $1), true, $3);
}
opt_class_base
{
- current_class.Bases = (ArrayList) $7;
+ current_container.AddBasesForPart (current_class, (ArrayList) $7);
if (RootContext.Documentation != null) {
- current_class.DocComment = Lexer.consume_doc_comment ();
+ current_container.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
}
"`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
c.GetSignatureForError ());
}
-
- if (!c.Parameters.Empty){
- Report.Error (132, c.Location,
- "`{0}': The static constructor must be parameterless", c.GetSignatureForError ());
- }
} else {
c.ModFlags = Modifiers.Check (Constructor.AllowedModifiers, (int) $2, Modifiers.PRIVATE, c.Location);
}
opt_modifiers
EVENT type variable_declarators SEMICOLON
{
+ current_array_type = null;
foreach (VariableDeclaration var in (ArrayList) $5) {
MemberName name = new MemberName (var.identifier,
}
current_container.AddEnum (e);
- RootContext.Tree.RecordDecl (current_namespace.NS, name, e);
$$ = e;
}
SEMICOLON
{
MemberName name = MakeName ((MemberName) $5);
+ Parameters p = (Parameters) $7;
+ if (p.HasArglist) {
+ // TODO: wrong location
+ Report.Error (1669, name.Location, "__arglist is not valid in this context");
+ }
+
Delegate del = new Delegate (current_namespace, current_class, (Expression) $4,
- (int) $2, name, (Parameters) $7, (Attributes) $1);
+ (int) $2, name, p, (Attributes) $1);
if (RootContext.Documentation != null) {
del.DocComment = Lexer.consume_doc_comment ();
}
current_container.AddDelegate (del);
- RootContext.Tree.RecordDecl (current_namespace.NS, name, del);
$$ = del;
}
;
// CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST, CLOSE_PARENS_OPEN_PARENS
// or CLOSE_PARENS_MINUS.
}
+ | OPEN_PARENS expression error { CheckToken (1026, yyToken, "Expecting ')'", lexer.Location); }
;
parenthesized_expression
// in Binary.DoResolve().
$$ = new ParenthesizedExpression ((Expression) $1);
}
- ;;
+ ;
member_access
: primary_expression DOT IDENTIFIER
{
LocatedToken lt = (LocatedToken) $3;
- $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);
+ $$ = new MemberAccess ((Expression) $1, lt.Value);
}
| predefined_type DOT IDENTIFIER
{
LocatedToken lt = (LocatedToken) $3;
+ // TODO: Location is wrong as some predefined types doesn't hold a location
$$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);
}
;
;
invocation_expression
- : primary_expression {
- $$ = lexer.Location;
- } OPEN_PARENS opt_argument_list CLOSE_PARENS
+ : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- if ($1 == null) {
- Location l = (Location) $3;
- Report.Error (1, l, "Parse error");
- }
- $$ = new Invocation ((Expression) $1, (ArrayList) $4);
+ if ($1 == null)
+ Report.Error (1, (Location) $2, "Parse error");
+ else
+ $$ = new Invocation ((Expression) $1, (ArrayList) $3);
}
| parenthesized_expression_0 CLOSE_PARENS_OPEN_PARENS OPEN_PARENS CLOSE_PARENS
{
;
typeof_expression
- : TYPEOF OPEN_PARENS VOID CLOSE_PARENS
- {
- $$ = new TypeOfVoid ((Location) $1);
+ : TYPEOF
+ {
+ pushed_current_array_type = current_array_type;
}
- | TYPEOF OPEN_PARENS type CLOSE_PARENS
+ OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((Expression) $3, (Location) $1);
+ Expression type = (Expression)$4;
+ if (type == TypeManager.system_void_expr)
+ $$ = new TypeOfVoid ((Location) $1);
+ else
+ $$ = new TypeOf (type, (Location) $1);
+ current_array_type = pushed_current_array_type;
}
;
LocatedToken lt = (LocatedToken) $3;
deref = new Unary (Unary.Operator.Indirection, (Expression) $1, lt.Location);
- $$ = new MemberAccess (deref, lt.Value, lt.Location);
+ $$ = new MemberAccess (deref, lt.Value);
}
;
anonymous_method_expression
: DELEGATE opt_anonymous_method_signature
{
+ if (oob_stack == null)
+ oob_stack = new Stack (6);
+
oob_stack.Push (current_local_parameters);
current_local_parameters = (Parameters)$2;
ToplevelBlock anon_block = (ToplevelBlock) $4;
anon_block.Parent = current_block;
- $$ = new AnonymousMethod ((Parameters) $2, (ToplevelBlock) top_current_block,
+ $$ = new AnonymousMethod (current_container, (Parameters) $2, (ToplevelBlock) top_current_block,
anon_block, loc);
}
current_local_parameters = (Parameters) oob_stack.Pop ();
MemberName name = MakeName ((MemberName) $5);
int mod_flags = (int) $2;
- if ($3 != null) {
- ClassPart part = PartialContainer.CreatePart (
- current_namespace, current_class, name, mod_flags,
- (Attributes) $1, Kind.Class, (Location) $3);
-
- current_container = part.PartialContainer;
- current_class = part;
- } else {
- if ((mod_flags & Modifiers.STATIC) != 0) {
- current_class = new StaticClass (
- current_namespace, current_class, name,
- mod_flags, (Attributes) $1);
- } else {
- current_class = new Class (
- current_namespace, current_class, name,
- mod_flags, (Attributes) $1);
- }
-
- current_container.AddClassOrStruct (current_class);
- current_container = current_class;
- RootContext.Tree.RecordDecl (current_namespace.NS, name, current_class);
- }
+ push_current_class (new Class (
+ current_namespace, current_class, name,
+ mod_flags, (Attributes) $1), false, $3);
}
opt_class_base
{
"The class System.Object cannot have a base " +
"class or implement an interface.");
}
- current_class.Bases = (ArrayList) $7;
+ current_container.AddBasesForPart (current_class, (ArrayList) $7);
}
if (RootContext.Documentation != null) {
- current_class.DocComment = Lexer.consume_doc_comment ();
+ current_container.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
}
current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, (Location) $1);
top_current_block = current_block;
} else {
- current_block = new Block (current_block, (Location) $1, Location.Null);
+ current_block = new Block (current_block, (Location) $1, Location.Null);
}
}
opt_statement_list CLOSE_BRACE
LocatedToken lt = (LocatedToken) $1;
LabeledStatement labeled = new LabeledStatement (lt.Value, lt.Location);
- if (current_block.AddLabel (lt.Value, labeled, lt.Location))
+ if (current_block.AddLabel (labeled))
current_block.AddStatement (labeled);
}
statement
declaration_statement
: local_variable_declaration SEMICOLON
{
+ current_array_type = null;
if ($1 != null){
DictionaryEntry de = (DictionaryEntry) $1;
Expression e = (Expression) de.Key;
| local_constant_declaration SEMICOLON
{
+ current_array_type = null;
if ($1 != null){
DictionaryEntry de = (DictionaryEntry) $1;
;
expression_statement
- : statement_expression SEMICOLON
- {
- $$ = $1;
- }
+ : statement_expression SEMICOLON { $$ = $1; }
;
//
// 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); }
- | error {
+ : expression
+ {
+ Expression expr = (Expression) $1;
+ ExpressionStatement s = expr as ExpressionStatement;
+ if (s == null) {
+ Report.Error (201, expr.Location, "Only assignment, call, increment, decrement, and new object expressions can be used as a statement");
+ $$ = null;
+ }
+ $$ = new StatementExpression (s);
+ }
+ | error
+ {
Report.Error (1002, GetLocation ($1), "Expecting `;'");
$$ = null;
}
switch_statement
: SWITCH OPEN_PARENS
{
+ if (switch_stack == null)
+ switch_stack = new Stack (2);
switch_stack.Push (current_block);
}
expression CLOSE_PARENS
opt_switch_sections
: /* empty */
{
- Report.Error (1522, lexer.Location, "Empty switch block");
+ Report.Warning (1522, 1, lexer.Location, "Empty switch block");
+ $$ = new ArrayList ();
}
| switch_sections
;
} block {
Expression type = null;
string id = null;
+ Block var_block = null;
if ($2 != null){
DictionaryEntry cc = (DictionaryEntry) $2;
id = lt.Value;
while (current_block.Implicit)
current_block = current_block.Parent;
+ var_block = current_block;
current_block = current_block.Parent;
}
}
- $$ = new Catch (type, id, (Block) $4, ((Block) $4).loc);
+ $$ = new Catch (type, id, (Block) $4, var_block, ((Block) $4).loc);
}
;
} else {
this.expression_or_array_initializer = (Expression)eoai;
}
- CSharpParser.current_array_type = null;
this.Location = lt.Location;
this.OptAttributes = opt_attrs;
}
}
}
-TypeContainer pop_current_class ()
+void push_current_class (TypeContainer tc, bool is_interface, object partial_token)
{
- TypeContainer retval = current_class;
+ if (partial_token != null)
+ current_container = current_container.AddPartial (tc, is_interface);
+ else
+ current_container = current_container.AddTypeContainer (tc, is_interface);
+ current_class = tc;
+}
- current_class = (TypeContainer) current_class.Parent;
- current_container = (TypeContainer) current_container.Parent;
+DeclSpace pop_current_class ()
+{
+ DeclSpace retval = current_class;
- if (current_class != current_container) {
- if (((ClassPart) current_class).PartialContainer != current_container)
- throw new InternalErrorException ("current_container and current_class are out of sync");
- } else if (current_container is ClassPart)
- current_container = ((ClassPart) current_class).PartialContainer;
+ current_class = current_class.Parent;
+ current_container = current_class.PartialContainer;
return retval;
}
{
Namespace ns = current_namespace.NS;
- if (current_container.Name == ""){
- if (ns.Name != "")
+ if (current_container.Name.Length == 0){
+ if (ns.Name.Length != 0)
return new MemberName (ns.MemberName, class_name);
else
return class_name;
public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
{
- current_namespace = new NamespaceEntry (null, file, null, Location.Null);
this.name = file.Name;
this.file = file;
- current_container = RootContext.Tree.Types;
- // TODO: Make RootContext.Tree.Types a PartialContainer.
- current_class = current_container;
- current_container.NamespaceEntry = current_namespace;
- oob_stack = new Stack ();
- switch_stack = new Stack ();
+ current_namespace = new NamespaceEntry (null, file, null);
+ current_class = current_namespace.SlaveDeclSpace;
+ current_container = current_class.PartialContainer; // == RootContest.ToplevelTypes
lexer = new Tokenizer (reader, file, defines);
}
public void parse ()
{
+ int errors = Report.Errors;
try {
if (yacc_verbose_flag > 1)
yyparse (lexer, new yydebug.yyDebugSimple ());
// Removed for production use, use parser verbose to get the output.
//
// Console.WriteLine (e);
- Report.Error (-25, lexer.Location, "Parsing error");
+ if (Report.Errors == errors)
+ Report.Error (-25, lexer.Location, "Parsing error");
if (yacc_verbose_flag > 0)
Console.WriteLine (e);
}
- RootContext.Tree.Types.NamespaceEntry = null;
+ if (RootContext.ToplevelTypes.NamespaceEntry != null)
+ throw new InternalErrorException ("who set it?");
}
-void CheckToken (int error, int yyToken, string msg, Location loc)
+static void CheckToken (int error, int yyToken, string msg, Location loc)
{
- if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){
- Report.Error (error, loc, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ()));
- return;
- }
- Report.Error (error, loc, msg);
+ if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
+ Report.Error (error, loc, "{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ());
+ else
+ Report.Error (error, loc, msg);
}
void CheckIdentifierToken (int yyToken, Location loc)