📄 实验2.cpp
字号:
while(tmpChar != '#') { //求出产生式的个数
if(tmpChar == ';')
tmpIndex++;
fscanf(pFile,"%c",&tmpChar);
}
proNum = tmpIndex;
rewind(pFile);
for(int i = 0;i < proNum;i++) { //读出各产生式并置于已定义的数据结构ProNode中,
//同时可将非终结符置于非终结符号表
fscanf(pFile,"%c %c %c",&proNode[i].leftSym,&proNode[i].midSym[0],\
&proNode[i].midSym[1]);
proNode[i].midSym[2] = '\0';
fscanf(pFile,"%c",&tmpChar);
int j = 0;
while(tmpChar != ';') {
proNode[i].rightSym[j] = tmpChar;
fscanf(pFile,"%c",&tmpChar);
j++;
}
proNode[i].rightSym[j] = '\0';
proNode[i].length = j;
}
return true;
}
void PrintPro(ProNode proNode[],int proNum) { //显示产生式
for(int i = 0 ; i < proNum ; i++) {
cout<<proNode[i].leftSym<<proNode[i].midSym[0]<<proNode[i].midSym[1];
for(int j = 0; j < proNode[i].length;j++)
cout<<proNode[i].rightSym[j];
cout<<endl;
}
}
void SetUnTerminate(char UnTerminate[],ProNode proNode[],int proNum) {
//获得非终结符,存储于非终结符表
for(int i = 0; i < proNum; i++) { //从第一个产生式开始
bool flag = true;
int tmpLength = strlen(UnTerminate);
for(int j = 0; j <= tmpLength; j++) {
if(UnTerminate[j] == proNode[i].leftSym) { //若已存在,则进入下个产生式
flag = false;
break;
}
}
if(flag) {
UnTerminate[tmpLength] = proNode[i].leftSym; //将非终结符加入到非终结符表
UnTerminate[tmpLength + 1] = '\0';
}
}
}
void SetTerminate(char Terminate[],ProNode proNode[],int proNum) {
//获得终结符,存储于终结符表
int tmpLength;
bool flag ;
for(int i = 0; i < proNum; i++) { //从第一个产生式开始
for(int k = 0 ; k < proNode[i].length; k++) {
flag = true;
tmpLength = strlen(Terminate);
if(isupper(proNode[i].rightSym[k])) //若为非终结符号,则进入下一个字符
flag = false;
else if ( proNode[i].rightSym[k] == '^') {
int tmpLength = strlen(ProNull);
flag = false;
ProNull[tmpLength] = proNode[i].leftSym; //记录能产生空字符的产生式
ProNull[tmpLength + 1] = '\0';
}
else if(flag)
for(int j = 0; j <= tmpLength; j++) {
if(Terminate[j] == proNode[i].rightSym[k]) {
//若已存在,则进入下一个字符
flag = false;
break;
}
}
if(flag) { //将终结符加入到终结符表
Terminate[tmpLength] = proNode[i].rightSym[k];
Terminate[tmpLength + 1] = '\0';
}
}
}
}
int GetNumofUT(char UnTerminate[]) { //获得非终结符个数
return strlen(UnTerminate);
}
int GetNumofT(char Terminate[]) { //获得终结符个数
return strlen(Terminate);
}
bool IsNull(char c) { //非终结符能否产生空字符
int len = strlen(ProNull);
for(int i = 0;i < len;i++) {
if(ProNull[i] == c)
return true;
}
return false;
}
bool IsTerminate(char c) { //判断是否为终结符号
int num = GetNumofT(Terminate);
bool flag = false;
for(int i = 0 ; i < num; i++ ) {
if(Terminate[i] == c) {
flag = true;
break;
}
}
return flag;
}
int GetUTLoaction(char UnTerminate[],char c) { //获得非终结符在非终结符表中的位置
for(int i = 0 ; i < GetNumofUT(UnTerminate);i++)
if(UnTerminate[i] == c)
return i;
return -1;
}
int GetTLocaction(char Terminate[],char c) { //获得终结符在终结符表中的位置
for(int i = 0 ; i < GetNumofT(Terminate);i++)
if(Terminate[i] == c)
return i;
return -1;
}
void AddChar(char chArray[],char c) { //将非终结符的所有first值加入First集
bool flag = true;
int tmpLength = strlen(chArray);
for(int i = 0; i <= tmpLength; i++) {
if(chArray[i] == c) { //若已存在,则不加入
flag = false;
break;
}
}
if(flag) {
chArray[tmpLength] = c; //将first值加入First集
chArray[tmpLength + 1] = '\0';
}
}
void AddCharToChar(char chArray[],char otherArray[]) {
int otherLength = strlen(otherArray);
for(int j = 0 ; j < otherLength; j++) {
bool flag = true;
int tmpLength = strlen(chArray);
for(int i = 0; i <= tmpLength; i++) {
if(chArray[i] == otherArray[j]) { //若已存在,则不加入
flag = false;
break;
}
}
if(flag) {
chArray[tmpLength] = otherArray[j]; //将first值加入First集
chArray[tmpLength + 1] = '\0';
}
}
}
void First(ProNode proNode[],UnTInfo unTInfo[]) { //求出First集合
for(int i = proNum -1 ; i >= 0 ; i--) { //从最后一个产生式开始进行分析
char leftSym = proNode[i].leftSym;
char c = proNode[i].rightSym[0];
int leftSymLoc = GetUTLoaction(UnTerminate,leftSym);
if(IsNull(leftSym)) //如果产生式推出空字符,则把空字符加入First集合
AddChar(unTInfo[leftSymLoc].first,c);
else {
if(IsTerminate(c)) { //如果产生式右边第一个符号为终结符号
AddChar(unTInfo[leftSymLoc].first,c); //将符号加入First集合
}
else {
for(int k = 0; k < proNode[i].length; k++) {
if(!IsNull(proNode[i].rightSym[k])) {
//判断能否产生空字符,直到找到不为空的停止
break;
}
}
if(k == proNode[i].length)
//若对于产生式右边的一切非终结符,均可推出ε,则将ε加进FIRST集
AddChar(unTInfo[leftSymLoc].first,'^');
else {
for(int l = 0 ; l <k;l++) {
/*将产生式右边能推出空字符的非终结符的Frist集中不含ε的终结符加入到该非终结符的Fisrt集*/
char rightChar = proNode[i].rightSym[l];
int rightSymLoc = GetUTLoaction(UnTerminate,rightChar);
int firstLen = strlen(unTInfo[rightSymLoc].first);
for (int m = 0 ; m < firstLen; m++) {
if(unTInfo[rightSymLoc].first[m] != '^')
AddChar(unTInfo[leftSymLoc].first,unTInfo[rightSymLoc].first[m]);
}
}
/*将产生式右边不能推出空字符的非终结符的Frist集加入到该非终结符的Fisrt集*/
int rightSymLoc = GetUTLoaction(UnTerminate,proNode[i].rightSym[k]);
AddCharToChar(unTInfo[leftSymLoc].first,unTInfo[rightSymLoc].first);
}
}
}
}
}
void Follow(ProNode proNode[],UnTInfo unTInfo[]) { //计算各非终结符的Follow集
AddChar(unTInfo[0].follow,'#'); //开始符号,则把“#”加入FOLLOW中;
int numOfUnT = GetNumofUT(UnTerminate);
for(int i = 0; i < numOfUnT ; i++) {
for(int j = 0 ;j < proNum; j++) { //从第一个产生式开始进行分析,逐个进行扫描
bool flag = false ;
for(int k = 0 ; k < proNode[j].length; k++) {
flag = false;
if(UnTerminate[i] == proNode[j].rightSym[k]) //判断非终结符是否在产生式右边
flag = true;
if(flag) {
if((k == proNode[j].length - 1) || IsNull(proNode[j].rightSym[k+1])) {
//若B→αA 或B→αAβ,且β=>ε,则把FOLLOW(B)加入FOLLOW(A) 中
if(proNode[j].leftSym != UnTerminate[i]) {
int leftSymLoc = GetUTLoaction(UnTerminate,proNode[j].leftSym);
AddCharToChar(unTInfo[i].follow,unTInfo[leftSymLoc].follow);
}
}
if(proNode[j].rightSym[k+1] != '\0'){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -