前言

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

分析器

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. Java高级篇(一)——线程

    前面我们系统的了解了Java的基础知识,本篇开始将进入到Java更深层次的介绍,我们先来介绍一下Java中的一个重要的概念--线程. 一.什么是线程 在了解线程前,我们首先要了解进程的概念.进程是操作 ...

  2. RabbitMQ 发布订阅持久化

    RabbitMQ是一种重要的消息队列中间件,在生产环境中,稳定是第一考虑.RabbitMQ厂家也深知开发者的声音,稳定.可靠是第一考虑,为了消息传输的可靠性传输,RabbitMQ提供了多种途径的消息持 ...

  3. .NET Core初体验 在window上构建第一个app

    ASP.NET Core 是一个跨平台,高性能的开源框架,用于构建现代化的,基于云的互联网应用程序.使用 ASP.NET Core ,您可以: 构建Web应用程序和服务,IoT应用程序和移动后端. 在 ...

  4. oracle创建表空间、创建用户并赋予权限

    分开执行如下sql语句 --创建临时表空间 CREATE SMALLFILE TEMPORARY TABLESPACE "TEMP11" TEMPFILE 'E:\app\MD\o ...

  5. C语言的第一次作业

    一.PTA实验作业 题目1. 温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验 ...

  6. Mysql5.7.17中文乱码问题

    写Java web调数据库,老是出现汉字乱码,一直没理睬,今天决定好好"整治"一下,却发现并没有那么简单.从网上找的方法,大部分都尝试了一遍都有一些问题. 有的改完了,数据库启动不 ...

  7. c/cpp语言链表连接部分详解

    核心代码: ①pTail->next = pNew; ②pNew->next = NULL; ③pTail = pNew; 设结构体名称为 struct ST: 注:方框代表分配的内存空间 ...

  8. Cypher语法

    cypher是neo4j官网提供的声明式查询语言,非常强大,用它可以完成任意的图谱里面的查询过滤,我们知识图谱的一期项目 基本开发完毕,后面会陆续总结学习一下neo4j相关的知识.今天接着上篇文章来看 ...

  9. Linux的打印rpm包的详细信息的shell脚本

    #!/bin/bash # list a content summary of a number of RPM packages # USAGE: showrpm rpmfile1 rpmfile2 ...

  10. 第一章 IDEA的使用

    第一章   IDEA的使用 1.为什么要使用idea 最智能的IDE IDEA相对于eclipse来说最大的优点就是它比eclipse聪明.聪明到什么程度呢?我们先来看几个简单的例子. A.智能提示重 ...