Search code examples
c++constructorifstream

C++ error C2512 trying to use ifstream to read a file in a class, visual studio 2008


I admittedly am an extreme C++ novice, so please forgive me for my probably very naive question.

I am writing code that should parse an assembly language file in its fundamental parts, to be translated into machine language at a second stage.

I have built a parser class, but I am not having success in opening the external assembly .asm textfile, and in feeding it to the various functions that compose my parser class.

More in particular, there are problems with the constructor. I attach the full code I wrote below:

// parses .asm assembly files
#include <iostream>
#include <fstream>
#include <varargs.h>
#include <string>
using namespace std;

class parser
{
private:
    istream inputfile;
    char inputname[30];
    string line;
    bool endfile;
    bool a_command, l_command, c_command; 
    string parsedLine, destParsedLine, compParsedLine, jumpParsedLine;
public:
    // default parser constructor
    parser()
    {
    }

    //parser(char* argv[])
    //{
    //  reader(argv[]);
    //}

    // opens input file
    string reader(char* argv[])
    {
        strcpy(inputname,argv[1]);
        strcat(inputname,".asm");
        // opens input .asm file
        ifstream inputfile(inputname);
        // reads first line
        getline(inputfile,line);
        if (line[0] == '/' || line.empty())
            inputfile.ignore(line.length(),'\n');
        return line;
    }

    // checks if at end file
    bool hasMoreCommands()
    {
        a_command = false;
        l_command = false;
        c_command = false;
        endfile = false;
        if (inputfile.eof())
            endfile = true;         
        return endfile;
    }

    // advances read of inputfile
    void advance()
    {
        if (line[0] == '/' || line.length() == 0)
            inputfile.ignore(line.length(),'\n');
        getline(inputfile,line);
    }

    /* function for labelling the type of command (address,computation,label) */
    bool commandType()
    {
        if (line[0] == '@')
            a_command = true;
        else if (line[0] == '(')
            l_command = true;
        else
            c_command = true;
        return a_command, l_command, c_command;
    }

    // function to select parsing function
    string selector()
    {
        if (a_command || l_command)
            symbol();
        else if (c_command)
        {
            dest();
            comp();
            jump();
            string parsedLine = destParsedLine + compParsedLine + jumpParsedLine;
        }
        return parsedLine;
    }

    // function returning address or label symbol
    string symbol()
    {
        if (a_command)
            string parsedLine = line.substr(1);
        else if (l_command)
            string parsedLine = line.substr(1,line.length()-1);
        return parsedLine;
    }

    // functions returning computation destination
    string dest()
    {
        size_t equal = line.find('='); //no '=' found = returns 'npos'
        string destParsedLine = line.substr(0,equal);
        return destParsedLine;
    }
    string comp()
    {
        size_t equal = line.find('=');
        size_t semicolon = line.find(';');
        string compParsedLine = line.substr(equal,semicolon);
        return compParsedLine;
    }
    string jump()
    {
        size_t semicolon = line.find(';');
        string jumpParsedLine = line.substr(semicolon);
        return jumpParsedLine;
    }
};

// main program
int main (int argc, char *argv[])
{
    bool endfile = false;
    string parsedLine;
    int count = 0;

    if ((argc != 2) || (strchr(argv[1],'.') != NULL))
    {
        cout << argv[0] << ": assembly .asm file argument should be supplied, without .asm extension\n";
        return 1;
    }

    parser attempt1 = parser();
    attempt1.reader(argv[]);
    while (!endfile)
    {
        attempt1.hasMoreCommands();
        if (endfile)
            return 0;
        if (count > 0)
            attempt1.advance();
        attempt1.commandType();
        attempt1.selector();
        cout << parsedLine << endl; //debugging purposes
        count++;
    }
}

I provide the name of the .asm textfile to be opened, from the command line (.asm file located in the same folder of this cpp file).

Hence I need to use varargs.h which I suppose may be part of the problem.

When I try to build this, visual studio 2008 gives me the following 2 errors:

1 error C2512: 'std::basic_istream<_Elem,_Traits>' : no appropriate default constructor available line 21

2 error C2059: syntax error : ']' line 137

Help appreciated, and insults tolerated, thanks :)


Solution

  • Following @Remy Lebeau suggestions, the modified code below at least compiles correctly (still does not do what it is supposed to do though)

    // parses .asm assembly files
    #include <iostream>
    #include <fstream>
    #include <varargs.h>
    #include <string>
    using namespace std;
    
    class parser
    {
    private:
        istream inputfile;
        char inputname[30];
        string line;
        bool endfile;
        bool a_command, l_command, c_command; 
        string parsedLine, destParsedLine, compParsedLine, jumpParsedLine;
    public:
        // default parser constructor
        parser()
        {
        }
    
        // ignores inputfile line if comment or empty
        void ignoreline()
        {
            if (line[0] == '/' || line.empty())
                inputfile.ignore(line.length(),'\n');
        }
    
        // composes inputfile name and opens input file
        void reader(char* argv[])
        {
            strcpy(inputname,argv[1]);
            strcat(inputname,".asm");
            // opens input .asm file
            inputfile.open(inputname, fstream::in);
            // reads first line
            getline(inputfile,line);
            ignoreline();
        }
    
        // checks if at end file
        bool hasMoreCommands()
        {
            a_command = false;
            l_command = false;
            c_command = false;
            endfile = false;
            if (inputfile.eof())
                endfile = true;         
            return endfile;
        }
    
        // advances read of inputfile
        void advance()
        {
            ignoreline();
            getline(inputfile,line);
        }
    
        /* function for labelling the type of command (address,computation,label) */
        bool commandType()
        {
            if (line[0] == '@')
                a_command = true;
            else if (line[0] == '(')
                l_command = true;
            else
                c_command = true;
            return a_command, l_command, c_command;
        }
    
        // function to select parsing function
        string selector()
        {
            if (a_command || l_command)
                symbol();
            else if (c_command)
            {
                dest();
                comp();
                jump();
                string parsedLine = destParsedLine + compParsedLine + jumpParsedLine;
            }
            return parsedLine;
        }
    
        // function returning address or label symbol
        string symbol()
        {
            if (a_command)
                string parsedLine = line.substr(1);
            else if (l_command)
                string parsedLine = line.substr(1,line.length()-1);
            return parsedLine;
        }
    
        // functions returning computation destination
        string dest()
        {
            size_t equal = line.find('='); //no '=' found = returns 'npos'
            string destParsedLine = line.substr(0,equal);
            return destParsedLine;
        }
    
        string comp()
        {
            size_t equal = line.find('=');
            size_t semicolon = line.find(';');
            string compParsedLine = line.substr(equal,semicolon);
            return compParsedLine;
        }
    
        string jump()
        {
            size_t semicolon = line.find(';');
            string jumpParsedLine = line.substr(semicolon);
            return jumpParsedLine;
        }
    };
    
    // main program
    int main (int argc, char *argv[])
    {
        bool endfile = false;
        string parsedLine;
        int count = 0;
    
        if ((argc != 2) || (strchr(argv[1],'.') != NULL))
        {
             cout << argv[0] << ": assembly .asm file argument should be supplied, without .asm extension\n";
            return 1;
        }
    
        parser attempt1 = parser();
        attempt1.reader(argv);
        while (!endfile)
        {
            attempt1.hasMoreCommands();
            if (endfile)
                return 0;
            if (count > 0)
                attempt1.advance();
            attempt1.commandType();
            attempt1.selector();
            cout << parsedLine << endl;
            count++;
        }
        return 0;
    }