实验一:Chomsky文法类型判断
Chomsky文法类型判断
预备实验Chomsky文法类型判断一、实验目的:编写程序,判断文法的类型。
二、实验要求:输入一组任意的规则,输出相应的Chomsky 文法的类型。
三、实验原理:1.0型文法产生式特点:a->B2. 1型文法产生式特点:|a|<=|B|,除S->#外。
3. 2型文法产生式的特点:A->r,除S->#外。
4. 3型文法产生式的特点:A->aB|a (右线性) ,A->Ba|a(左线性)●0型文法产生的语言称为0型语言。
●1型文法或上下文有关文法(CSG )产生的语言称为1型语言或上下文有关语言(CSL)。
●2型文法或上下文无关文法(CFG )产生的语言称为2型语言或上下文无关语言(CFL )。
●3型文法或正则(正规)文法(RG )产生的语言称为3型语言正则(正规)语言(RL )。
实验代码:#include<iostream>#include<cstring>using namespace std;//*********************************char b[10][10];//******************************bool wenfa0(int k)//0型文法判断{ int i,j,k1=0;for(j=0;j<=k;j++)for(i=0;i<strlen((b[j]));i++){if(b[j][i]!='-'){if(b[j][i]>='A' && b[j][i]<='Z'){k1++;break;}}elsebreak;}if(k1==k+1)return true;elsereturn false;}//******************************** bool wenfa1(intk,char c)//1型文法判断{inti,j,len;bool flag1=false,flag2=false;for(i=0;i<=k;i++){len=strlen((b[i]));for(j=0;j<len;j++){if(b[i][j]=='-'){if(len-(2*j+1)<0)return false;elseflag2=true;}if(b[i][j]==c && !flag2){flag1=true;}if( flag2 && b[i][j]=='#'){return false;}}}return true;}//****************************** bool wenfa2(int k)//2型文法判断{ inti,j,len;for(i=0;i<=k;i++){len=strlen(b[i]);for(j=0;j<len;j++){ if(b[i][j]=='-'){ break;}if(b[i][j]>='a' && b[i][j]<='z' ||j>1)return false;}}return true;}//**********************bool wenfa3(int k)//3型文法判断{inti,j,len;bool flag=false;for(i=0;i<=k;i++){len = strlen(b[i]);cout<<b[i]<<endl;for(j=0;j<len;j++){ if(flag){ if(b[i][j]>='A' && b[i][j]<='Z' && j==len-2 && b[i][j+1]>='A' && b[i][j+1]<='Z') return false;if(!(b[i][j]>='A' && b[i][j]<='Z') && j==len-2 && !(b[i][j+1]>='A' && b[i][j+1]<='Z')) return false;if(b[i][j]>='A' && b[i][j]<='Z' && j==len-1 && b[i][j-1]=='-')return false;}if(!flag && b[i][j]=='-'){if(len-j-1<=2)flag=true;elsereturn false;}}flag=false;}return true;}//**********************************int main(){char a[100],c,w=3,h=0;int i=0,j,len,k;cout<<" *************Chomsky文法类型判断*************"<<endl;{cout<<"请输入产生式"<<endl;gets(a);cout<<"请输入识别符";cin>>c;len=strlen(a);k=0;j=0;for(i=0;i<len;i++){if(a[i]==' '){b[k][j]='\0';j=0;k++;}elseb[k][j++]=a[i];}if(wenfa0(k)){if(wenfa1(k,c)){if(wenfa2(k)){if(wenfa3(k)){cout<<"该文法是3型文法"<<endl; }elsecout<<"该文法是2型文法"<<endl; }elsecout<<"该文法是1型文法"<<endl;}else cout<<"该文法是0型文法"<<endl; }elsecout<<"该文法不是0型文法"<<endl; }return 0;}实验截屏:。
编译原理实验一:生成Chomsky文法
实验一:生成Chomsky文法一:要求1)文法的输入应简便2)指明是哪一类Chomsky文法,给出相应的四元组形式。
输入:一组任意的文法规则输出:相应的Chomsky文法二:实验目的1、掌握四种文法类型的定义,及其区别;2、熟悉各种文法类型的判断,能够快速按照要求写出对应文法类型的文法用例.三:实验原理(一)0型文法,产生式左右部可以使用"非终结符"和"终结符"随意组合,但左部不能为空;(二)1型文法,在0型文法的基础上,要求右部的符号长度大于左部(空除外);(三)2型文法,在1型文法的基础上,要求左部必须由非终结符号组成,且左部只能拥有一个非终结符;(四)3型文法,在2型文法的基础上,产生式必须型如:A->Aa|a或A->aA|a;四:数据结构与算法struct Chomsky{string left;string right;};void apart(Chomsky *p,int i) //分开产生式左右部void VNVT(Chomsky *p)//求VN和VTvoid useless(Chomsky *p)//删除无用产生式void print(Chomsky *p)//输出四元组int zero(Chomsky *p)//0型文法int one(Chomsky *p)//1型文法int two(Chomsky *p)//2型文法int three(Chomsky *p)//3型文法五:出错分析1:#include<iostream>忽视了c++语言中的头文件应当去掉.h,须再另加上using namespace std;2:自定义的变量容易搞错大小写3:在数据结构的定义之中,字符与字符串的差别,本次实验室字符串而不是字符六:实验结果与分析0型1型2型3型七:源代码#include<iostream>#include<string>using namespace std;#define max 50int NONE=1;int RELEFT=1;string strings,noend,end;//非终结符与终结符存储int n;//产生式总数struct Chomsky{string left;string right;};void apart(Chomsky *p,int i) //分开产生式左右部{int j;for(j=0;j<strings.length();j++)if(strings[j]=='-'){p[i].left=strings.substr(0,j);p[i].right=strings.substr(j+1,strings.length()-j);}}void VNVT(Chomsky *p)//求VN和VT{int i,j;for(i=0;i<n;i++){for(j=0;j<(int)p[i].left.length();j++){if((p[i].left[j]>='A'&&p[i].left[j]<='Z'))//非终结符判断{if(noend.find(p[i].left[j])>100)noend+=p[i].left[j];}else{if(end.find(p[i].left[j])>100)end+=p[i].left[j];}}for(j=0;j<(int)p[i].right.length();j++){if(!(p[i].right[j]>='A'&&p[i].right[j]<='Z'))//终结符判断{if(end.find(p[i].right[j])>100)end+=p[i].right[j];}else{if(noend.find(p[i].right[j])>100)noend+=p[i].right[j];}}}void print(Chomsky *p)//输出四元组{int i;cout<<endl<<"G=({"<<noend<<"},{"<<end<<"},P,"<<noend[0]<<"),其中P由下列产生式组成:"<<endl;for(i=0;i<n;i++)cout<<p[i].left<<"->"<<p[i].right<<endl;}int zero(Chomsky *p)//0型文法{int flag(0),count(0);int i,j;for(i=0;i<n;i++){for(j=0;j<(int)p[i].left.length();j++){if(p[i].left[j]>='A'&&p[i].left[j]<='Z') //有否非终结符flag++;}if(flag>0){flag=0;count++;}elsebreak; //左部没有非终结符,结束}if(count==n)return 1; //属于0型文法else{cout<<endl<<"所输产生式不属于任何文法。
计算机编译原理chomsky文法分类分析
0型文法的规则形式是:每个产生式α→β都满足,α∈(V N∪V T)*且至少含有一个非终结符,β∈(V N∪V T)*,0型文法也叫短语文法。
1型文法的规则形式是:每个产生式α→β均满足|α|≤|β|,仅仅S→ε例外,且S不得出现在任何产生式的右部,1型文法也称上下文有关文法,从两种文法的规则形式来看,1型文法对规则形式的约束比0型文法强,1型文法能描述的语言0型文法也能描述,而0型文法能描述的语言1型文法不一定能够描述,1型文法是0型文法的特例。
2型文法的规则形式是A→β,其中A∈V N,β∈(V N∪V T)*,2型文法也称上下文无关文法,分析2型文法的规则形式不难发现,2型文法是1型文法的特例,也是0型文法的特例。
3型文法的规则形式是A→αB或A→α,其中α∈,A、B∈V N,3型文法也称正规文法,可以看出3型文法是前面3种文法的特例。
从形式上文法是一个四元式(VN,VT,P,S)VN为非终结符的集合如:动词VT为终结符的集合如:动词->eat(eat不可分解,则为终结符)P文法规则的集合S开始符号chomsky将文法分成4类:0型文法(短语文法或无限制文法),识别0语言的机器叫做图灵机定义:P中产生式a-->b,其中a属于V正闭包且至少含有一个非终结符,b属于V星闭包注:任何0型文法都是可递归可枚举的对0型文法作某些限制,可以得到其他文法的定义1型文法(上下文有关文法),线性界限自动机增加的限制:除了S产生空串之外,产生式的右部长度要大于等于左部,S不能出现在右部,非终结符不能产生空串。
例如:aAb-->ayb(在某种条件下A转换为y,所以称为上下文有关)2型文法(上下文无关文法),下推自动机增加的限制:P中只有A->b,而不是a->b,产生式左边只能有一个非终结符。
3型文法(正规文法),有限状态自动机增加的限制:产生式的右边非终结符的位置要么在最左边要么在最右边而且最多只能有一个在左端则称左线性文法,在右端则称右线性文法对比:四种文法之间的关系是随着型号的增加,对语言的限制条件就越来越大条件如下:0型文法: 产生式左右两边都可以出现任意符号串1型文法: 产生式的左边可以有终结符的出现,产生式右边是任意符号串2型文法:产生式的左边是非终结符,产生式的右边是任意符号串3型文法:产生式的左边是非终结符,产生式的右边非终结符的位置要么在最左边要么在最右边而且最多只能有一个如:A-->aB | dA-->Ba | d文法的简化:文法当中有时会存在一些没有的规则,删掉对P没有影响而且使得构造的文法更加简练1、查找有无形如P->P的产生式,删除2、若存在推导过程中永远不会用到,删除3、若某个产生式在推导过程中不能从中导出终结符,删除4、整理。
Chomsky文法体系分类
Chomsky⽂法体系分类
Chomsky⽂法分为0型,1型,2型,3型。
0型⽂法:
⽆限制语⾔,等价于图灵机。
1型⽂法:
⼜称上下⽂有关语⾔
式⼦左边形式:多个字符,必须含有⼀个终结符。
式⼦右边形式:⽆限制,但必须为有限个字符。
2型⽂法:
式⼦左边形式:⼀个字符,必须是⾮终结符。
式⼦右边形式:⽆限制,但必须为有限个字符。
3型⽂法:
⼜称为正则⽂法(正则语⾔,有限状态⾃动机)
正则⽂法分为:左线型⽂法,右线性⽂法。
式⼦左边形式:⼀个字符,必须是⾮终结符。
式⼦右边形式:最多两个字符,两个字符包括⼀个终结符合⼀个⾮终结符。
右线性⽂法:式⼦右边为:终结符||终结符+⾮终结符。
左线型⽂法:式⼦右边为:终结符||⾮终结符+终结符。
(注意:终结符合⾮终结符的位置不可换。
⽂法必须⼀致保持⼀致。
)
判断⽂法:
先看是否属于3型⽂法,否,看是否属于2型,否,看是否属于1型,否,0型。
只是对⽣成式形式加以限制 0型⽆限制 1型不允许A→ε形式 2型 3型属于2型不含A→ε的2型、3型属于1型,1型、2型、3型均属于0型。
chomsky文法类型地判断
编译原理实验报告实验名称Ch omsky文法类型判断实验时间2014-4-2院系计算机科学与技术学院班级2011级科技(3)班学号E01114375练钢1.实验目的(1)通过实验进一步理解chomsky文法类型判断的的依据,理解每个类型文法的特点。
(2)进一步理解4种文法类型之间的包含关系。
(3)体会这种理论对于计算机科学发展的深刻影响,特别是对程序设计语言的设计、编译方法和计算复杂性等方面的重大作用。
通过上机实现文法类型的自动判别。
2.实验原理1.0型文法(短语文法)如果对于某文法G,P中的每个规则具有下列形式:u:: = v其中u∈V+,v∈V*,则称该文法G为0型文法或短语文法,简写为PSG。
这种0型文法或短语结构文法的相应语言称为0型语言或短语结构语言L文法由于没有其他任何限制,因此0型文法也称为无限制文法,其相应的语言称为无限制性语言。
任何0型语言都是递归可枚举的,故0型语言又称递归可枚举集。
这种语言可由图灵机(Turning)来识别。
2.1型文法(上下文有关文法)如果对于某文法G,P中的每个规则具有下列形式:xUy:: = xuy;u∈V+;x,y∈V*,则称该文法G为1型文法或上下文有关文法,其中U∈VN也称上下文敏感文法,简写为CSG。
1型文法的规则左部的U和右部的u具有相同的上文x和下文y,利用该规则进行推导时,要用u替换U,必须在前面有x和后面有y的情况下才能进行,显示了上下文有关的特性。
,1型语言可由线性有界自动机来识别。
1型文法所确定的语言为1型语言L13.2型文法(上下文无关文法)如果对于某文法G,P中的每个规则具有下列形式:U :: = u;u∈V+,则称该文法G为2型文法或上下文无关文法,简写为其中U∈VNCFG。
按照这条规则,对于上下文无关文法,利用该规则进行推导时,无需考虑非终结符U所在的上下文,总能用u替换U,或者将u归约为U,显示了上下文无关的特点。
2型文法所确定的语言为2型语言L2,2型语言可由非确定的下推自动机来识别。
乔姆斯基文法
乔姆斯基⽂法
根据对产⽣式施加的限制不同,乔姆斯基(Chomsky)定义了四类⽂法和语⾔。
0型⽂法:短语结构⽂法或⽆限制⽂法,,其描述能⼒相当于图灵机,可使⽤任何的语法描述形式;
1型⽂法:也叫上下⽂有关⽂法,其描述能⼒相当于线性有界⾃动机,语法形式如下:xSy -> xAy。
也就是说,S推导出A是和上下⽂x, y相关的,即S只有在上下⽂x, y的环境中才能推导出A;
2型⽂法:也叫上下⽂⽆关⽂法,其描述能⼒相当于下推⾃动机,语法形式如下:S -> A。
S可以⽆条件的推导出A,和上下⽂⽆关,上下⽂⽆关⽂法因此得名;
3型⽂法:也叫正则⽂法,等价于正则表达式,其描述能⼒相当于有穷⾃动机,语法形式如下:S -> Aa。
其中最后⼀个a必须为⾮终结符。
chomsky一二三型文法
chomsky一二三型文法
上世纪50年代,美国语言学家诺姆·乔姆斯基(Noam Chomsky)提出了一套分类文法的方法,即乔姆斯基文法,分为三种类型,分别被称为一型、二型和三型。
一型文法又称为上下文有关文法。
它的特点是产生式规则的左侧可包含一个或多个非终结符号,右侧则是非终结符号和终结符号的组合,且右侧的产生式规则必须根据上下文来进行分析。
一型文法可以描述一些自然语言的语言规则,但在实际应用中较少使用。
二型文法也被称为上下文无关文法。
它的产生式规则左侧只能是一个非终结符号,右侧可以是任意的终结符号和非终结符号的组合,且不需要根据上下文来分析。
二型文法被广泛应用于语言处理和编译器设计领域,如编程语言的语法分析和自然语言处理。
三型文法又称正则文法。
它的产生式规则左侧只能有一个非终结符号,右侧要么是一个终结符号,要么是一个非终结符号加上一个终结符号。
三型文法的规则比较简单,主要用于描述正则语言,如正则表达式和有限状态自动机。
乔姆斯基的这三种文法类型为形式语言的研究提供了重要的框架,对于语言、语言处理和计算机科学领域都具有重要的意义。
对应chomsky四种文法的四种语言之间的关系
对应chomsky四种文法的四种语言之间的关系NoamChomsky是20世纪最重要的语言学家之一。
他提出了一套语言理论,其中包括了四种文法类型。
这些文法在语言学研究中起着重要作用,因为它们提供了一种方式来描述不同类型的语言结构。
在本文中,我们将探讨这四种文法类型以及它们之间的关系。
1. 正则文法正则文法也称为类型3文法,是最简单的文法类型。
它由一组规则组成,这些规则定义了一种语言的基本结构。
正则文法可以描述一些简单的语言结构,例如正则表达式和有限自动机。
正则文法的语言特征是具有线性结构,其中每个符号只能出现一次。
这种文法的规则只能是一些形如A -> aB或者A -> a的形式。
其中A和B是非终结符,a是终结符。
正则文法只能描述一些简单的语言,例如a^n b^n,其中n是任意正整数。
这种语言可以使用有限自动机来识别。
2. 上下文无关文法上下文无关文法也称为类型2文法,它比正则文法更强大。
这种文法的规则可以定义为A -> α,其中A是一个非终结符,α是一个符号串。
这意味着一个非终结符可以被替换为任何符号串,而不管它周围的上下文是什么。
上下文无关文法可以描述一些复杂的语言结构,例如二元表达式和HTML文档。
上下文无关文法的语言特征是具有树形结构,其中每个符号可以出现多次。
这种文法的规则只能是一些形如A -> α的形式。
其中A是非终结符,α是一个符号串。
上下文无关文法可以描述一些复杂的语言,例如a^n b^n c^n,其中n是任意正整数。
这种语言可以使用语法分析器来识别。
3. 上下文相关文法上下文相关文法也称为类型1文法,它比上下文无关文法更强大。
这种文法的规则可以定义为αAβ -> αγβ,其中A是一个非终结符,α和β是符号串,γ是一个符号串,它可以替换A。
上下文相关文法可以描述一些非常复杂的语言结构,例如自然语言。
上下文相关文法的语言特征是具有树形结构,其中每个符号可以出现多次。
Chomsky 文法类型判断试验报告-推荐下载
如果对于某文法 G,P 中的每个规则具有下列形式: U :: = u
其中 U∈VN;u∈V+,则称该文法 G 为 2 型文法或上下文无关文法,简 写为 CFG。
按照这条规则,对于上下文无关文法,利用该规则进行推导时,无需考虑 非终结符 U 所在的上下文,总能用 u 替换 U,或者将 u 归约为 U,显示了上下 文无关的特点。
for(j=0;j<p[i].left.length();j++) //遍历产生式左部每一个字 符
{ if(p[i].left[j]>='A'&&p[i].left[j]<='Z') //判断字符是否 是非终结符 break; } if(j==p[i].left.length()) { cout<<"该文法不是0型文法"<<endl; return 0; break;
2 型文法所确定的语言为 2 型语言 L2,2 型语言可由非确定的下推自动机 来识别。
一般定义程序设计语言的文法是上下文无关的。如 C 语言便是如此。因此, 上下文无关文法及相应语言引起了人们较大的兴趣与重视。
4.3 型文法(正则文法,线性文法) 如果对于某文法 G,P 中的每个规则具有下列形式:
U :: = T 或 U :: = WT 其中 T∈VT;U,W∈VN,则称该文法 G 为左线性文法。 如果对于某文法 G,P 中的每个规则具有下列形式:
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电通,力1根保过据护管生高线产中0不工资仅艺料可高试以中卷解资配决料置吊试技顶卷术层要是配求指置,机不对组规电在范气进高设行中备继资进电料行保试空护卷载高问与中题带资2负料2,荷试而下卷且高总可中体保资配障料置各试时类卷,管调需路控要习试在题验最到;大位对限。设度在备内管进来路行确敷调保设整机过使组程其高1在中正资,常料要工试加况卷强下安看与全22过,22度并22工且22作尽22下可护都能1关可地于以缩管正小路常故高工障中作高资;中料对资试于料卷继试连电卷接保破管护坏口进范处行围理整,高核或中对者资定对料值某试,些卷审异弯核常扁与高度校中固对资定图料盒纸试位,卷置编工.写况保复进护杂行层设自防备动腐与处跨装理接置,地高尤线中其弯资要曲料避半试免径卷错标调误高试高等方中,案资要,料求编试技5写、卷术重电保交要气护底设设装。备备置管4高调、动线中试电作敷资高气,设料中课并技3试资件且、术卷料中拒管试试调绝路包验卷试动敷含方技作设线案术,技槽以来术、及避管系免架统不等启必多动要项方高方案中式;资,对料为整试解套卷决启突高动然中过停语程机文中。电高因气中此课资,件料电中试力管卷高壁电中薄气资、设料接备试口进卷不行保严调护等试装问工置题作调,并试合且技理进术利行,用过要管关求线运电敷行力设高保技中护术资装。料置线试做缆卷到敷技准设术确原指灵则导活:。。在对对分于于线调差盒试动处过保,程护当中装不高置同中高电资中压料资回试料路卷试交技卷叉术调时问试,题技应,术采作是用为指金调发属试电隔人机板员一进,变行需压隔要器开在组处事在理前发;掌生同握内一图部线纸故槽资障内料时,、,强设需电备要回制进路造行须厂外同家部时出电切具源断高高习中中题资资电料料源试试,卷卷线试切缆验除敷报从设告而完与采毕相用,关高要技中进术资行资料检料试查,卷和并主检且要测了保处解护理现装。场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
Chomsky文法体系分类
Chomsky文法体系分类文法G(Grammar)是一个四原组,G=(N,T,P,S),N(Non-teinator)是非终结符集合,T(Terminator)是终结符集合,P(Proction)是产生式集合,S(Start)是起始符其中: N 交 T = 空集 P 是形式为 - 的产生式(N T)*N+(N T)*,也就是说中必需有一个非终结符 (N T)* ,也就是说可以是空串 S N 1型文法又称上下文有关文法。
生成式形式为 - , 且 | | | | 并且不存在 A- ε 2型文法又称上下文无关文法。
生成式形式为 A- ,即左边必需惟独一个非终结符 3型文法又称文法。
生成式 A- wB或A- w,称为右线性文法生成式 A- Bw或A- w,称为左线性文法 0型文法对生成式没有任何限制的文法称为0型文法。
从0到3都是包含的关系,但是有特例,包含A- ε 产生式的2,3型文法不属于1型文法。
四种文法产生的语言分离称为上下文有关语言,上下文无关语言,正则语言,无限制性语言。
2型语言的表示法 2型语言是很重要的一种语言,除了用四元组的办法表示,此处再介绍两种表示办法。
当人们要说明或者研究程序设计语言本身时,常常又需要一种语言,被研究的语言叫做对象语言,即某种程序设计语言,研究对象语言的语言称为元语言,即元语言是描述语言的语言。
BNF范式通常被作为研究某种程序设计语言语法的元语言,而语法图是与BNF范式的描述能力等价的另一种文法表示形式,因其直观性而常常采纳。
(1)巴科斯范式(Backus Normal Form,BNF) 2型文法生成式左端惟独一个非终结符,所以可以把左端相同的生成式合并在一起,右端用|隔开,用::=代替- ,全部非终结符用括起来,这是Backus为了描述AIGOL语言首次提出并用法的。
用BNF描述十进制整数的生成语法:无符号整数 ::= 数字 | 数字无符号整数数字 ::= 0|1|2|3|4|5|6|7|8|9 (2)语法图语法图有四种基本形式 (3)推导树 2型文法还常常用推导树表示第1页共1页。
乔姆斯基文法
乔姆斯基文法
乔姆斯基文法(Chomsky Grammar)是由语言学家诺姆·乔姆斯基(Noam Chomsky)提出的一种形式语言描述工具,用于描述自然语言的句法结构。
乔姆斯基文法属于生成文法的一种,它描述了生成自然语言句子所需的规则和限制。
乔姆斯基文法包括以下几个重要的组成要素:
终结符(Terminals):代表语言中的实际词汇或符号。
终结符是语法分析过程中不再分解的最基本的符号。
非终结符(Non-terminals):代表语法规则中的符号或变量。
非终结符可以根据文法规则被替换为终结符或其他非终结符。
产生式规则(Production Rules):定义了语言中句子的构成规则。
每个产生式由一个非终结符和一个由非终结符和终结符组成的序列构成。
产生式描述了如何从一个符号推导到另一个符号。
开始符号(Start Symbol):定义了语法的起始点。
所有的句子都是从开始符号开始推导生成的。
乔姆斯基文法根据产生式规则的形式特点,分为以下几个类型:
0型文法(无约束文法):产生式的左侧可以是任意符号串,右侧可以是任意符号串。
1型文法(上下文有关文法):产生式的左侧可以是任意非终结符,右侧可以是任意符号串。
2型文法(上下文无关文法):产生式的左侧只能是单一非终结符,右侧可以是任意符号串。
3型文法(正则文法):产生式的左侧只能是单一非终结符,右侧可以是终结符和非终结符的串。
乔姆斯基文法提供了一种形式化的方式来描述语言的结构,它被广泛应用于自然语言处理、编译器设计和计算机语言的形式化描述等领域。
安徽大学编译原理实验一Chomsky文法类型判断
实验一:文法类型判断实验日期:2012.4.13 教师签字:成绩:名称: Chomsky文法类型判断实验目的:一.掌握四种文法类型的定义,及其区别;二.熟悉各种文法类型的判断,能够快速按照要求写出对应文法类型的文法用例.实验原理:一.0型文法,产生式左右部可以使用"非终结符"和"终结符"随意组合,但左部不能为空;二.1型文法,在0型文法的基础上,要求右部的符号长度大于左部(空除外);三.2型文法,在1型文法的基础上,要求左部必须由非终结符号组成,且左部只能拥有一个非终结符;四.3型文法,在2型文法的基础上,产生式必须型如:A->Aa|a 或A->aA|a;实验内容:1.实验要求:输入一组任意的规则,输出相应的Chomsky 文法的类型。
0型文法判别:1型文法判别:2型文法判别:3型文法判别:程序代码:/*SID:E10914012NAME:杨翔宇PROG:CHINT:判断Chomsky文法类型*/#include<stdio.h>#include<string.h>#include<ctype.h>struct node{char left[30],right[30];intleftlen,rightlen,startleft,startright;}n[1000];int t0=0,t1=0,t2=0,t3=0;int main(){inti,j,k,p,q,count=0,pos=0,poslowlast=0,countflag=0,flag0=0,flag1=0,flag2 =0,flag3=0,true3=0,ff=0,rnew=0,ll;char left[30],right[30],flagprogram[100],flag[100];printf("请输入合法的文法表达式,直到文件结束,其中\"定义为\"符号用\"->\"表示\",空子用'^'表示:\n");while(~scanf("%s",flagprogram))//等价于EOF结束{for(i=0;i<strlen(flagprogram);i++){if(flagprogram[i]=='-'){pos=i;break;}}for(j=0;j<pos;j++)n[count].left[n[count].leftlen++]=flagprogram[j];for(k=pos+2;k<strlen(flagprogram);k++)n[count].right[n[count].righ tlen++]=flagprogram[k];count++;}for(i=0;i<count;i++){if(isupper(n[i].left[0]))flag0=1;//如果至少有一个产生式左部中至少含有一个非终结符,则为0型n[i].leftlen=strlen(n[i].left);n[i].rightlen=strlen(n[i].right);if(n[i].leftlen<=n[i].rightlen)flag1++;//如果每个产生式的右部长度均大于等于左部长度,这为1型if(n[i].leftlen==1&&isupper(n[i].left[0]))flag2++;//如果每个产生式左部都为一个非终结符,则此文法为2型的poslowlast=0;if(isupper(n[i].right[0])||n[i].right[0]=='^')true3=1;else{while(!isupper(n[i].right[poslowlast])&&poslowlast<n[i].rightlen)posl owlast++;}for(k=poslowlast;k<n[i].rightlen;k++)if(!isupper(n[i].right[k])||isupper(n[i].right[0]))true3=1;}if(flag0)t0=1;//判断0型文法else{printf("输入错误,左部无非终结符\n");return 0;}if(flag1==count)t1=1;if(flag2==count)t2=1;if(flag2==count&&!true3)t3=1;if(t0==1&&!t1&&!t2&&!t3)printf("此文法是一个0型文法\n");if(t1==1&&!t2&&!t3)printf("此文法是一个1型文法\n");if(t2==1&&!t3)printf("此文法是一个2型文法\n");if(t3==1)printf("此文法是一个3型文法\n");return 0;}。
实验一Chomsky文法类型的判断
实验一:chomsky文法类型的判断2012/4/20实验一:chomsky文法类型的判断实验目的:1.熟练掌握四种文法类型的概念及区别。
2.设计一个Chomsky文法类型判别器,判断0型、1型、2型和3型文法。
实验要求:输入一组任意的规则,输出相应的Chomsky文法的类型。
实验原理:1.设G=(Vn,Vt,P,S),如果它的每个产生式α->β是这样一种结构:α∈(Vn∪Vt)*且至少含有一个非终结符,而β∈(Vn∪Vt)*,则G 是一个0型文法。
2.设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式α->β均满足|β|>=|α|,仅仅S->ԑ除外,则文法G是1型或上下文有关的。
3.设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式α->β均满足:α是一个非终结符,β∈(Vn∪Vt)*,则此文法称为2型的或上下文无关的。
4. 设G=(Vn,Vt,P,S)为一文法,若P中的每一个产生式的形式都是A->aB 或A->a,其中A和B都是非终结符,a∈Vt*,则G是3型文法或正规文法。
5.4个文法类的定义是逐渐增加限制的,因此可采用自顶向下的算法。
实验内容:1.程序清单如下:#include<iostream>#include<string>using namespace std;typedef struct CSS //定义一个产生式结构体{string left; //定义产生式的左部string right; //定义产生式的右部}CSS;bool Zero(CSS *p,int n) //判断0型文法{int i,j;for(i=0;i<n;i++) //循环n次,即遍历所有产生式{for(j=0;j<p[i].left.length();j++) //遍历产生式左部每一个字符{if(p[i].left[j]>='A'&&p[i].left[j]<='Z') //判断字符是否是非终结符 break;}if(j==p[i].left.length()){cout<<"该文法不是0型文法"<<endl;return 0;break;}}if(i==n)return 1;//如果每个产生时都能找到非终结符}bool First(CSS *p,int n) //判断1型文法{int i;if(Zero(p,n)) //先判断是否是0型文法{for(i=0;i<n;i++){if((p[i].left.length()>p[i].right.length())&&p[i].right.length()!=NULL) //判断产生式左部长度是否大于右部break;}if(i==n)return 1;else{cout<<"该文法是0型文法"<<endl;return 0;}}elsereturn 0;}bool Second(CSS *p,int n) //判断2型文法{int i;if(First(p,n)) //同上,先判断低级文法是否成立{for(i=0;i<n;i++) //同上,遍历所有文法产生式{if((p[i].left.length()!=1)|| !(p[i].left[0]>='A'&&p[i].left[0]<='Z')) //判断产生式左部长度是否为一,左部第一个是否是非终结符break;}if(i==n)return 1;else{cout<<"该文法是1型文法"<<endl;return 0;}}elsereturn 0;}void Third(CSS *p,int n) //判断3型文法{int i;if(Second(p,n)) //同上,先判断是否是2型文法{for(i=0;i<n;i++) //同上,遍历文法所有的产生式{if((p[i].right.length()==0)||(p[i].right.length()>=3)||(p[i].right[0]>='A'& &p[i].right[0]<='Z')) //判断产生式右部字符个数是否在12之间,判断右部第一个字符是否是非终结符break;}if(i==n){for(i=0;i<n;i++){if(p[i].right.length()==2){if(!(p[i].right[1]>='A'&&p[i].right[1]<='Z'))break;}}if(i==n){cout<<"该文法属于3型文法"<<endl;}elsecout<<"该文法属于2型文法"<<endl;}else cout<<"该文法属于2型文法"<<endl;}elsecout<<"结束"<<endl;}void main( ){int i,j,n;string input;cout<<"请输入文法产生式个数N:";cin>>n;CSS *p=new CSS[n]; // 初始化产生式数组for(i=0;i<n;i++) //输入产生式数组{input.erase(); //清除cin>>input; //输入for(j=0;j<input.length();j++)//改变输入数据的形式{if(input[j]=='-'){p[i].left=input.substr(0,j);p[i].right=input.substr(j+2,input.length());}}}Third(p,n); //调用文法类型判断,自顶向下system("pause");}2.程序运行结果:测试用例1:7S->aSBES->aBEEB->BaB->abbB->bbbE->beeE->ee运行结果:测试用例2:1型文法:7S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->ee运行结果:测试用例3:2型文法:9S->aABA->bBS->bBB->bBS->aB->bA->aAB->aA->aS运行结果见下页:测试用例4:3型文法:9S->aAA->bBS->bBB->bBS->aB->bA->aAB->aA->aS运行结果:。
Chomsky文法判别
实验名称:生成Chomsky文法输入:一组任意的文法规则输出:相应的Chomsky文法要求:1)文法的输入应简便2)指明是哪一类Chomsky文法,给出相应的四元组形式。
一实验原理:乔姆斯基把文法分成四种类型,即0型1型2型3型。
设G=(VN, VT, P, S), 如果它的每个产生式α→β是这样一种结构:α∈(VN∪VT)* 且至少含有一个非终结符,而β∈(VN∪VT)* 则G是一个0型文法设G=(VN, VT, P, S)为一文法,若P中的每一个产生式α→β均满足|β|≥|α|,仅仅S→ε除外,则文法G是1型或上下文有关的。
设G=(VN, VT, P, S),若P中的每一个产生式α→β满足α是一个非终结符,β∈(VN∪VT)*,则此文法称为2型的或上下文无关的。
设G=(VN, VT, P, S),若P中的每一个产生式的形式都是A→aB 或A→a(右线性)或(A→a, A→Ba 左线性),其中A和B都是非终结符,a∈VT* ,则G是3型文法或正规文法。
二相关数据结构定义:static char VN[10]={'!'};//非终结符集合最多10个(假设均为大写字母)static char VT[10]={'A'};//终结符集合最多为10个(为a,b,c....x,y,z,0,1.....9)static char p[20][20];//产生式规则,最多20个//记录每个产生式的左右部分的位置结构体typedef struct{int left; //分别表示产生式左边最后一个字符的位置int right; //和右边第一个字符的位置int n; //n为整个产生式字符串的最后一个字符的下标}position;三关键函数:1.//判断字符str是否在字符串p中存在,存在则返回0int search_chr(char *p,char str);2.//判断文法的类型int judge_Chomsky(int n,position pp[]);四实验代码#include<iostream>#include<string.h>using namespace std;static char VN[10]={'!'};//非终结符集合最多10个(假设均为大写字母)static char VT[10]={'A'};//终结符集合最多为10个(为a,b,c....x,y,z,0,1.....9)static char p[20][20];//产生式规则,最多20个//记录每个产生式的左右部分的位置结构体typedef struct{int left,right;int n;}position;position pp[20];//判断字符str是否在字符串p中存在,存在则返回0int search_chr(char *p,char str){int n=strlen(p);for(int i=0;i<n;i++){ if(str==p[i])return 0;}return 1;}//判断文法的类型int judge_Chomsky(int n,position pp[]){int flag1,flag2,flag3,flag4,i,j;//各文法的判断标志初始时为0 int left=0,right=0;flag1=flag2=flag3=flag4=0;for(i=0;i<n;i++){for(j=0;j<=pp[i].left;j++){if(search_chr(VN,p[i][j])==0)break;}if(j>pp[i].left){return -1; //不满足0型文法条件}}flag1=1;if(flag1){for(i=0;i<n;i++){int t=pp[i].n-pp[i].right-pp[i].left;if((pp[i].left==0)&&(p[i][0]=='S')){}else{if(t<0)return 0;}}}flag2=1;if(flag2)for(i=0;i<n;i++){if(pp[i].left!=0)return 1;else{if(search_chr(VN,p[i][0])==0)continue;else if(search_chr(VN,p[i][0])!=0){ return 1;}}}}flag3=1;if(flag3){for(i=0;i<n;i++){if((pp[i].n-pp[i].right==0)&&(search_chr(VT,p[i][pp[i].right])==0)) continue;else if(pp[i].n-pp[i].right==1){if((search_chr(VT,p[i][pp[i].right])==0)&&(search_chr(VN,p[i][pp[i]. right+1])==0)){ right=1;break;}elseif((search_chr(VT,p[i][pp[i].right+1])==0)&&(search_chr(VN,p[i][pp[i].r ight])==0)){ left=1; break;}}}if(left){for(i=0;i<n;i++){if((pp[i].n-pp[i].right==0)&&(search_chr(VT,p[i][pp[i].right])==0))continue;if(pp[i].n-pp[i].right==1){if((search_chr(VN,p[i][pp[i].right])==0)&&(search_chr(VT,p[i][pp[i]. right+1])==0))continue;else{return 2;}}if(pp[i].n-pp[i].right!=1){return 2;}}}else if(right){for(i=0;i<n;i++){if((pp[i].n-pp[i].right==0)&&(search_chr(VT,p[i][pp[i].right])==0))continue;if(pp[i].n-pp[i].right==1){if((search_chr(VT,p[i][pp[i].right])==0)&&(search_chr(VN,p[i][pp[i].rig ht+1])==0))continue;else{return 2;}}if(pp[i].n-pp[i].right!=1){return 2;}}}}return 3;}main(){int n,i,j=0,k1=0,k2=0;//k1为非终结符的个数,k2为终结符个数cout<<"请输入产生式规则的项数(<=20):"<<endl;cin>>n;cout<<"请输入"<<n<<"条"<<"产生式规则:"<<endl;for( i=0;i<n;i++){scanf("%s",&p[i]);char str[20];strcpy(str,p[i]);int m;for(m=0;m<strlen(str);m++)if(str[m]=='-')break;pp[i].n=strlen(str)-1;pp[i].left=m-1;pp[i].right=m+2; //记录产生式左右位置for(j=0;j<strlen(str);j++)// 存入非终结符{if(str[j]<='Z'&&str[j]>='A'&&(search_chr(VN,str[j])))VN[k1++]=str[j];}for(j=0;j<strlen(str);j++)//存入终结符{if(str[j]<='z'&&str[j]>='a'&&(search_chr(VT,str[j]))) VT[k2++]=str[j];else if(str[j]<='9'&&str[j]>='0'&&(search_chr(VT,str[j])))VT[k2++]=str[j];}}if(judge_Chomsky(n, pp)==-1){cout<<"此产生式不能构成任何文法"<<endl;}else{cout<<"文法的类型为:"<<judge_Chomsky(n, pp)<<endl;cout<<"此文法的四元组形式为: G=({";for(i=0;i<k1-1;i++)cout<<VN[i]<<",";cout<<VN[i]<<"}"<<","<<"{";for(i=0;i<k2-1;i++)cout<<VT[i]<<",";cout<<VT[i]<<"}"<<","<<"P,S)"<<endl;}return 0;}五实验结果和测试用例:3型文法来自书本例3.5(39页)S->0AS->1BS->0A->0AA->0SA->1BB->1BB->1B->02型文法来自书本例3.4(39页)S->aBS->bAA->aA->aSA->bAAB->bB->bSB->aBB1型文法来自书本例3.3(37页)S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->ee包含S->ε的1型文法例子为S->aSBES->aBEEB->BEaB->abS->0型文法修改上述1型例子后S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->e包含S->ε的0型文法例子为S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->eS->非上述文法S->aSBES->aBEEB->BEaB->abbB->bbbE->bee->f六遇到的问题及结果分析主要问题为给出哪一类Chomsky文法后还需给出相应的四元组形式。
文法的分类【编译原理】编译原理4种文法类型
⽂法的分类【编译原理】编译原理4种⽂法类型1956年,Chomsky建⽴形式语⾔的描述。
通过对产⽣式的施加不同的限制,Chomsky把⽂法分为4种类型 ⾸先定义⼀个产⽣式 α→β0型⽂法定义:0型⽂法(PSG):α∈(V N∪V T)* ,且⾄少含⼀个V Nβ∈(V N∪V T)*对产⽣式没有任何限制例如:A0→A0 , A1→B0型⽂法说明:0型⽂法也称为短语⽂法。
⼀个⾮常重要的理论结果是,0型⽂法的能⼒相当于图灵机(Turing)。
或者说,任何0型语⾔都是递归可枚举的;反之,递归可枚举集必定是⼀个0型语⾔。
对0型⽂法产⽣式的形式作某些限制,以给出1,2和3型⽂法的定义。
(注意)⽂法G 定义为四元组(V N ,V T ,P,S)¨V N:⾮终结符集¨V T:终结符集¨P :产⽣式集合(规则集合)¨S :开始符号(识别符号)1型⽂法(上下⽂有关⽂法context-sensitive): 对任⼀产⽣式α→β,都有|β|>=|α|,仅仅 S→ε除外 产⽣式的形式描述:α1Aα2→α1βα2 (其中,α1、α2、β∈(V N∪V T)*,β≠ε,A∈VN) 即:A只有出现在α1α2的上下⽂中,才允许⽤β替换。
产⽣的语⾔称“上下⽂有关语⾔”但S不能出现在产⽣式的右部。
例如:0A0→011000 1A1→1010112型⽂法(CFG):对任⼀产⽣式α→β,都有α∈V N,β∈(V N∪V T)* 产⽣式的形式描述:A→β(A∈V N) 即β取代A时,与A所处的上下⽂⽆关。
产⽣的语⾔称“上下⽂⽆关语⾔” 例如:G[S]:S→01 S→0S13型⽂法(RG):也称正规⽂法 每个产⽣式均为 “A→aB”或“A→a” —— 右线性 “A→Ba”或“A→a” —— 左线性 其中,A、B∈V N,a∈V T* 产⽣的语⾔称“正规语⾔” 例如:G[S]: S→0A | 0 A→1B | B B→1 | 04个⽂法类的定义是逐渐增加限制的,因此每⼀种正规⽂法都是上下⽂⽆关的,每⼀种上下⽂⽆关⽂法都是上下⽂有关的,⽽每⼀种上下⽂有关⽂法都是0型⽂法。
文法判别实验报告
设G=(VN,VT,P,S),如果它的每个产生式α β均满足:|β| ≥ |α|,仅仅Sε除外,则文法G是1型文法(上下文有关文法,上下文敏感文法),简称CSG。
3)、2型文法——上下文无关文法
设G=(VN,VT,P,S),如果它的每个产生式α β均满足:α是一个非终结符,β∈V*,则文法G是2型文法(上下文无关文法),简称CFG。
有时将2型文法的产生式表示为Aβ的形式,其中A∈VN,也就是用β取代非终结符A时,与A所在的上下文无关,因此取名为上下文无关。
4)、3型文法——正规文法
设G=(VN,VT,P,S),如果它的每个产生式AαB或Aα(A Bα或Aα),其中A和B都是非终结符,α∈VT*,则文法G是3型文法(正规文法,正则文法,有穷状态文法),简称RG。
}
2)、结果
输入:
S->aSBES->aBEEB->BEaB->abbB->bbbE->beeE->ee
输入:
S->aB S->bA A->a A->aS A->bAA B->b B->bS B->aBB
输出:
姓名xxx
文法类型的判别
1.实验目的
输入一组文法规则,判定它是哪一种文法。
2.实验原理
乔姆斯基(Chomsky)于1956年建立形式语言的描述
他把文法分成:0型、1型、2型、3型
1)、0型文法——短语文法
设G=(VN,VT,P,S),如果它的每个产生式α β是这样一种结构:α∈(VN∪VT)*且α至少包含一个非终结符, β∈(VN∪VT)*,则G是一个0型文法(短语结构文法、无限制文法),简称PSG。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理实验报告实验名称Chomsky文法类型判断实验时间2014.04.02院系计算机科学与技术学院班级XXXXXXXXX学号XXXXXXX姓名XXXX1.试验目的:上机实验有助于我们发现理论课学习中无法发现的问题,通过上机实验操作,进一步加深对理论课所学的“Chomsky文法类型判断”的理解,同时提升自己的编程能力,为以后的学习打下良好的基础。
2.实验原理① 0型文法(短语文法)如果对于某文法G,P中的每个规则具有下列形式:u -> v其中u∈V+,v∈V*,则称该文法G为0型文法或短语文法,简写为PSG。
0型文法或短语结构文法的相应语言称为0型语言或短语结构语言L。
这种文法由于没有其他任何限制,因此0型文法也称为无限制文法,其相应的语言称为无限制性语言。
任何0型语言都是递归可枚举的,故0型语言又称递归可枚举集。
这种语言可由图灵机(Turning)来识别。
② 1型文法(上下文有关文法)如果对于某文法G,P中的每个规则具有下列形式:xUy -> xuy其中U∈VN;u∈V+;x,y∈V*,则称该文法G为1型文法或上下文有关文法,也称上下文敏感文法,简写为CSG。
1型文法的规则左部的U和右部的u具有相同的上文x和下文y,利用该规则进行推导时,要用u替换U,必须在前面有x和后面有y的情况下才能进行,显示了上下文有关的特性。
1型文法所确定的语言为1型语言L1,1型语言可由线性有界自动机来识别。
③ 2型文法(上下文无关文法)如果对于某文法G,P中的每个规则具有下列形式:U -> u其中U∈VN;u∈V+,则称该文法G为2型文法或上下文无关文法,简写为CFG。
按照这条规则,对于上下文无关文法,利用该规则进行推导时,无需考虑非终结符U所在的上下文,总能用u替换U,或者将u归约为U,显示了上下文无关的特点。
2型文法所确定的语言为2型语言L2,2型语言可由非确定的下推自动机来识别。
一般定义程序设计语言的文法是上下文无关的。
如C语言便是如此。
因此,上下文无关文法及相应语言引起了人们较大的兴趣与重视。
④ 3型文法(正则文法,线性文法)如果对于某文法G,P中的每个规则具有下列形式:U -> T 或 U -> WT其中T∈VT ;U,W∈VN,则称该文法G为左线性文法。
如果对于某文法G,P中的每个规则具有下列形式:U ->= T 或 U -> TW其中T∈VT ;U, W∈VN,则称该文法G为右线性文法。
左线性文法和右线性文法通称为3型文法或正则文法,有时又称为有穷状态文法,简写为RG。
按照定义,对于正则文法应用规则时,单个非终结符号只能被替换为单个终结符号,或被替换为单个非终结符号加上单个终结符号,或者被替换为单个终结符号加上单个非终结符号。
3型文法所确定的语言为3型语言L3,3型语言可由确定的有限状态自动机来识别。
在常见的程序设计语言中,多数与词法有关的文法属于3型文法。
可以看出,上述4类文法,从0型到3型,产生式限制越来越强,其后一类都是前一类的子集,而描述语言的功能越来越弱,四类文法及其表示的语言之间的关系可表示为:0型⊃1型⊃2型⊃3型;即L0⊃ L1⊃ L2⊃ L33.实验内容输入:一组任意的规则。
输出:相应的Chomsky 文法的类型。
注意事项:⑴文法的输入应简便。
⑵指明是哪一类Chomsky文法,并给出相应的四元组形式:G=(V N,V T,P,S)。
说明:简单起见,可以不考虑0型文法类。
4.实验心得本次实验,我最大的体会就是我们不仅要熟练地掌握书本上的知识,更重要的是能够把学到的知识应用到上机编程中,这样才能算是真正学会了书本上所讲的知识。
在编写代码的过程中,我发现自己对3型文法的概念没有理解清楚,认为在对某个3型文法进行判断时,可以同时使用左线性文法和右线性文法,结果实际测试的过程中发现了错误,后来向别的同学请教及时发现并改正了错误;在对文法的各个要素进行输入的过程中,我也遇到了问题,主要是各种输入非法的情况考虑不周全,后来经过改正,修改了自己发现的所有错误,并及时改正了在测试中发现的问题,但仍无法保证所有的边界情况都考虑周全,这也是本实验所欠缺的地方,以后我会继续努力。
我想,学习是个持之以恒的过程,如果真正想学好编译原理的话,光靠实验课的时间是远远不够的,所以以后我一定要加强学习,坚持不懈,一切努力都是值得的。
5.实验代码与结果本实验使用java语言编写,编程工具是eclipse,实验运行结果如下:⑴几种非法输入测试①产生式左部不含有非终结符:②产生式的左部含有非法字符。
还有一些其他的非法输入,在此就不一一举例。
⑵正确的输入:①数据一:(3型文法)G=({S, A, B}, {1, 2}, P, S) ,P={S->1A, S->1, A->2B, B->1B, B->2S };首先是数据的输入:输入包括:非终结符集和终结符集的输入、产生式的个数、依次输入产生式的左部和右部以及开始符。
实验结果:②数据二:(2型文法)G=({S}, {0, 1}, P , S) ,P={ S->0S1, S->01 }; 数据的输入:实验结果:实验源代码如下:i mport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;;public class Chomsky{String[] left=new String[10]; //产生式左部String[] right=new String[10]; //产生式右部String Vn=new String(); //非终结符集合String Vt=new String(); //终结符集合int[] type=new int[20]; //标记文法的类型char start; //开始符int count; //产生式的个数boolean mark1=true,mark2=true;public void GetIn(BufferedReader f) //输入方法{try{boolean mark=true;System.out.println("||实验一:Chomsky文法类型判断||\n");System.out.println("请输入非终结符集Vn:");Vn=f.readLine();System.out.println("请输入终结符集Vt:");Vt=f.readLine();String V=Vn+Vt;System.out.println("请输入产生式的个数:");String s=f.readLine();count=Integer.parseInt(s);for(int i=0;i<count;i++) //输入产生式左部{System.out.println("请输入第"+(i+1)+"个产生式的左部:");left[i]=f.readLine();if((IsVh(left[i],V))==true){for(int j=0;j<left[i].length();j++){if(IsChar(left[i].charAt(j),Vn)==true){mark=true;break;}if((j+1)==left[i].length())mark=false;}}else{System.out.println("输入非法!");System.exit(0);}}if(mark==false){System.out.println("产生式左部皆为终结符号,输入非法!");System.exit(0);}for(int i=0;i<count;i++) //输入产生式右部{System.out.println("请输入第"+(i+1)+"个产生式的右部:");right[i]=f.readLine();if(right[i]!=null){if((IsVh(right[i],V))==false){System.out.println("输入非法!");System.exit(0);}}}System.out.println("请输入开始符:");start=(char)f.read();for(int i=0;i<count;i++){if(IsChar(start,left[i])==true){if(IsChar(start,Vn)==true){break;}else{System.out.println("开始符为终结符,输入非法!");System.exit(0);}}else{if((i+1)==count){System.out.println("产生式左部不含有开始符,输入非法!");System.exit(0);}}}System.out.println("输入成功!\n");OutPut();}catch(IOException e){System.err.println("发生异常:"+e);e.printStackTrace();}}public void OutPut() //输出方法{System.out.println("生成的文法G为:");System.out.print("G=({");for(int i=0;i<Vn.length();i++){System.out.print(Vn.charAt(i));if((i+1)!=Vn.length())System.out.print(",");}System.out.print("},{");for(int i=0;i<Vt.length();i++){System.out.print(Vt.charAt(i));if((i+1)!=Vt.length())System.out.print(",");}System.out.println("},P,"+start+")");System.out.print("P={");for(int i=0;i<count;i++){System.out.print(left[i]+"->"+right[i]);if((i+1)!=count)System.out.print(", ");}System.out.println("};");Recognize();}public void Recognize() //判别方法{for(int i=0;i<count;i++){if(right[i].length()>=left[i].length()) //1型文法判别条件{type[i]=1;if(IsVh(left[i],Vn)==true&&(left[i].length()==1)) //2型文法判别条件{type[i]=2;if(right[i].length()==1&&IsChar(right[i].charAt(0),Vt))type[i]=3;if(right[i].length()==2&&mark1==true){if(IsChar(right[i].charAt(0),Vt)&&IsChar(right[i].charAt(1),Vn))type[i]=3;elsetype[i]=2;mark2=false;}if(right[i].length()==2&&mark2==true){if(IsChar(right[i].charAt(0),Vn)&&IsChar(right[i].charAt(1),Vt))type[i]=3;elsetype[i]=2;mark1=false;}}elsetype[i]=1;}elsetype[i]=0;}int min=type[0];for(int i=1;i<count;i++){if(type[i]<=min)min=type[i];}System.out.println("G是"+min+"型文法.");}public boolean IsVh(String str,String Vh) //判断字符串是否在某个集合中{for(int j=0;j<str.length();j++){for(int k=0;k<Vh.length();k++){if(str.charAt(j)==Vh.charAt(k))break;if((k+1)==Vh.length())return false;}}return true;}public boolean IsChar(char c,String Vh) //判断字符是否在某个集合中{for(int k=0;k<Vh.length();k++){if(c==Vh.charAt(k))break;if((k+1)==Vh.length())return false;}return true;}public static void main(String args[]){Chomsky Cho=new Chomsky();BufferedReader f=new BufferedReader(new InputStreamReader (System.in));Cho.GetIn(f);}}11。