预测分析表方法

简介: 代码遵从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

 


目录
相关文章
|
2月前
|
存储 关系型数据库 MySQL
提高查询性能的秘密:深入剖析聚集、辅助、覆盖和联合索引
提高查询性能的秘密:深入剖析聚集、辅助、覆盖和联合索引
|
2月前
|
存储 数据挖掘 大数据
大数据数仓建模基础理论【维度表、事实表、数仓分层及示例】
数据仓库建模是组织和设计数据以支持数据分析的过程,包括ER模型和维度建模。ER模型通过实体和关系描述数据结构,遵循三范式减少冗余。维度建模,特别是Kimball方法,用于数据仓库设计,便于分析和报告。事实表存储业务度量,如销售数据,分为累积、快照、事务和周期性快照类型。维度表提供描述性信息,如时间、产品、地点和客户详情。数仓通常分层为ODS(源数据)、DWD(明细数据)、DIM(公共维度)、DWS(数据汇总)和ADS(应用数据),以优化数据管理、质量、查询性能和适应性。
|
2月前
|
数据挖掘 索引
使用 DataFrame 进行数据聚合与透视:洞察数据深层结构
【5月更文挑战第19天】DataFrame 提供了聚合和透视功能,便于数据分析。通过`groupby`和`agg`计算类别统计信息,如`sum`和`mean`,揭示数据模式。使用`pivot_table`重新排列数据,展示清晰结构。多维度透视和按时间聚合进一步增强分析能力。这些工具帮助我们理解复杂数据,挖掘隐藏规律,为决策提供依据。利用DataFrame进行数据深层分析,解锁数据价值,开启数据探索之旅。
36 2
|
2月前
|
存储 算法 iOS开发
R语言关联挖掘实例(购物篮分析)
R语言关联挖掘实例(购物篮分析)
|
2月前
|
数据挖掘 数据库
离线数仓6.0--- 数据仓库 ER模型-范式理论,维度模型、维度建模理论之事实表、维度建模理论之维度表
离线数仓6.0--- 数据仓库 ER模型-范式理论,维度模型、维度建模理论之事实表、维度建模理论之维度表
173 0
|
数据挖掘
2-华大时空组学分析软件 Spateo 空转数据基础分析用法示例
本分分享了使用华大时空组学分析软件 Spateo进行聚类、DE等简单空间转录组分析的用法示例,以供参考
860 1
扩增子测序中OTU表进行抽平的两种方式
A random rarefaction of sample reads according to a specific reads length (usually the smallest value) should be performed firstly for downstream analysis.
292 0
|
算法 数据挖掘 Python
数据挖掘与关联规则:发现隐藏在数据中的模式
数据挖掘是从大规模数据集中发现有价值的信息和模式的过程。其中,关联规则是一种常用的数据挖掘技术,它可以帮助我们发现数据中的相关性和潜在规律。在本文中,我们将介绍关联规则的概念、算法以及如何使用Python实现关联规则的挖掘。
264 0
|
数据可视化 数据挖掘 数据库
【数据挖掘】用Excel挖掘股权关系并按照年份统计不同类型的亲缘关系在上市公司中的分布和趋势【动态可视化工具】
推荐一个在线制作动图网站 Flourish(https://app.flourish.studio) 无需编程基础就可以做出漂亮的动态图表🎉🎉🎉
210 1
【数据挖掘】用Excel挖掘股权关系并按照年份统计不同类型的亲缘关系在上市公司中的分布和趋势【动态可视化工具】
|
算法 数据挖掘
数据分析模型-关联模型
尿布与啤酒背后的原理,如何让客户加满购物篮?
1611 0
数据分析模型-关联模型