实现PARSER类
其实就是对输入串的一个分析,基于扫描器的基础之上
类图:
表达式:
Expression is Term + Expression
or Term - Expression
or Term = Expression
or just Term
项:
Term is Factor * Term
or Factor / Term
or just Factor
因子:
Factor is Number
or -Factor
Or (Expression)
Parser.h:
#ifndef _PARSER_H_
#define _PARSER_H_
class Scanner;
class Node;
enum STATUS
{
STATUS_OK,
STATUS_ERROR,
STATUS_QUIT
};
class Parser
{
public:
Parser(Scanner& scanner);
void Parse();
Node* Expr();
Node* Term();
Node* Factor();
double Calculate() const;
private:
Scanner& scanner_;
Node* tree_;
STATUS status_;
};
#endif // _PARSER_H_
Parser.cpp:
#include "Parser.h"
#include "Scanner.h"
#include "Node.h"
#include <cassert>
#include <iostream>
Parser::Parser(Scanner& scanner) : scanner_(scanner), tree_(0)
{
}
void Parser::Parse()
{
tree_ = Expr();
}
Node* Parser::Expr()
{
Node* node = Term();
EToken token = scanner_.Token();
if (token == TOKEN_PLUS)
{
//Accept的意思->扫描下一个单元
scanner_.Accept();
Node* nodeRight = Expr();
node = new AddNode(node, nodeRight);
}
else if (token == TOKEN_MINUS)
{
scanner_.Accept();
Node* nodeRight = Expr();
node = new SubNode(node, nodeRight);
}
return node;
}
Node* Parser::Term()
{
Node* node = Factor();
EToken token = scanner_.Token();
if (token == TOKEN_MULTIPLY)
{
scanner_.Accept();
Node* nodeRight = Term();
node = new MultiplyNode(node, nodeRight);
}
else if (token == TOKEN_DIVIDE)
{
scanner_.Accept();
Node* nodeRight = Term();
node = new DivideNode(node, nodeRight);
}
return node;
}
Node* Parser::Factor()
{
Node* node = 0;
EToken token = scanner_.Token();
if (token == TOKEN_LPARENTHESIS)
{
scanner_.Accept(); // accept '('
node = Expr();
if (scanner_.Token() == TOKEN_RPARENTHESIS)
{
scanner_.Accept(); // accept ')'
}
else
{
status_ = STATUS_ERROR;
// Todo:抛出异常
std::cout<<"missing parenthesis"<<std::endl;
node = 0;
}
}
else if (token == TOKEN_NUMBER)
{
node = new NumberNode(scanner_.Number());
scanner_.Accept();
}
else if (token == TOKEN_MINUS)
{
scanner_.Accept(); // accept minus
node = new UMinusNode(Factor());
}
else
{
status_ = STATUS_ERROR;
// Todo:抛出异常
std::cout<<"not a valid expression"<<std::endl;
node = 0;
}
return node;
}
double Parser::Calculate() const
{
assert(tree_ != 0);
return tree_->Calc();
}