算符优先系列之(一)Firstvt和Lastvt集
来源:互联网 发布:java异常处理设计 编辑:程序博客网 时间:2024/06/09 15:57
#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <sstream>#include <algorithm>#include <set>#include <queue>#include <stack>#include <map>#include <bitset>typedef long long LL;const int inf=0x3f3f3f3f;const double pi= acos(-1.0);const double esp=1e-6;using namespace std;const int Maxn=110;const int maxn=20;char str[maxn][Maxn];//输入文法char st[maxn];//输入串char stac[maxn];//模拟栈的数组char nstr[maxn][maxn];//储存转化文法char mstr[maxn][maxn];char fin[maxn];//存储终结符char firstvt[maxn][maxn],lastvt[maxn][maxn];char cmp[maxn][maxn];//存储表中的比较符int firstflag[maxn],lastflag[maxn];//非终结符的firstvt,lastvt是否求出int fcnt[maxn],lcnt[maxn];//非终结符firsvt和lastvt的个数int is_fin(char c) { //判断终结符 for(int i=0; fin[i]!='\0'; i++) { if(fin[i]==c) return 1; } return 0;}int site(char c) { //求在表中的下标 for(int i=0; fin[i]!='\0'; i++) { if(fin[i]==c) return i; }}void get_firstvt(char s,int t) { //求s非终结符的firstvt值 int i,j,ii,jj,tt; for(i=0; i<t; i++) { if(str[i][0]==s) break; } if(!firstflag[i]) { int k=fcnt[i]; for(j=0; str[i][j]!='\0'; j++) { if(j==2||str[i][j]=='|') { if(is_fin(str[i][j+1])) { firstvt[i][k++]=str[i][j+1]; } else { if(is_fin(str[i][j+2])) { firstvt[i][k++]=str[i][j+2]; } if(str[i][j+1]!=s) { get_firstvt(str[i][j+1],t); for(ii=0; ii<t; ii++) { if(str[ii][0]==str[i][j+1]) break; } for(jj=0; jj<fcnt[ii]; jj++) { for(tt=0; tt<k; tt++) { if(firstvt[i][tt]==firstvt[ii][jj]) break; } if(tt==k) { firstvt[i][k++]=firstvt[ii][jj]; } } } } } } firstvt[i][k]='\0'; fcnt[i]=k; firstflag[i]=1; }}void output_firstvt(int T) { //输出firstvt集 for(int i=0; i<T; i++) { get_firstvt(str[i][0],T); } for(int i=0; i<T; i++) { printf("Firstvt[%c]:",str[i][0]); for(int j=0; j<fcnt[i]; j++) { printf("%c ",firstvt[i][j]); } puts(""); }}void get_lastvt(char s,int t) { //求s非终结符的lastvt值 int i,j,ii,jj,tt; for(i=0; i<t; i++) { if(str[i][0]==s) break; } if(!lastflag[i]) { int k=lcnt[i]; for(j=0; str[i][j]!='\0'; j++) { if(str[i][j+1]=='|'||str[i][j+1]=='\0') { if(is_fin(str[i][j])) { lastvt[i][k++]=str[i][j]; } else { if(is_fin(str[i][j-1])) { lastvt[i][k++]=str[i][j-1]; } if(str[i][j]!=s) { get_lastvt(str[i][j],t); for(ii=0; ii<t; ii++) { if(str[ii][0]==str[i][j]) break; } for(jj=0; jj<lcnt[ii]; jj++) { for(tt=0; tt<k; tt++) { if(lastvt[i][tt]==lastvt[ii][jj]) break; } if(tt==k) { lastvt[i][k++]=lastvt[ii][jj]; } } } } } } lastvt[i][k]='\0'; lcnt[i]=k; lastflag[i]=1; }}void output_lastvt(int T) { //输出lastvt集 for(int i=0; i<T; i++) { get_lastvt(str[i][0],T); } for(int i=0; i<T; i++) { printf("Lastvt[%c]:",str[i][0]); for(int j=0; j<lcnt[i]; j++) { printf("%c ",lastvt[i][j]); } puts(""); }}void output(int i,int j,char *str) { printf("\t"); for(int ii=i; ii<=j; ii++) printf("%c",str[ii]);}int main() { int T; while(scanf("%d",&T)!=EOF) { int cnt=0;//终结符的个数 memset(firstflag,0,sizeof(firstflag)); memset(lastflag,0,sizeof(lastflag)); memset(cmp,0,sizeof(cmp)); for(int i=0; i<T; i++) { scanf("%s",str[i]); fcnt[i]=lcnt[i]=0; } for(int i=0; i<T; i++) { for(int j=0; str[i][j]!='\0'; j++) { if((str[i][j]<'A'||str[i][j]>'Z')&&(str[i][j]!='-'&&str[i][j]!='>')&&str[i][j]!='|') fin[cnt++]=str[i][j]; } } fin[cnt++]='#'; fin[cnt]='\0'; output_firstvt(T); output_lastvt(T); } return 0;}
Problem Description
学过编译原理的菊苣们都知道算符优先文法,作为一个有点深度的分析方法,我们怎么能只止步于理论呢,实践才是王道哦。
已知文法G[S]的表达式,计算G[S]的Firstvt和Lastvt。因为某些特殊的原因,我们在这规定一下输入输出格式。
例如:
已知文法G[S]为:
S->a|@|(T)
T->T,S|S
首先先把各条件语句按照从左到右从上到下的方式分解和输出
S->a
S->@
S->(T)
T->T,S
T->S
对于输出首先输出FIRSTVT集然后输出LASTVT集,对于各自的集合的的输出按照非终结符从上向下的方式
Firstvt[S]:非终结符+空格的形式
Firstvt[T]:
Lastvt[S]:
Lastvt[T]:
Input
多组输入。第一行输入一个n,表示表达式的个数,接下来n行,每行一个表达式
Output
根据上述的格式,输出文法的Firstvt和Lastvt集合
Example Input
2S->a|@|(T)T->T,S|S
Example Output
Firstvt[S]:a @ ( Firstvt[T]:, a @ ( Lastvt[S]:a @ ) Lastvt[T]:, a @ )
阅读全文
0 0
- 算符优先系列之(一)Firstvt和Lastvt集
- sdut 算符优先系列之(一)Firstvt和Lastvt集
- 算符优先系列之(一)Firstvt和Lastvt集 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Descri
- 算符优先算法(FIRSTVT集,LASTVT集,判读是否是算符优先文法,算符优先矩阵,句子分析)
- 混乱的First,Follow,Firstvt和Lastvt
- First,Follow,Firstvt和Lastvt (编译原理)
- 编译原理--First,Follow,Firstvt和Lastvt
- 算符优先 firstvt 计算
- 算符优先 lastvt 计算
- FIRST集和FOLLOW集,FIRSTVT集和LASTVT集总结
- First集和Follow集,FirstVt集和LastVt集的计算
- <编译原理>——first集、follow集、firstvt集及lastvt集
- 宽度优先搜索搜索系列一
- 重学数据结构系列之——图的遍历(广度优先搜索和深度优先搜索)学习来源:计蒜客
- 优先策略之广度优先和最佳优先
- STL系列之五 priority_queue 优先队列
- 优先队列之堆排序(一)
- JavaScript入门之条件运算符和优先级别关系
- # C#调用已经使用Python训练好的神经网络做图片检测
- Bandwagon的vps设置vpn代理
- 将linux(ubuntu)安装到U盘下面--便携式ubuntu和使用dd制作U盘安装工具
- 技术分享连载(八十)
- C/C++ 第八周串和数组 (一)顺序串算法 项目2—(一)
- 算符优先系列之(一)Firstvt和Lastvt集
- 360检测Dedecms重定向漏洞的解决方案
- Linux网络编程基础---IPV4地址
- 使用DeepLearning4J进行K-Means聚类
- Set,Map集合与数组互转
- 文本特征选择的关键算法总结
- 多态的对象模型
- 学习笔记4 线性表
- 第八周-项目2-顺序串算法