对于我的作业,我们正在根据下面的语法规则创建一个递归下降解析器:
Prog ::= StmtList StmtList ::= { Stmt T_SC } { StmtList } Stmt ::= Decl | Set | Print Decl ::= T_INT T_ID | T_STRING T_ID Set ::= T_SET T_ID Expr Print ::= T_PRINT Expr | T_PRINTLN Expr Expr ::= Term { (T_PLUS|T_MINUS) Expr } Term ::= Primary { (T_STAR|T_SLASH) Term } Primary ::= T_ICONST | T_SCONST | T_ID | T_LPAREN Expr T_RPAREN
我的问题是,我目前正在研究Parsetree的Decl函数,我坚持如何在我的头文件中创建一个可以识别标识符的类。我只是想知道如何为Decl函数创建一个类。就这些。如果你打算回答我的问题,请向我解释为什么我可以学习和实施。我在头文件下面只包含了parse.cpp文件中的Decl函数。
ParseTree * Decl(istream* in) { // Needs Fixing
//Decl ::= T_INT T_ID | T_STRING T_ID
Token tok1 = ParserToken.getToken(in);
cout << "token in Decl: " << tok1 << endl;
if(tok1 == T_INT)
{
Token tok2 = ParserToken.getToken(in);
if(tok2 != T_ID)
{
error(tok2.GetLinenum(), "Identifier Required");
return 0;
}
return new Declare(tok1.GetLinenum(), "T_INT",0);
}
else if(tok1 == T_STRING)
{
Token tok3 = ParserToken.getToken(in);
if(tok3 != T_ID)
{
error(tok3.GetLinenum(), "Identifier Required");
return 0;
}
return new Declare(tok1.GetLinenum(), "T_STRING", 0);
}
else
ParserToken.pushbackToken(tok1);
return 0;
}
标题文件
#ifndef PARSER_H_
#define PARSER_H_
#include <iostream>
using std::istream;
#include <string>
using std::string;
using std::stoi;
#include "lexer.h"
extern void error(int linenum, const string& message);
extern int idcount, setcount, mcount, pcount;
enum TypeForNode { INT_TYPE, STRING_TYPE, ERROR_TYPE };
class ParseTree {
int linenumber;
ParseTree *left;
ParseTree *right;
public:
ParseTree(int n, ParseTree *l = 0, ParseTree *r = 0) : linenumber(n), left(l), right(r) {}
virtual ~ParseTree() {}
ParseTree* getLeft() const { return left; }
ParseTree* getRight() const { return right; }
int getLineNumber() const { return linenumber; }
virtual TypeForNode GetType() const { return ERROR_TYPE; }
virtual int GetIntValue() const { throw "no integer value"; }
virtual string GetStringValue() const { throw "no string value"; }
};
class StatementList : public ParseTree {
public:
StatementList(ParseTree *first, ParseTree *rest) : ParseTree(0, first, rest) {}
};
class Addition : public ParseTree {
public:
Addition(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
};
class Subtraction : public ParseTree {
public:
Subtraction(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
// will need to fill in type and value;
// remember type is a function of
};
class Multiplication : public ParseTree {
public:
Multiplication(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
// will need to fill in type and value;
// remember type is a function of
};
class Division : public ParseTree {
public:
Division(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
// will need to fill in type and value;
// remember type is a function of
};
class PrintStatement : public ParseTree {
public:
PrintStatement(int line, ParseTree *op1) : ParseTree(line, op1, 0){}
};
class Declare : public ParseTree { //This is where I'm having trouble
string id;
public:
Declare(int line, ParseTree *op1) : ParseTree(line, op1, 0){
TypeForNode GetType() const { return STRING_TYPE; }
string GetStringValue() const { return id; }
}
};
class StringConstant : public ParseTree {
string value;
public:
StringConstant(const Token& tok) : ParseTree(tok.GetLinenum()) {
value = stoi( tok.GetLexeme() );
}
TypeForNode GetType() const { return STRING_TYPE; }
string GetStringValue() const { return value; }
};
class IntegerConstant : public ParseTree {
int value;
public:
IntegerConstant(const Token& tok) : ParseTree(tok.GetLinenum()) {
value = stoi( tok.GetLexeme() );
}
TypeForNode GetType() const { return INT_TYPE; }
int GetIntValue() const { return value; }
};
extern ParseTree * Prog(istream* in);
extern ParseTree * StmtList(istream* in);
extern ParseTree * Stmt(istream* in);
extern ParseTree * Decl(istream* in);
extern ParseTree * Set(istream* in);
extern ParseTree * Print(istream* in);
extern ParseTree * Expr(istream* in);
extern ParseTree * Term(istream* in);
extern ParseTree * Primary(istream* in);
#endif /* PARSER_H_ */
这些是我收到的错误,这些错误都围绕着相同的行。
arser.h: In constructor ‘Declare::Declare(int, ParseTree*)’:
parser.h:85:32: error: a function-definition is not allowed here before ‘{’ token
TypeForNode GetType() const { return STRING_TYPE; }
^
parser.h:86:34: error: a function-definition is not allowed here before ‘{’ token
string GetStringValue() const { return id; }
^
In file included from parser.cpp:9:0:
parser.h: In constructor ‘Declare::Declare(int, ParseTree*)’:
parser.h:85:32: error: a function-definition is not allowed here before ‘{’ token
TypeForNode GetType() const { return STRING_TYPE; }
^
parser.h:86:34: error: a function-definition is not allowed here before ‘{’ token
string GetStringValue() const { return id; }
^
parser.cpp: In function ‘ParseTree* Decl(std::istream*)’:
parser.cpp:84:57: error: no matching function for call to ‘Declare::Declare(int, const char [6], int)’
return new Declare(tok1.GetLinenum(), "T_INT",0);
^
In file included from parser.cpp:9:0:
parser.h:84:4: note: candidate: Declare::Declare(int, ParseTree*)
Declare(int line, ParseTree *op1) : ParseTree(line, op1, 0){
^
parser.h:84:4: note: candidate expects 2 arguments, 3 provided
parser.h:81:7: note: candidate: Declare::Declare(const Declare&)
class Declare : public ParseTree {
^
parser.h:81:7: note: candidate expects 1 argument, 3 provided
parser.h:81:7: note: candidate: Declare::Declare(Declare&&)
parser.h:81:7: note: candidate expects 1 argument, 3 provided
parser.cpp:94:61: error: no matching function for call to ‘Declare::Declare(int, const char [9], int)’
return new Declare(tok1.GetLinenum(), "T_STRING", 0);
^