So the assignment for this class is to code a recursive descent parser. I got the parser to detect errors in bad files and then output the errors. Now I need to set and print but I am struggling. I have to put in code the professor gave us but
I am getting this error.
Line 65 : no matching function for call to 'Value::Value()' return Value();
It also repeats on line 122.
This is my header file.
<code>/*
* ParseNode.h
*
* Created on: Apr 2, 2017
* Author: gerardryan
*/
#ifndef PARSENODE_H_
#define PARSENODE_H_
using namespace std;
#include<vector>
#include <iostream>
#include <string>
#include<map>
using std::istream;
using std::cout;
using std::endl;
using std::string;
#include "polylex.h"
extern int globalErrorCount;
// objects in the language have one of these types
enum Type {
INTEGERVAL,
FLOATVAL,
STRINGVAL,
UNKNOWNVAL,
};
// this class will be used in the future to hold results of evaluations
class Value {
int i;
float f;
string s;
Type t;
public:
Value(int i) : i(i), f(0), t(INTEGERVAL) {}
Value(float f) : i(0), f(f), t(FLOATVAL) {}
Value(string s) : i(0), f(0), s(s), t(STRINGVAL) {}
Type GetType() { return t; }
int GetIntValue();
float GetFloatValue();
string GetStringValue();
};
// every node in the parse tree is going to be a subclass of this node
class ParseNode {
// a list of statements is represented by a statement to the left, and a list of statments to the right
class StatementList : public ParseNode {
public:
StatementList(ParseNode *l, ParseNode *r) : ParseNode(l,r) {}
};
// a SetStatement represents the idea of setting id to the value of the Expr pointed to by the left node
class SetStatement : public ParseNode {
string id;
public:
SetStatement(string id, ParseNode* exp) : id(id), ParseNode(exp) {}
// a PrintStatement represents the idea of printing the value of the Expr pointed to by the left node
class PrintStatement : public ParseNode {
public:
PrintStatement(ParseNode* exp) : ParseNode(exp) {}
};
// represents adding, or subtracting, the two child expressions
class MinusOp : public ParseNode {
public:
MinusOp(ParseNode *l, ParseNode *r) : ParseNode(l,r) {}
};
class PlusOp : public ParseNode {
public:
PlusOp(ParseNode *l, ParseNode *r) : ParseNode(l,r) {}
Value Eval(map<string,Value>& symb) {
Value op1 = left->Eval(symb);
Value op2 = right->Eval(symb);
return Value();
}
};
// represents multiplying the two child expressions
class TimesOp : public ParseNode {
public:
TimesOp(ParseNode *l, ParseNode *r) : ParseNode(l,r) {}
};
class Join : public ParseNode {
public:
Join(ParseNode *l, ParseNode *r) : ParseNode(l,r) {}
};
// a representation of a list of coefficients must be developed
class Coefficients : public ParseNode {
vector <ParseNode *> coeffs;
public:
Coefficients(vector <ParseNode *> coeffs) : coeffs(coeffs), ParseNode() {}
};
// leaves of the parse tree
// notice that the parent constructors take no arguments
// that means this is a leaf
class Iconst : public ParseNode {
int iValue;
public:
Iconst(int iValue) : iValue(iValue), ParseNode() {}
Type GetType() { return INTEGERVAL; }
Value Eval(map<string,Value>& symb) {
return Value(iValue);
}
};
class Fconst : public ParseNode {
float fValue;
public:
Fconst(float fValue) : fValue(fValue), ParseNode() {}
Type GetType() { return FLOATVAL; }
};
class Sconst : public ParseNode {
string sValue;
public:
Sconst(string sValue) : sValue(sValue), ParseNode() {}
Type GetType() { return STRINGVAL; }
};
class Ident : public ParseNode {
string id;
public:
Ident(string id) : id(id), ParseNode() {}
void RunStaticChecks(map<string,bool>& idMap) {
if( idMap[id] == false ) {
cout << ("Identifier used before set");
}
}
//Type GetType(); // not known until run time!
};
if (eval == 0)
{
//cout << tok.getLexeme() << endl;
return new Ident(tok.getLexeme());
}
else
{
return eval;
}
}
// note EvalAt is optional
return 0;
}
// notice we don't need a separate rule for ICONST | FCONST
// this rule checks for a list of length at least one
ParseNode *Coeffs(istream& in)
{
vector <ParseNode *> coeffs;
ParseNode *p = GetOneCoeff(in);
if (p == 0)
return 0;
coeffs.push_back(p);
while(true)
{
Token t = GetToken(in);
if (t != COMMA)
{
PutBackToken(t);
break;
}
p = GetOneCoeff(in);
if (p == 0)
{
error("Missing coefficient after comma");
return 0;
}
coeffs.push_back(p);
}
return new Coefficients(coeffs);
}
Line 65 : no matching function for call to 'Value::Value()' return Value();
It also repeats on line 122.
That is because you have no default constructor for Value.
Could not compile your program because you did not post polylex.h.
Please use code tags correctly. Code tags use square brackets [], not angle brackets <>. http://www.cplusplus.com/articles/jEywvCM9/
Hint: You can edit your post, highlight your code and press the <> formatting button.
Generally, you want to separate the functions of the tokeniser (also called a lexer) from other stages of your compiler or interpreter. The reason for this is basic modularity: each pass consumes one kind of thing (e.g., characters) and produces another one (e.g., tokens).
So you’ve converted your characters to tokens. Now you want to convert your flat list of tokens to meaningful nested expressions, and this is what is conventionally called parsing. For a JavaScript-like language, you should look into recursive descent parsing. For parsing expressions with infix operators of different precedence levels, Pratt parsing is very useful, and you can fall back on ordinary recursive descent parsing for special cases.
To learn more, find best online programming courses here: https://hackr.io/
Just to give you a more concrete example based on your case, I’ll assume you can write two functions: accept(token) and expect(token), which test the next token in the stream you’ve created. You’ll make a function for each type of statement or expression in the grammar of your language. Here’s Pythonish pseudocode for a statement() function, for instance:
def statement():
if accept("if"):
x = expression()
y = statement()
return IfStatement(x, y)
elif accept("return"):
x = expression()
return ReturnStatement(x)
elif accept("{")
xs = []
while True:
xs.append(statement())
if not accept(";"):
break
expect("}")
return Block(xs)
else:
error("Invalid statement!")
This gives you what’s called an abstract syntax tree (AST) of your program, which you can then manipulate (optimisation and analysis), output (compilation), or run (interpretation).