Solved

cannot implicitly convert type " " to System.Collections.Generic.List<> in c#

Posted on 2012-03-12
9
1,554 Views
Last Modified: 2012-06-21
Hi all,
I'm currently working on abstract syntax tree(clite grammar).
But i'm getting a few errors:

error (line 8): cannot implicitly convert type "Declarations" to System.Collections.Generic.List<CliteLexer.Declaration>

error(line 9): the call is ambiguous between the following method and properties: 'CliteLexer.Parser.statements()' and 'CliteLexer.Parser.statements()'.

error(line 15):CProgram does not contain a constructor that takes 2 arguments.

error(line 18):Type or namespace name 'Declarations' could not be found (are you missing a using directive or an assembly reference).
*same error in line 20

this is part of my program from Parser.cs:
public Program program()
        {
            match(Token.TokenType.Int);
            match(Token.TokenType.Main);
            match(Token.TokenType.LeftParen);
            match(Token.TokenType.RightParen);
            match(Token.TokenType.LeftBrace);
            List<Declaration> decls = declarations();
            List<Statement> stmts = statements();
            match(Token.TokenType.RightBrace);

            if (error_flag == false)
                Console.WriteLine("No Syntax Error. Comgratulation!");

            CProgram p = new CProgram(decls,stmts);
        }

        private Declarations declarations()
        {
            Declarations ds = new Declarations();
            while (current_token.getType() == Token.TokenType.Int ||
                current_token.getType() == Token.TokenType.Float ||
                current_token.getType() == Token.TokenType.Char ||
                current_token.getType() == Token.TokenType.Bool)
                declaration(ds);
            return ds;
        }

        private void declaration(Declarations ds)
        {
            Type t = type();
            match(Token.TokenType.Identifier);
            if (current_token.getType() == Token.TokenType.LeftBracket)
            {
                match(Token.TokenType.LeftBracket);
                match(Token.TokenType.IntLiteral);
                match(Token.TokenType.RightBracket);
            }

            while (current_token.getType() == Token.TokenType.Comma)
            {
                match(Token.TokenType.Comma);
                match(Token.TokenType.Identifier);
                if (current_token.getType() == Token.TokenType.LeftBracket)
                {
                    match(Token.TokenType.LeftBracket);
                    match(Token.TokenType.IntLiteral);
                    match(Token.TokenType.RightBracket);
                }
            }

            match(Token.TokenType.Semicolon);
        }

Open in new window


part of the program in AbstractSyntax.cs:
public class CProgram
    {
        List<Declaration> decpart = new List<Declaration>();
        List<Statement> body = new List<Statement>();

        CProgram(List<Declaration> d, List<Statement> b)
        {
            decpart = d;
            body = b;
        }

        public String toStringIndented(String indent)
        {
            return indent + "Program(\n"
              + decpart.toStringIndented(indent + "  ") + ",\n"
              + body.toStringIndented(indent + "  ") + "\n"
              + indent + ")";
        }

        public String toString()
        {
            return toStringIndented("");
        }
    }

    public class Declaration
    {
        public List<Declaration> decl = null;

        public Declaration(List<string> Declarations)
        {
            this.decl = Declarations;
        }

        public String toString()
        {
            return toStringIndented("");
        }

        public String toStringIndented(String indent)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(indent);
            sb.Append("Declarations(\n");
            int i = 0;
            foreach (string s in decl)
            {
                sb.Append(this.toStringIndented(indent + "  "));
                i++;
                if (i == decl.Count)
                    sb.Append("\n");
                else
                    sb.Append(",\n");
            }
            sb.Append(indent);
            sb.Append(")");
            return sb.ToString();
        }
    }

    public class VariableDecl : Declaration
    {
        Variable v;
        Type t;

        public VariableDecl(List<string> Declarations) : base(Declarations)
        {

        }

        public new String toString()
        {
            return toStringIndented("");
        }

        public new String toStringIndented(String indent)
        {
            return indent + "Declaration(" + v + ", " + t + ")";
        }
    }

    public class ArrayDecl : Declaration
    {
        Variable v = null;
        Type t = null;

        int size = 0;

        public ArrayDecl(List<string> Declarations) : base(Declarations)
        {

        }

        public new String toString()
        {
            return toStringIndented("");
        }

        public new String toStringIndented(String indent)
        {
            return indent + "Declaration(" + v + ", " + t + ", " + size + ")";
        }
    }

Open in new window


any help would be greatly appreciated thanks:)
0
Comment
Question by:crazy4s
  • 4
  • 3
9 Comments
 
LVL 74

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 37712568
error (line 8): cannot implicitly convert type "Declarations" to System.Collections.Generic.List<CliteLexer.Declaration>
You've declared the variable to be a List<Declaration>, yet your method declarations returns a single Declarations object. These are two different types. You either need to change your method to return a List<Declaration> or change your variable to be of type Declarations.

error(line 9): the call is ambiguous between the following method and properties: 'CliteLexer.Parser.statements()' and 'CliteLexer.Parser.statements()'.
Don't know specifically because you don't display that function definition anywhere. However, this means you have two properties with the same name within scope, and the compiler doesn't know which you intended to use.


error(line 15):CProgram does not contain a constructor that takes 2 arguments.
You haven't marked the constructor for CProgram as public, so it defaults to private. This means the compiler doesn't see an accessible constructor taking two parameters.

error(line 18):Type or namespace name 'Declarations' could not be found (are you missing a using directive or an assembly reference).
*same error in line 20
You don't display a class definition for a type named Declarations (plural). However, there is a type named Declaration (singular). Did you intend to refer to that class?
0
 

Author Comment

by:crazy4s
ID: 37712625
>>You've declared the variable to be a List<Declaration>, yet your method declarations returns a single Declarations object. These are two different types. You either need to change your method to return a List<Declaration> or change your variable to be of type Declarations.

so do you meant i need to return a List<Declaration> for this class?
private Declaration declarations()
        {
            List<Declaration> ds = new List<Declaration>();
            while (current_token.getType() == Token.TokenType.Int ||
                current_token.getType() == Token.TokenType.Float ||
                current_token.getType() == Token.TokenType.Char ||
                current_token.getType() == Token.TokenType.Bool)
                declaration(ds); <-- //has some invalid arguments??
            return ds; <-- //cannot implicitly convert type 'System.Collection.Generic.List<CliteLexer.Declaration>' to 'CliteLexer.Declaration'
        }

>> Don't know specifically because you don't display that function definition anywhere. However, this means you have two properties with the same name within scope, and the compiler doesn't know which you intended to use.

in my Parser.cs:
private Statement statements()
        {
            Statements s = new Statements();
            while (current_token.getType() == Token.TokenType.Semicolon ||
                current_token.getType() == Token.TokenType.LeftBrace ||
                current_token.getType() == Token.TokenType.Identifier ||
                current_token.getType() == Token.TokenType.If ||
                current_token.getType() == Token.TokenType.While)
                statement(s);
            return s;
        }

        private statement(Statements s)
        {
            if (current_token.getType() == Token.TokenType.Semicolon)
            {
                s = new Skip(match(Token.TokenType.Semicolon));            
            }
            else if (current_token.getType() == Token.TokenType.LeftBrace)
            {
                match(Token.TokenType.LeftBrace);
                s = statement();
                match(Token.TokenType.RightBrace);
            }
            else if (current_token.getType() == Token.TokenType.Identifier)
            {
                s = assignment();
            }
            else if (current_token.getType() == Token.TokenType.If)
            {
                s = ifstatement();
            }
            else if (current_token.getType() == Token.TokenType.While)
            {
                s = whilestatement();
            }

            return s;
        }

Open in new window


in AbstractSyntax.cs:
    public class Statement
    {
        public List<string> stat = null;

        public Statement(List<string> Statements)
        {
            this.stat = Statements;
        }

        public String toString()
        {
            return toStringIndented("");
        }

        public String toStringIndented(String indent)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(indent);
            sb.Append("Declarations(\n");
            int i = 0;
            foreach (string s in stat)
            {
                sb.Append(this.toStringIndented(indent + "  "));
                i++;
                if (i == stat.Count)
                    sb.Append("\n");
                else
                    sb.Append(",\n");
            }
            sb.Append(indent);
            sb.Append(")");
            return sb.ToString();
        }
    }

Open in new window


>> You don't display a class definition for a type named Declarations (plural). However, there is a type named Declaration (singular). Did you intend to refer to that class?

i was actually abit confuse on when to use singular and plural although i understand how it should works but when come to coding i just got confused! can you explain on this?
0
 

Author Comment

by:crazy4s
ID: 37712912
for the first error, not sure whether i'm right but can i do it this way?
but still got the error for the return list:(

        private Declaration declarations()
        {
            List<Declaration> ds = new List<Declaration>();
            Declaration dsl;
            while (current_token.getType() == Token.TokenType.Int ||
                current_token.getType() == Token.TokenType.Float ||
                current_token.getType() == Token.TokenType.Char ||
                current_token.getType() == Token.TokenType.Bool)
            {
                declaration(dsl);
                ds.Add(dsl);
            }
            return ds; <-- //cannot implicitly convert type 'System.Collection.Generic.List<CliteLexer.Declaration>' to 'CliteLexer.Declaration'
        }
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:crazy4s
ID: 37717992
So now i have this in my Parser.cs:

private List<Declaration> declarations()
        {
            List<Declaration> ds = new List<Declaration>();
            List<Declaration> dsl = new List<Declaration>();
            while (current_token.getType() == Token.TokenType.Int ||
                current_token.getType() == Token.TokenType.Float ||
                current_token.getType() == Token.TokenType.Char ||
                current_token.getType() == Token.TokenType.Bool)
            {
                dsl = declaration();
                ds.AddRange(dsl);
            }
            return ds; 
        }

        private List<Declaration> declaration()
        {
            List<Declaration> result = new List<Declaration>();
            Type t = type();
            Variable v = new Variable(match(Token.TokenType.Identifier));

            if (current_token.getType() == Token.TokenType.LeftBracket)
            {
                match(Token.TokenType.LeftBracket);
                int i = Convert.ToInt32(match(Token.TokenType.IntLiteral));
                match(Token.TokenType.RightBracket);
                ArrayDecl ad = new ArrayDecl(v, t, i);
                result.Add(ad);
            }
            else
            {
                VariableDecl vd = new VariableDecl(v, t);
                result.Add(vd);
            }

            while (current_token.getType() == Token.TokenType.Comma)
            {
                match(Token.TokenType.Comma);
                Variable v1 = new Variable(match(Token.TokenType.Identifier));
                if (current_token.getType() == Token.TokenType.LeftBracket)
                {
                    match(Token.TokenType.LeftBracket);
                    int i = Convert.ToInt32(match(Token.TokenType.IntLiteral));
                    match(Token.TokenType.RightBracket);
                    ArrayDecl ad = new ArrayDecl(v1, t, i);
                    result.Add(ad);
                }
                else
                {
                    VariableDecl vd2 = new VariableDecl(v1, t);
                    result.Add(vd2);
                }
            }

            match(Token.TokenType.Semicolon);

            return result;
        }

Open in new window


after editing my code in parser, i edited my abstract syntax too but how should i get the items from the list<> and print it out? before that i used "this" but it seems lk not working because all the Declaration subclass are complaining "does not have a constructor that takes 0 argument?
public class Declaration
    {
        public List<Declaration> decl = null;

        public Declaration(List<Declaration> Declarations)
        {
            this.decl = Declarations;
        }

        public String toString()
        {
            return toStringIndented("");
        }

        public String toStringIndented(String indent)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(indent);
            sb.Append("Declarations(\n");
            int i = 0;
            foreach (Declaration s in decl)
            {
                sb.Append(this.toStringIndented(indent + "  "));
                i++;
                if (i == decl.Count)
                    sb.Append("\n");
                else
                    sb.Append(",\n");
            }
            sb.Append(indent);
            sb.Append(")");
            return sb.ToString();
        }
}

public class VariableDecl : Declaration
    {
        Variable v = null;
        Type t = null;

        public VariableDecl(List<Declaration> Declarations)
            : base(Declarations)
        {

        }

        public VariableDecl(Variable v1, Type t1) <-- error????
        {
            v = v1;
            t = t1;
        }

        public new String toString()
        {
            return toStringIndented("");
        }

        public new String toStringIndented(String indent)
        {
            return indent + "Declaration(" + v + ", " + t + ")";
        }
    }

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37718274
Since you created a single constructor which takes parameters, you have overridden the implicit default constructor that the compiler creates for you. You need to provide a default constructor for the Declaration class, and you need to invoke from the derived class. This is as simple as adding this to your Declaration class:

public Declaration() { }

Open in new window


...and modifying your VariableDecl class' constructor to:

public VariableDecl(Variable v1, Type t1) : base()
{
    v = v1;
    t = t1;
}

Open in new window

0
 

Author Comment

by:crazy4s
ID: 37722561
so i need two constructor for the base class and the derived class?
hmm sorry i'm abit confused, but can you explain in more details why do i need to split to two different constructors?

        public VariableDecl(List<Declaration> Declarations)
            : base(Declarations)
        {

        }

        public VariableDecl(Variable v1, Type t1)
            : base()
        {
            v = v1;
            t = t1;
        }

Open in new window

0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 500 total points
ID: 37722626
Sure. When you create a class, if you did nothing more than this:

public class MyClass { }

Open in new window


...you get a constructor for free (i.e. you don't have type anything). This is the default, parameterless constructor:

e.g.

MyClass c = new MyClass();

Open in new window


When you create any single constructor within your class:

e.g.

public class MyClass
{
    public MyClass(string someParameter)
    {

    }
}

Open in new window


...then you effectively erase the free constructor you got before. In order to get back that parameterless constructor, you have to add it yourself:

e.g.

public class MyClass
{
    public MyClass(string someParameter)
    {

    }

    public MyClass()
    {

    }
}

Open in new window


The reason you received the error earlier is because you "erased" the default constructor in Declaration when you created just a single constructor:

public Declaration(List<Declaration> Declarations)
{
    this.decl = Declarations;
}

Open in new window


This means that the only available base constructor a derived class could invoke is this constructor. Now, in VariableDecl, you created two constructors:

public VariableDecl(List<Declaration> Declarations)
    : base(Declarations)
{

}

public VariableDecl(Variable v1, Type t1) <-- error????
{
    v = v1;
    t = t1;
}

Open in new window


The top constructor is fine because you explicitly invoked the base class' constructor which takes one parameter of type List<Declaration> (which is the only constructor defined by the base class since you "erased" the default constructor and you didn't explicitly add it back). The problem with the bottom constructor is that you didn't explicitly invoke a base class constructor, and by default the compiler will try to locate the default base class constructor--the one you "erased". Since the compiler cannot find that constructor, you get the error. My suggestion earlier ( http:#a37718274 ) explicitly defined (added back) the default constructor for the base class, and so the compiler could then find an implementation of the default constructor, and the error goes away. (In hindsight, you don't need to do what I mentioned for the VariableDecl constructor above [ http:#questionCommentsViewInlineCode20-37718274-2 ], but it doesn't hurt anything to do so.)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Refresh Datagridview from another form 1 28
C# SQL BULK INSERT CLASS 5 35
Image(2) 3 26
Web Reply Form - PHP with Upload 4 14
JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Envision that you are chipping away at another e-business site with a team of pundit developers and designers. Everything seems, by all accounts, to be going easily.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now