预测分析表方法

简介: 代码遵从C++14标准,忙着别的事潦草的完成,还有许多需要优化的地方。预测表里面的数:-1代表这有报错,其他数字拆开十位代表行,个位代表列;行:给出文法的行,从0开始,如:E→TE’是第0行;因为只需要到了右半部分所以只保留了右半部分列:为什么会出现列呢?因为很多文法右半部分是或的关系,如:T’ →*FT’ |/ FT’ |%FT’|ε 依次的行列是(3,0),(3,1),(3,2),(3,3)所以预测表里存储的是30,31,32,33其他部分看代码的注释即可,有问题可以留言或加我QQ讨论

算术表达式文法

E→TE’

E’ → +TE’|- TE’|ε

T→FT’

T’ →*FT’ |/ FT’ |%FT’|ε

F→(E) |id|num


给定一符合该文法的句子,如id+id*id#,运行预测分析程序,给出分析过程和每一步的分析结果

前言

  • 代码遵从C++14标准,忙着别的事潦草的完成,还有许多需要优化的地方。
  • 预测表里面的数:-1代表这有报错,其他数字拆开十位代表行,个位代表列;
  • 行:给出文法的行,从0开始,如:E→TE’是第0行;因为只需要到了右半部分所以只保留了右半部分
  • 列:为什么会出现列呢?因为很多文法右半部分是或的关系,如:T’ →*FT’ |/ FT’ |%FT’|ε 依次的行列是(3,0),(3,1),(3,2),(3,3)所以预测表里存储的是30,31,32,33
  • 其他部分看代码的注释即可,有问题可以留言或加我QQ讨论

话不多说上代码


main.cpp

//

// Created by NorthS on 2022/5/5.

// QQ:1826496887

// url:www.vieuu.cn

//

#include "compilerwork.h"

//E`=X

//T`=Y

stack<char> reverAndPush(stack<char> s,string str);

int main(){

   string s[5][10];

   s[0][0]="TX";

   s[1][0]="+TX";s[1][1]="-TX";s[1][2]="$";

   s[2][0]="FY";

   s[3][0]="*FY";s[3][1]="/FY";s[3][2]="%FY";s[3][3]="$";

   s[4][0]="(E)";s[4][1]="i";s[4][2]="n";

   int patable[5][10]={0,0,-1,-1,-1,-1,-1,0,-1,-1,

                       -1,-1,10,11,-1,-1,-1,-1,12,12,

                       20,20,-1,-1,-1,-1,-1,20,-1,-1,

                       -1,-1,33,33,30,31,32,-1,33,33,

                       41,42,-1,-1,-1,-1,-1,40,-1,-1

   };

   int follow[5][10]={0,0,0,0,0,0,0,0,1,1,

                      0,0,0,0,0,0,0,0,1,1,

                      0,0,1,1,0,0,0,0,1,1,

                      0,0,1,1,0,0,0,0,1,1,

                      0,0,1,1,1,1,1,0,1,1

   };

   string str="ii#";

   int flag=0;

   stack<char> gra;

   gra.push('#');

   gra.push('E');

   while(1){

       if(flag-1==str.size())break;

       if(isNonterminator(gra.top())){//非终结符

           int i= inNonterminatorindex(gra.top());

           int j= inTerminatorindex(str[flag]);

           if(patable[i][j]!=-1){//在预测表中有交点

               int index=patable[i][j];

               int m=index/10;

               int n=index%10;

               cout<<gra.top()<<"\t\t\t"<<str[flag]<<"\t\t\t"<<"展开非终结符"<<gra.top()<<"->"<<s[m][n]<<endl;

              //在栈中弹出该非终结符

               gra.pop();

              //其右式逆序入栈

               gra= reverAndPush(gra,s[m][n]);

           }else{//在预测表中没交点

               if(follow[i][j]==1){//当前单词属于该follow集

                   cout<<gra.top()<<"\t\t\t"<<str[flag]<<"\t\t\t"<<"\033[31;1m"<<"从栈中弹出该非终结符"<<gra.top()<<"\033[0m"<<endl;

                  //从栈中弹出该非终结符继续分析

                   gra.pop();

               }else{//当前单词不属于该follow集

                   cout<<gra.top()<<"\t\t\t"<<str[flag]<<"\t\t\t"<<"\033[31;1m"<<"串指针下移(抛弃该单词不分析)"<<"\033[0m"<<endl;

                  //串指针下移(抛弃该单词不分析)

                   flag++;

                   if(flag==str.size()){//如果跳过的单词是最后一个单词报错并直接结束

                       break;

                   }

               }

           }

       }

       if(isTerminator(gra.top())){//终结符

           if(gra.top()==str[flag]){//匹配成功

               cout<<gra.top()<<"\t\t\t"<<str[flag]<<"\t\t\t"<<"匹配终结符"<<str[flag]<<endl;

               gra.pop();//栈顶元素出栈

               flag++;//串指针下移

           }else{//匹配不成功

              //第一种:从栈中弹出此终结符x(认为输入串中缺少单词a)√

              // 第二种:将串指针下移一个位置(认为串中当前单词a多余)

               cout<<gra.top()<<"\t\t\t"<<str[flag]<<"\t\t\t"<<"\033[31;1m"<<"从栈中弹出该终结符"<<"\033[0m"<<gra.top()<<endl;

               gra.pop();

           }

       }

   }

   return 0;

}

handle.cpp

//

// Created by NorthS on 2022/5/5.

// QQ:1826496887

// url:www.vieuu.cn

//

#include "compilerwork.h"

char Nonterminator[10]={'E','X','T','Y','F'};

char Terminator[10]={'i','n','+','-','*','/','%','(',')','#'};

bool isNonterminator(char ch){

   for(int i=0;i<strlen(Nonterminator);i++){

       if(Nonterminator[i]==ch)return true;

   }

   return false;

}

bool isTerminator(char ch){

   for(int i=0;i<strlen(Terminator);i++){

       if(Terminator[i]==ch)return true;

   }

   return false;

}

int inNonterminatorindex(char ch){

   for(int i=0;i<strlen(Nonterminator);i++){

       if(Nonterminator[i]==ch)return i;

   }

   return -4;

}

int inTerminatorindex(char ch){

   for(int i=0;i<strlen(Terminator);i++){

       if(Terminator[i]==ch)return i;

   }

   return -4;

}

stack<char> reverAndPush(stack<char> s,string str){

   if(str.size()==1&&str[0]=='$')return s;

   for(int i=str.size()-1;i>=0;i--){

       s.push(str[i]);

   }

   return s;

}

compilerwork.h

//

// Created by NorthS on 2022/5/5.

// QQ:1826496887

// url:www.vieuu.cn

//

#ifndef COMPILERW4_COMPILERWORK_H

#define COMPILERW4_COMPILERWORK_H

#include<bits/stdc++.h>

using namespace std;

/**

* 是否是非终结符

* @param ch

* @return

*/

bool isNonterminator(char ch);

/**

* 是否是终结符

* @param ch

* @return

*/

bool isTerminator(char ch);

/**

* 该非终结符在非终结符表中的位置

* @param ch

* @return

*/

int inNonterminatorindex(char ch);

/**

* 该终结符在终结符表中的位置

* @param ch

* @return

*/

int inTerminatorindex(char ch);

#endif //COMPILERW4_COMPILERWORK_H

 


目录
相关文章
|
开发工具 git
IDEA中如何使用Git 图文超详细
IDEA中Git使用,实战教程
11436 1
IDEA中如何使用Git 图文超详细
|
监控 负载均衡 Java
5 大 SpringCloud 核心组件详解,8 张图彻底弄懂
本文图文详解 Spring Cloud 的五大核心组件,帮助深入理解和掌握微服务架构。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
5 大 SpringCloud 核心组件详解,8 张图彻底弄懂
|
存储 缓存 监控
缓存击穿、缓存穿透、缓存雪崩 3大问题,如何彻底解决?
【10月更文挑战第8天】在分布式系统中,缓存的使用极大地提高了系统的性能和响应速度。然而,缓存击穿、缓存穿透和缓存雪崩是三个常见的缓存相关问题,它们可能导致系统性能下降,甚至引发系统崩溃。本文将深入探讨这三个问题的成因、影响以及彻底的解决方案。
2784 1
什么是多态?面向对象中对多态的理解
本文介绍了面向对象编程中的多态概念,包括其定义、优点以及编译时多态和运行时多态的具体实现方式。通过实例展示了函数重载、运算符重载、虚函数、接口和抽象类的应用,帮助读者深入理解多态的灵活性和可扩展性。
1095 8
|
开发工具 C++ git
五分钟看懂推送本地项目到 GitHub新手菜鸡
五分钟看懂推送本地项目到 GitHub新手菜鸡
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
1259 8
|
安全 Java 关系型数据库
springboot整合springsecurity,从数据库中认证
本文介绍了如何在SpringBoot应用中整合Spring Security,并从数据库中进行用户认证的完整步骤,包括依赖配置、数据库表创建、用户实体和仓库接口、用户详情服务类、安全配置类、控制器类以及数据库初始化器的实现。
1577 3
springboot整合springsecurity,从数据库中认证
|
存储 NoSQL Redis
Redis之 redis.conf配置文件
Redis之 redis.conf配置文件
3296 0
|
存储 Cloud Native Java
Windows下Minio的安装以及基本使用
MinIO 是一个开源的云原生分布式对象存储系统,兼容亚马逊S3接口,适合存储大容量非结构化数据。本文介绍Windows下MinIO的安装与基本使用:通过以上步骤,您可以在Windows环境中成功安装并使用MinIO。
10574 19
|
IDE 开发工具
【开发IDE升级】如何对IDEA版本进行升级
本文介绍了如何将 IntelliJ IDEA Ultimate 从 2020.2.2 版本升级到 2022.3.2 版本。主要内容包括准备工作、卸载旧版本和安装新版本的步骤。首先,从官网下载所需版本并备份旧版配置;接着,通过 Uninstall.exe 卸载旧版,保留配置和插件;最后,安装新版并完成激活。详细的操作步骤和截图帮助用户顺利完成升级过程。
18199 1
【开发IDE升级】如何对IDEA版本进行升级