`
kennethf6986
  • 浏览: 69279 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个简单的计算器程序

阅读更多
const char number = '8';
const char quit = 'q';
const char print = ';';

const string prompt = ">";
const string result = "=";

const char name = 'a';
const char let = 'L';
const string declkey = "let";


//定义单词
class Token{
public:
	char kind;
	double value;
	string name;

	Token(char ch)
		:kind(ch),value(0){}
	Token(char ch, double val)
		:kind(ch), value(val){}
	Token(char ch, string n): kind(ch),name(n){}
};

//单词流
class Token_stream{
public:
	Token_stream();
	Token get();
	void putback(Token t);
	void ignore(char c);

private:
	bool full;
	Token buffer;
};

//定义单词流的构造函数
Token_stream::Token_stream()
:full(false),buffer(0){}

//
void Token_stream::putback(Token t)
{
	if(full) error("putback() into a full buffer()");
	full = true;
	buffer = t;
}

//得到一个单词
Token  Token_stream::get()
{
	if(full){  //如果单词流中已经有一个单词
		full = false;
		return buffer;
	}

	char ch;
	cin>>ch;

	switch(ch) {
	case print:
	case quit:
	//处理云算法,数字分组符号
	case '(': case ')': case '{': case '}': case '+':
	case '-': case '*': case '/': case '!': case '%': 
    //处理 let ×× = 的情况
	case '=':
		return Token(ch);
	//处理数字
	case '.':
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
		{
			cin.putback(ch);
			double val;
			cin>>val;
			return Token(number,val);

		}
	default: 
		//处理变量
		if(isalpha(ch)) {
			string s;
			s += ch;
			while( cin.get(ch) && (isalpha(ch) || (isdigit(ch) ))) s+=ch;
			cin.putback(ch);
			if(s == declkey)
				return Token(let); //返回表示let的单词
			return Token(name, s); //返回表示变量的单词
		}
		error("Bad token");
		}
}

void Token_stream::ignore(char c)
{
	if(full && buffer.kind == c)
	{
		full = false;
		return ;
	}
	full = false;

	char ch = 0;
	while(cin>>ch)
	{
		if(ch == c) return;
	}
}

//定义variable类
class Variable
{
public:
	string name;
	double value;
	Variable(string n, double v):name(n),value(v){}
};

//定义variable向量
vector<Variable> var_table;

//return the value of the Variable named s
double get_value(string s)
{
	for(int i=0; i<var_table.size(); i++)
		if(var_table[i].name == s) return var_table[i].value;
	error("get: undefined variable ",s);
}

//set the Variable named s to d
void set_value(string s, double d)
{
	for(int i=0; i<var_table.size(); i++)
		if(var_table[i].name == s)
		{
			var_table[i].value = d;
			return ;
		}
	error("get: undefined variable ",s);
}

//判断变量var是否已经存在
bool is_declared(string var)
{
	for(int i=0; i<var_table.size(); i++)
		if(var_table[i].name == var) return true;
	return false;
}

//新加入一个初始化的变量
double define_name(string var, double val)
{
	if(is_declared(var) ) error(var,"declared twice");
	var_table.push_back(Variable(var, val));
	return val;
}


Token_stream ts;

double expression();

//定义primary规则
double primary()
{
	Token t = ts.get();
	switch(t.kind) {
	case '(':
		{
			double d = expression();
			t = ts.get();
			if(t.kind !=')') error("')' expected");
			return d;
		}
	case '{':
		{
			double d = expression();
			t = ts.get();
			if(t.kind !='}') error("'}' expected");
			return d;
		}
	case number:
		return t.value;
	case '+':
		return primary();
	case '-':
		return -primary();
	case name:
		return get_value(t.name);
	default:
		error("primary expected");
	}
}

//处理阶乘
double factorial()
{
	double left = primary();

	double ff = left;
	Token t = ts.get();
	//处理阶乘
	if(t.kind =='!')
	{
		if(left == 0) left = 1;
		
		if(left > 0)
		{
			for(int i=1; i<left; ++i)
				ff*=(left-i);
		}
	}else{
		ts.putback(t);
	}
	return ff;
}



double term()
{
	double left = factorial();
	Token t = ts.get();

	while(true) {
		switch (t.kind){
		case '*' :
			left *= factorial();
			t = ts.get();
			break;
		case '/':
			{
				double d = factorial();
				if(d==0) error("divide by zero");
				left/=d;
				t = ts.get();
				break;
			}
		case '%':
			{
				int i1 = narrow_cast<int>(left);
				int i2 = narrow_cast<int>(factorial() );
				if(i2 == 0) error("%: divide by zero");
				left = i1%i2;
				t = ts.get();
				break;
			}
		default:
			ts.putback(t);
			return left;
		}
	}
}

double expression()
{
	double left = term();
	Token t = ts.get();

	while(true)
	{
		switch(t.kind)
		{
		case '+':
			left += term();
			t = ts.get();
			break;
		case '-':
			left -= term();
			t = ts.get();
			break;
		default:
			ts.putback(t);
			return left;
		}
	}
}

double declaration()
{
	Token t = ts.get();
	if(t.kind != name) error("name expected in declaration");
	string var_name = t.name;

	Token t2 = ts.get();
	if(t2.kind != '=') error("= missing in declaration of ", var_name);

	double d = expression();
	
	define_name(var_name, d );
	return d;
}

double statement()
{
	Token t = ts.get();
	switch (t.kind) {
	case let:
		return declaration();
	default :
		ts.putback(t);
		return expression();
	}
}


void clean_up_mess();

void calculate()
{
	while(cin)
	{
		try{
			cout<<prompt;
			Token t = ts.get();
			while(t.kind == print) t = ts.get();

			if(t.kind == quit)
			{
				return;
			}
			ts.putback(t);
			cout<< result <<statement()<<endl;
		}catch(exception&e)
		{
			cerr<<e.what()<<endl;
			clean_up_mess();
		}
	}
}

void clean_up_mess()
{
	ts.ignore(print);
}




int  main()
{
	try{
		define_name("pi", 3.1415926535);
		define_name("e", 2.7182818284);
		calculate();
		keep_window_open();
		return 0;

	}catch(runtime_error& e )
	{
		cerr<<e.what()<<endl;
		keep_window_open("~~");
		return 1;
	}catch(...)
	{
		cerr<<"exception\n";
		keep_window_open("~~");
		return 2;
	}
}
分享到:
评论

相关推荐

    一个简单计算器程序-基于对话框.doc

    该资源是一篇关于使用 MFC 开发一个简单科学计算器程序的教程,通过创建一个基于对话框的应用程序,实现了加、减、乘、除四个基本功能,并在此基础上扩展了平方、开方、三角函数等功能。 知识点一:MFC 基础知识 *...

    用VC编写的一个简单计算器程序

    【标题】"用VC编写的一个简单计算器程序"指的是使用Visual C++(简称VC)开发的简易版计算应用程序。Visual C++是微软公司推出的一种集成开发环境,它支持C++语言,同时也提供了MFC(Microsoft Foundation Classes)...

    基于labview的简单计算器程序

    在本案例中,我们讨论的是一个基于LabVIEW 2020编写的简单计算器程序。 首先,让我们深入理解LabVIEW编程的基本概念。LabVIEW中的主要编程元素是“VI”(Virtual Instrument,虚拟仪器),它由前面板和程序框图两...

    一个简易的计算器程序

    总的来说,使用MFC创建一个简易计算器程序涉及到GUI设计、事件处理、计算逻辑实现等多个方面,这对于理解和掌握MFC的使用非常有帮助。通过这个过程,开发者不仅可以加深对C++面向对象编程的理解,还能学习到Windows ...

    微信小程序 简易计算器 (源码)

    微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信小程序 简易计算器 (源码)微信...

    用C语言编简单计算器程序

    综上所述,上述代码示例展示了如何利用C语言实现一个基本的计算器程序,涵盖了变量声明、输入处理、条件判断与执行等关键环节,并提供了错误处理机制。这不仅是一次对C语言基础知识的应用练习,也为后续学习和项目...

    C语言一个简易计算器程序

    用C语言代码编写的一个简易计算器,可以实现加减乘除的功能!

    图形用户编程.编写一个简单的计算器程序,要求有菜单,能进行简单的加减乘除运算。

    在本文中,我们将探讨如何使用Java的图形用户界面(GUI)编程技术来创建一个简单的计算器程序。这个程序将具有菜单功能,并能够执行基本的加、减、乘、除运算。我们将使用Java Swing库来构建界面,并通过事件处理...

    Java版简易计算器程序设计

    ### Java版简易计算器程序设计知识点解析 #### 一、项目概述 本项目为一个简易计算器的设计与实现,采用Java语言开发。该计算器具备基本的算术运算功能,并且集成了记忆存储功能,能够满足日常计算的基本需求。项目...

    51单片机简易计算器程序

    从描述“绝对正确的51单片机简易计算器程序”可以看出,该程序是一个可靠的简易计算器程序,使用了多个头文件,包括`reg52.h`、`intrins.h`、`string.h`和`math.h`等,旨在实现基本的计算器功能。 标签分析 从标签...

    C#制作一个简单计算器程序

    在本项目中,我们将探讨如何使用C#编程语言制作一个简单的计算器程序。这个程序是基于“Visual C# .NET 应用教程第二版”的课后练习题,旨在帮助学习者掌握C#的基础语法和控制流程,同时理解面向对象编程的基本概念...

    一个简易的计算器 java小程序

    在本文中,我们将深入探讨如何创建一个简易的Java计算器程序,该程序具备基本的数学运算功能,如加、减、乘、除,还包括求平方根、取倒数、求余数以及清除操作。这个计算器的设计旨在提供用户友好的界面和简单易用的...

    模仿设计一个Windows计算器程序作业

    "模仿设计一个Windows计算器程序作业"这个标题指示了本次任务的主要目标,即创建一个类似于Windows操作系统内置的计算器程序。这通常是一项针对计算机科学或软件工程学生的编程作业,旨在帮助他们掌握基本的用户界面...

    一个简易的计算器,带注释

    在本项目中,我们讨论的是一个使用Java编程语言编写的简易计算器程序。这个计算器程序具有基本的四则运算功能,并且源代码中包含了详细的注释,便于初学者理解和学习。 首先,我们需要理解Java编程基础。Java是一种...

    利用简单工厂模式,实现简易计算器程序

    在这个任务中,我们需要使用Java面向对象编程来实现一个简易计算器程序,它具备加、减、乘、除四种基本运算功能。以下是具体的设计思路和实现方式: 1. **软件设计目标**: - **单一职责原则**:确保每个类或方法...

    c++编写的简易计算器程序

    在本项目中,我们讨论的是一个使用C++编程语言实现的简易计算器程序。这个程序具有图形用户界面(GUI),能够帮助用户执行基本的数学运算,包括加法、减法、乘法和除法。让我们深入了解一下这个项目的核心知识点。 ...

    用java 编写的简单计算器程序

    计算器 java 源程序 简单 容易理解 好运行

    (微信小程序毕业设计)简易计算器(源码+截图).zip

    (微信小程序毕业设计)简易计算器(源码+截图)(微信小程序毕业设计)简易计算器(源码+截图)(微信小程序毕业设计)简易计算器(源码+截图)(微信小程序毕业设计)简易计算器(源码+截图)(微信小程序毕业设计)简易计算器(源码+...

    VC做的一个简单的计算器程序

    标题 "VC做的一个简单的计算器程序" 暗示这是一个使用Visual C++(简称VC)编写的计算器应用。在本文中,我们将深入探讨使用VC进行Windows应用程序开发的基本概念、计算器程序的关键组成部分以及可能存在的改进点。 ...

Global site tag (gtag.js) - Google Analytics