前言

  • 这里要介绍各种语句和表达式,将通过一个桌面计算器的程序做些事情,该计算器提供四种座位浮点数的中缀运算符的标准算术运算。
  • 这个计算器由四个部分组成:一个分析器,一个输入函数,一个符号表和一个驱动程序。

分析器

program:
END
expr_list END //END表示输入结束
expr_list:
expression PRINT // PRINT表示分号
expression PRINT expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary
primary:
NUMBER
NAME
NAME = expression
- primary
(expression)
  • 语法分析器采用通常的递归下降的风格。终结符由词法分析程序get_token()识别,而非终结符由语法分析函数expr(),term()和prim()识别。一旦一个表达式的两个运算对象都知道,就立即对这个表达式求值。
  • 个人觉得分析器就像是定义程序能接受什么输入,而这里采用递归的形式,例如program代表程序,program可以接受END符号或者expr_list END,而expr_list又继续递归下去可以由其他的组成,直到可以得到一个结束情况。

总代码

#include<iostream>
#include<string>
#include<map>
#include<cctype>
using namespace std; // 将token用他们的字符所对应的整数表示,这样做既方便有效,
// 又能帮助使用排错系统的人。
enum Token_value {
NAME, NUMBER, END, PLUS='+',
MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')',
};
Token_value curr_tok = PRINT; double expr(bool);
double term(bool);
double prim(bool);
Token_value get_token();
double error(const string&);
map<string, double> table; int no_of_errors; int main()
{
table["pi"] = 3.1415924535;
table["e"] = 2.178; while(cin) {
get_token();
if(curr_tok == END) break;
if(curr_tok == PRINT) continue;
cout<<expr(false)<<'\n';
}
return no_of_errors;
} // 每个分析器都有一个bool参数,
// 指明该函数是否需要调用get_token()去取得下一个参数
// expr处理加减,一直到不是加减返回left
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;
}
}
} // 函数term处理乘除,采用的方式与expr()处理方法一样
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; // prim处理初等项的方式很像expr和term
double 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");
}
} Token_value get_token() {
char ch; do { // 低级输入,改进输入
if(!cin.get(ch)) return curr_tok = END;
} while(ch != '\n' && isspace(ch)); switch(ch) {
case 0:
return curr_tok=END;
case '\n':
return curr_tok=PRINT;
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)) {
string_value = ch;
while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
cin.putback(ch);
return curr_tok = NAME;
}
error("bad token");
return curr_tok = PRINT;
}
} double error(const string& s) {
no_of_errors ++;
cerr<<"error: "<<s<<'\n';
return 1;
}

扩展

  • 自己的代码只是简单的拼接,这里发现一个更好的博客

C++程序设计语言(特别版) -- 一个桌面计算器的更多相关文章

  1. C++程序设计与语言(特别版) -- 导论

    前言 刚开始的时候只学习了一些简单的C++语法知识,当C++不再是一门学科需要考试的时候,就想重新把C++捡回来,希望从中学习到一点思想性的东西而不再是一些语法性的东西. 下面都是一些参考书目的摘抄或 ...

  2. c++学习书籍推荐《C++程序设计语言(特别版)》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <C++程序设计语言(特别版•十周年中文纪念版)>编辑推荐:十周年纪念版,体味C++语言的精妙与魅力,享受与大师的心灵对话.1979年,Biarn ...

  3. 《C++程序设计语言(十周年纪念版)》【PDF】下载

    <C++程序设计语言(十周年纪念版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382171 内容简介 <C++程序设计 ...

  4. 《程序设计语言——实践之路(英文第三版)》【PDF】下载

    <程序设计语言--实践之路(英文第三版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382234 内容简介 <程序设计语 ...

  5. C程序设计语言(第二版)习题:第一章

    第一章虽然感觉不像是个习题.但是我还是认真去做,去想,仅此而已! 练习 1-1 Run the "hello, world" program on your system. Exp ...

  6. 《C++程序设计语言(英文第四版)》【PDF】下载

    <C++程序设计语言(英文第四版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382177 内容简介 本书是C++领域经典的参 ...

  7. C语言学习书籍推荐《C程序设计语言(第2版•新版)》下载

    克尼汉 (作者), 等 (作者, 译者), 徐宝文 (译者) 下载地址:点我 <C程序设计语言(第2版•新版)>是由C语言的设计者Brian W.Kernighan和Dennis M.Ri ...

  8. Notes 20180506 : Java程序设计语言概述

    2.Java程序设计语言概述 如果对于开发语言的排行榜有所关注的话,那么会发现很长一段时间以来Java都是位居榜首的高级开发语言,作为一个Java开发者,为此感到骄傲的同时也深感忧虑,骄傲的是自己接触 ...

  9. 《程序设计语言——实践之路》【PDF】下载

    程序设计语言--实践之路>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382240 内容简介 本书在美国大学已有使用了十余年,目前被欧 ...

随机推荐

  1. PAT-L3-球队“食物链”-dfs-状压-set

    题目分析: 1. 一场双循环赛制的篮球赛,注意双循环,双循环! 2. 共有n只球队,两两之间有胜有负有平局: 3. 输入: 举例: 第一行:W:代表球队1打赢过这只队伍 L:代表球队2没打赢过这只队伍 ...

  2. c++ --> union介绍

    union介绍 共用体,也叫联合体,在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目 ...

  3. Android Service基础

    Service Service 是一个组件,用来执行长时间的后台操作,不提供用户界面. 另一个应用组件可以启动一个Service,它将持续地在后台运行,即便是用户转移到另一个应用它也不会停止. 另外, ...

  4. eclipse中svn的各种状态图标详解

    - 已忽略版本控制的文件.可以通过Window → Preferences → Team → Ignored Resources.来忽略文件. A file ignored by version co ...

  5. LeetCode-4. 两个排序数组的中位数(详解)

    链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/ 有两个大小为 m 和 n 的排序数组 nums ...

  6. fcode-页面九宫格自动锁屏jquery插件

    fcode.js 自动锁屏插件 fcode.js是什么? fcode.js是一款web页面九宫格自动锁屏js插件,依赖于jquery, 会在设置的范围里,判断用户有无操作,然后执行锁屏的功能. 就一个 ...

  7. Beta总结

    45°炸 031502601 蔡鸿杰 031502604 陈甘霖 031502632 伍晨薇 一.写在Beta项目前 Beta 凡 事 预 则 立 二.GitHub传送门 Beta冲刺重要版本 三.用 ...

  8. C语言第五次博客作业

    一.PTA实验作业 题目1:6-6 使用函数输出水仙花数 1. 本题PTA提交列表 2. 设计思路 (1) 首先先定义narcissistic函数. (2)定义四个整形变量n,a,d,cnt,sum, ...

  9. 201621123025《Java程序设计》第1周学习总结

    201621123025<Jave程序设计>第一周学习总结 1.本章学习总结 对于java这门课程,如果不会编码那么会很难学会如何去使用它,而在大一的一二学期的专业课--C语言和数据结构我 ...

  10. OVS常用命令

    添加brideg: sudo ovs-vsctl add-br br0 删除brideg: sudo ovs-vsctl del-br br0 显示bridge: sudo ovs-vsctl sho ...