面向对象版表达式(十)

FunctionTable实现

让表达式计算器支持函数运算


对于一个好的科学计算器,内置函数是必需的。计算器必须能计算平方根、对数、三角函数等等。因而我们要让解析器识别这些函数,并调用适当的数学库函数。


FunctionTable实现


FunctionTable.h:

#ifndef _FUNCTION_TABLE_H_
#define _FUNCTION_TABLE_H_

class SymbolTable;

typedef double (*PtrFun)(double);

class FunctionTable
{
public:
	FunctionTable(SymbolTable& tbl);
	~FunctionTable();

	void Init(SymbolTable& tbl);
	unsigned int Size() const
	{
		return size_;
	}

	PtrFun GetFunction(unsigned int id) const
	{
		return pFuns_[id];
	}

private:
	PtrFun* pFuns_;
	unsigned int size_;
};

#endif // _FUNCTION_TABLE_H_

FunctionTable.cpp:

#include "FunctionTable.h"
#include "SymbolTable.h"
#include <cmath>
#include <cassert>
#include <iostream>

struct FunctionEntry
{
	PtrFun pFun_;
	char* funName_;
};

FunctionEntry Entrys[] =
{
	log,	"log",
	log10,	"log10",
	exp,	"exp",
	sqrt,	"sqrt",
	sin,	"sin",
	cos,	"cos",
	tan,	"tan",
	sinh,	"sinh",
	cosh,	"cosh",
	tanh,	"tanh",
	asin,	"asin",
	acos,	"acos",
	atan,	"atan"
};

FunctionTable::FunctionTable(SymbolTable& tbl)
	: size_(sizeof(Entrys) / sizeof(Entrys[0]))
{
	Init(tbl);
}

void FunctionTable::Init(SymbolTable& tbl)
{
	std::cout<<"function list:"<<std::endl;
	pFuns_ = new PtrFun[size_];
	for (unsigned int i=0; i<size_; ++i)
	{
		pFuns_[i] = Entrys[i].pFun_;
		unsigned int j = tbl.Add(Entrys[i].funName_);
		assert(i == j);
		std::cout<<Entrys[i].funName_<<std::endl;
	}
}

FunctionTable::~FunctionTable()
{
	delete[] pFuns_;
}

在Calc中要增加新的成员变量FunctionTable    记得初始化的顺序,让符号表先初始化  然后再初始化函数表  最后初始化存储表

Calc.h:

#ifndef _CALC_H_
#define _CALC_H_

#include "SymbolTable.h"
#include "Storage.h"
#include "FunctionTable.h"
#include <string>

class Parser;

class Calc
{
	friend class Parser;
public:
	Calc() : funTbl_(symTbl_), storage_(symTbl_) {}
private:
	Storage& GetStorage()
	{
		return storage_;
	}
	PtrFun GetFunction(unsigned int id) const
	{
		return funTbl_.GetFunction(id);
	}
	bool IsFunction(unsigned int id) const
	{
		return id < funTbl_.Size();
	}
	unsigned int AddSymbol(const std::string& str);
	unsigned int FindSymbol(const std::string& str) const;
	SymbolTable symTbl_;
	FunctionTable funTbl_;
	Storage storage_;
};

#endif // _CALC_H_

Calc.cpp

#include "Calc.h"

unsigned int Calc::FindSymbol(const std::string& str) const
{
	return symTbl_.Find(str);
}

unsigned int Calc::AddSymbol(const std::string& str)
{
	return symTbl_.Add(str);
}



在Node.h中要多增加一个一元运算节点

class FunctionNode : public UnaryNode
{
public:
	FunctionNode(Node* child, PtrFun pFun)
		: UnaryNode(child), pFun_(pFun) {}

	double Calc() const;
private:
	PtrFun pFun_;
};
Node.cpp

double FunctionNode::Calc() const
{
	return (*pFun_)(child_->Calc());
}


在Parser.cpp中对Factor的更改:


		if (scanner_.Token() == TOKEN_LPARENTHESIS)		// function call
		{
			scanner_.Accept();		// accept '('
			node = Expr();
			if (scanner_.Token() == TOKEN_RPARENTHESIS)
			{
				scanner_.Accept();	// accept ')'
				if (id != SymbolTable::IDNOTFOUND && calc_.IsFunction(id))
				{
					node = new FunctionNode(node, calc_.GetFunction(id));
				}
				else
				{
					status_ = STATUS_ERROR;
					std::cout<<"Unknown function "<<"\""<<symbol<<"\""<<std::endl;
				}

			}
			else
			{
				status_ = STATUS_ERROR;
				std::cout<<"Missing parenthesis in a function call."<<std::endl;
			}


		}
		else
		{
			if (id == SymbolTable::IDNOTFOUND)
			{
				id = calc_.AddSymbol(symbol);
			}
			node = new VariableNode(id, calc_.GetStorage());
		}
		
	






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值