实现《C++程序设计语言(特别版)》第6章 表达式和语句 - 桌面计算器 - Linux
来源:互联网 发布:高级安全windows防火墙 编辑:程序博客网 时间:2024/06/05 05:52
这个实现只是一个思路,需要容错和优化。表达式语法分析如下:
*****************
* program:
* END
* expr_list END
* expr_list:
* expression PRINT // PRINT is ;
* expression PRINT expr_list
* expression:
* expression + term
* expression - term
* term
* term:
* term / primary
* term * primary
* primary
* primary:
* NUMBER
* NAME // this is variable
* NAME = expression
* - primary
* ( expression )
*****************
文件列表:
- calc.cc
- calc.h
- main.cc
- makefile
源码下载连接:http://download.csdn.net/detail/wxqee/4397788
用法:
所有代码》》》》
xiwang@ubuntu:~/Dev/calc$ makeg++ -Wall -I. -D_DEBUG -c calc.cc -o calc.cc.og++ -Wall -I. -D_DEBUG -c main.cc -o main.cc.og++ -D_DEBUG -L. calc.cc.o main.cc.o -o calc -lpthreadxiwang@ubuntu:~/Dev/calc$ ./calcr = 2.5;2.5 //<输出>area = pi * r * r;19.635 //<输出>^C
所有代码》》》》
文件:calc.cc
// calc.cc#include "calc.h"#include <ctype.h>#include <iostream>#include <map>#include <string>using namespace std;// error functionint no_of_errors;double error(const string& s){ no_of_errors++; cerr << "error: " << s << '\n'; return 1;}// END error functionToken_value curr_tok = PRINT;double expr(bool get){ double left = term(get); for (;;) { switch (curr_tok) { case PLUS: left += term(true); break; case MINUS: left -= term(true); break; default: return left; } }}double term(bool get){ double left = prim(get); for (;;) { switch (curr_tok) { case MUL: left *= prim(true); break; case DIV: if (double d = prim(true)) { left /= d; break; } return error("divide by 0"); default: return left; } }}double number_value;string string_value;map<string, double> table; // var tabledouble prim(bool get){ if (get) get_token(); switch (curr_tok) { case NUMBER: { double v = number_value; get_token(); return v; } case NAME: { double& v = table[string_value]; if (get_token() == ASSIGN) v = expr(true); return v; } case MINUS: return -prim(true); case LP: { double e = expr(true); if (curr_tok != RP) return error(") expected"); get_token(); return e; } default: return error("primary expected"); }}// --BEGIN-- OPTIMIZE get_token function// Token_value get_token()// {// char ch = 0;// cin >> ch;//// switch (ch) {// case 0:// return curr_tok = END; // assign and return// case ';':// case '*':// case '/':// case '+':// case '-':// case '(':// case ')':// case '=':// return curr_tok = Token_value(ch);// case '0': case '1': case '2': case '3': case '4':// case '5': case '6': case '7': case '8': case '9':// case '.':// cin.putback(ch);// cin >> number_value;// return curr_tok = NUMBER;// default:// if (isalpha(ch)) {// cin.putback(ch);// cin >> string_value;// return curr_tok = NAME;// }// error("bad token");// return curr_tok = PRINT;// }// }Token_value get_token(){ char ch = 0; // --BEGIN-- ignore blanks except '\n' // do { // if (!cin.get(ch)) return curr_tok = END; // } while (ch != '\n' && isspace(ch)); cin >> ch; // ---END--- ignore blanks except '\n' switch (ch) { case 0: return curr_tok = END; // assign and return case ';': case '*': case '/': case '+': case '-': case '(': case ')': case '=': return curr_tok = Token_value(ch); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': cin.putback(ch); cin >> number_value; return curr_tok = NUMBER; default: if (isalpha(ch)) { // --BEGIN-- Optimize to avoid meeting blank issue // cin.putback(ch); // cin >> string_value; string_value = ch; while (cin.get(ch) && isalnum(ch)) string_value.push_back(ch); cin.putback(ch); // ---END_-- Optimize to avoid meeting blank issue return curr_tok = NAME; } error("bad token"); return curr_tok = PRINT; }}// ---END--- OPTIMIZE get_token function
/** * calc.h ***************** * program: * END * expr_list END * expr_list: * expression PRINT // PRINT is ; * expression PRINT expr_list * expression: * expression + term * expression - term * term * term: * term / primary * term * primary * primary * primary: * NUMBER * NAME // this is variable * NAME = expression * - primary * ( expression ) */#ifndef CALC_H_#define CALC_H_#include <map>#include <string>using namespace std;enum Token_value { NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PRINT=';', ASSIGN='=', LP='(', RP=')'};// for DRIVER PROGRAMextern Token_value curr_tok;extern map<string, double> table; // var tableextern int no_of_errors;extern double expr(bool get);extern Token_value get_token();extern double error(const string& s);// END for DRIVER PROGRAMextern double term(bool get);extern double prim(bool get);#endif
文件:main.cc (驱动程序)
/** * main.cc * * EAMPLE * ./calc 'rate=1.1934;150/rate;19.75/rate;217/rate' */#include <iostream>#include <sstream>#include "calc.h"using namespace std;// --BEGIN-- COMMENT SIMPLE DRIVER// // DRIVER PROGRAM// int main(int argc, char **argv) {// table["pi"] = 3.1415926535897932385; // PRE-DEFINED NAMES// table["e"] = 2.7182818284590452354;//// while (cin) {// get_token();// if (curr_tok == END) break;// if (curr_tok == PRINT) continue;// cout << expr(false) << endl;// }//// return no_of_errors;// }// ---END--- COMMENT SIMPLE DRIVERistream* input;int main(int argc, char * argv[]){ switch (argc) { case 1: input = &cin; break; case 2: input = new istringstream(argv[1]); break; default: error("too many arguments"); return 1; } table["pi"] = 3.1415926535897932385; // PRE-DEFINED NAMES table["e"] = 2.7182818284590452354; while (*input) { get_token(); if (curr_tok == END) break; if (curr_tok == PRINT) continue; cout << expr(false) << '\n'; } if (input != &cin) delete input; return no_of_errors;}
文件:makefile
# Makefile, 2012-06-23 T1110# TODO# ----------------------------------NAME = calcVERSION = 1.0.0RELEASE = 01# ----------------------------------BIN = $(NAME)OBJS = $(patsubst %.cpp,%.cpp.o,$(wildcard $(SRC_DIR)/*.cpp))OBJS += $(patsubst %.cc,%.cc.o,$(wildcard $(SRC_DIR)/*.cc))OBJS += $(patsubst %.C,%.C.o,$(wildcard $(SRC_DIR)/*.C))# TODO# BEGIN ----------------------------------# FoldersSRC_DIR = .# FlagsCXXFLAGS = -WallCXXFLAGS += -I$(SRC_DIR)CPPFLAGS = -D_DEBUGLDFLAGS = -L$(SRC_DIR)LIBS = -lpthread# END ----------------------------------.PHONY: all cleanall: $(BIN)$(BIN): $(OBJS)$(CXX) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)# source files%.cpp.o: %.cpp$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $^ -o $@%.cc.o: %.cc$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $^ -o $@%.C.o: %.C$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $^ -o $@clean:$(RM) $(BIN) $(OBJS)
- 实现《C++程序设计语言(特别版)》第6章 表达式和语句 - 桌面计算器 - Linux
- C++程序设计语言(特别版) -- 一个桌面计算器
- C++程序设计语言 特别版 第10章 Date类 完整实现
- 第10章 类---《C++程序设计语言(特别版)》
- C++程序设计语言--第六章:表达式和语句
- 《C++程序设计语言》(特别版)第四章答案
- 《C++程序设计语言(特别版)》
- C++ 程序设计语言(特别版)
- 第11章 运算符重载---《C++程序设计语言(特别版)》
- C++程序设计语言(特别版):第二章 C++概览
- C++程序设计语言(特别版):第三章 标准库概念
- C++程序设计语言(特别版):第一章 致读者
- 学习《C++程序设计语言(特别版)》 忠告
- Linux rmdir 命令实现(特别版)
- C和指针第二章--表达式计算器的C语言实现
- C primer plus第5章(运算符、表达式和语句)习题
- 《C++程序设计语言 》特别版 读书笔记
- 初读 《c++程序设计语言特别版》
- java基本数据类型
- Spring入门Blog[一、Ioc控制反转注入原理]
- Providing Resources
- 反射通用工具类
- Accessing Resources
- 实现《C++程序设计语言(特别版)》第6章 表达式和语句 - 桌面计算器 - Linux
- Spring入门Blog[二、Ioc控制反转集合注入和Scope]
- Spring入门Blog[三、Bean的懒加载和生命周期]
- 项目经理主要工作及指引
- i9000 通过odin刷基带步骤
- 下一个炙手可热的web UI开发平台:Dart Platform
- Spring入门Blog[四、基于Annotation的bean]
- linux进程管理
- 使用 Android 虛擬機器 - androidbmi/wiki/PlayEmulator