编译原理 波兰式和四元式及计算
实验目的
将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式,并计算用逆波兰式来表示的算术表达式的值。
实验环境
Microsoft Visual Studio 2019 Community
思路
转换:首先将‘#’压入栈中,依次读取输入字符串的每一个字符,如果遇到数字则继续读取下一个字符,如果还是数字则进行拼凑,直到读取到的不是数字,表明一个运算数已经读取完毕,将其加入到队列中。如果读取到的是运算符,就比较当前运算符与栈顶运算符之间的优先关系,如果栈顶运算符有优先级高,则将栈顶运算符弹出加入到队列中,重新分析当前运算符;如果栈顶运算符优先级低,则将当前读取的运算符压入栈中,继续读取下一个字符;如果两个运算符优先级相等,此时只可能是左右括号或井号相遇,则将栈顶运算符弹出栈,继续读取下一个字符;如果两个运算符没有优先级关系,则出错,直到整个输入字符串都读取完。此时队列里存储的就是完整的逆波兰式。
计算:从队列中依次读取元素,如果是数字,则压入栈中,如果是运算符,则从栈中取出两个数字,第一个数字为右操作数,第二个数字为左操作数,进行计算,计算结果再压入栈中。当队列为空时,计算结束,此时栈中只剩一个元素,就是计算结果。
对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照。
运算符优先级
#pragma once
#include <iostream>
#include <vector>
#include <fstream>
#include <stack>
#include <string>
#include <queue>
using namespace std;
class ReversePolishNotation
{
static vector<char> operators;//存放所有运算符
static vector<vector<char>> precedenceRelationTable;//存放运算符优先关系,坐标与运算符向量中的位置对应
static queue<string> reversePolishNotation;//存放逆波兰式的所有元素
static fstream file;//结果写入的文件
static int getIndex(char ch);
static void readOperators(string fileName);
static bool isDigital(char ch);
static void getReversePolishNotation(string str);
static void printReversePolishNotation();
static void calculateReversePolishNotation();
static double calculate(char op, double left, double right);
public:
static void analyse(string operatorsFileName, string str);
};
#include "ReversePolishNotation.h"
vector<char> ReversePolishNotation::operators;
vector<vector<char>> ReversePolishNotation::precedenceRelationTable;
queue<string> ReversePolishNotation::reversePolishNotation;
fstream ReversePolishNotation::file("ReversePolishNotationResult.txt");
/// <summary>
/// 获取运算符在运算符向量中的下标
/// </summary>
/// <param name="ch">运算符</param>
/// <returns>下标,未找到返回-1</returns>
int ReversePolishNotation