📄 text2.cpp
字号:
return i;
}
//构造分析表
void Parse::FormParseTable()
{
bool Mark = false;
int i=0,j=0,k=0,len=0;
char temp[30];
strcpy(temp,"\0");
Production pro;
ff = new FirstFollow[NumOfNonTeminal];
pt = new ParseTable(InputSymbol,NonTeminalSymbol);
//求出FIRST 和 Follow集合
for (i=0;i<NumOfNonTeminal;i++)
{
temp[len++] = NonTeminalSymbol[i];
temp[len] = '\0';
len = 0;
ff[i].ch = NonTeminalSymbol[i];
//求出FIRST 集合
strcpy(ff[i].first,First(temp));
//求出Follow集合
strcpy(ff[i].follow,Follow(NonTeminalSymbol[i]));
}
cout<<"\n"<<endl;
//输出FIRST 和 Follow集合
cout<<"\n First集合:";
for (i=0;i<NumOfNonTeminal;i++)
{
cout<<"\n First("<<ff[i].ch<<"):"<<ff[i].first;
}
cout<<endl;
cout<<"\n Follow集合:";
for (i=0;i<NumOfNonTeminal;i++)
{
cout<<"\n Follow("<<ff[i].ch<<"):"<<ff[i].follow;
}
cout<<endl;
//构造文法分析表
for (i=0;i<gra->GetNumOfGra();i++)
{
pro = gra->GetGrammar(i);
{
if (!IsInString(ff[GetPos(pro.From)].first,'e'))
{
len = strlen(ff[GetPos(pro.From)].first);
for (j=0;j<len;j++)
{
Mark = pt->Add(ff[GetPos(pro.From)].first[j],pro);
if (!Mark)//表示添加失败
{
cout<<"\n 在分析表的M["<<pro.From << "," <<ff[GetPos(pro.From)].first[j]<< "]项中已有产生式.";
cout<<"\n "<<pro.From<<"→"<<pro.To;
cout<<"和现在要添进的M["<<pro.From<< "," <<ff[GetPos(pro.From)].first[j]<< "]的产生式发生冲突!";
cout<<"\n 输入的文法不是LL1文法!" << endl;
getch();
exit(1);
}
}
}
else
{
if (IsInString(ff[GetPos(pro.From)].follow,'$'))
{
Mark = pt->Add('$',pro);
if (!Mark)//表示添加失败
{
cout<<"\n 在分析表的M["<<pro.From << ",$]项中已有产生式.";
cout<<"\n "<<pro.From<<"→"<<pro.To;
cout<<"和现在要添进的M["<<pro.From<< ",$]的产生式发生冲突!";
cout<<"\n 输入的文法不是LL1文法!" << endl;
getch();
exit(1);
}
}
else
{
len = strlen(ff[GetPos(pro.From)].follow);
for (j=0;j<len;j++)
{
Mark = pt->Add(ff[GetPos(pro.From)].follow[j],pro);
if (!Mark)//表示添加失败
{
cout<<"\n 在分析表的M["<<pro.From << "," <<ff[GetPos(pro.From)].first[j]<< "]项中已有产生式.";
cout<<"\n "<<pro.From<<"→"<<pro.To;
cout<<"和现在要添进的M["<<pro.From<< "," <<ff[GetPos(pro.From)].first[j]<< "]的产生式发生冲突!";
cout<<"\n 输入的文法不是LL1文法!" << endl;
getch();
exit(1);
}
}
}
}
}
}
}
//看是否是终结符
bool Parse::IsTeminal(char ch)
{
if (!isupper(ch))
{
return true;
}
else
{
return false;
}
}
//出错处理函数
void Parse::Error()
{
cout<<"\n ━━━━━━━┷━━━━━━━━━┷━━━━━━━━━";
cout<<"\n 检测出现错误! 你输入的字符串不是LL1文法。";
cout<<"\n 请按任意键继续......"<<endl;
getch();
}
//作出一个表达式在分析表下的动作
void Parse::MadeMoves(char * str)
{
int i,j;
int len=0,len1=0;
char temp;
bool flag = false;
char * stackTemp = new char [120];
char * strTemp = new char [120];
char ip;
Production pro;
stack<char> * st = new stack<char>(0);
stack<char> * strst = new stack<char>(0);
st->push('$');
len = strlen(str);
cout<<endl;
cout<<"\n 下面是对"<<str<<"进行分析所做的移动:";
cout<<"\n ━━━━━━━┯━━━━━━━━━┯━━━━━━━━━";
cout<<"\n STACK │ 输 入 │ 输 出 ";
cout<<"\n ━━━━━━━┿━━━━━━━━━┿━━━━━━━━━";
//把$加进去
strcat(str,"$");
strcpy(strTemp,str);
for (i=strlen(str)-1;i>=0;i--)
{
strst->push(str[i]);
}
len1 = 0;
stackTemp[len1++] = '$';
stackTemp[len1++] = gra->GetstartState();
stackTemp[len1] = '\0';
st->push(gra->GetstartState());
cout<<"\n "<<stackTemp;
for (j=0;j<13-(int)strlen(stackTemp);j++)
{
cout<<" ";
}
cout<<"│";
for (j=0;j<18-strst->length();j++)
{
cout<<" ";
}
cout<<strTemp<<"│";
flag = false;
i=0;
temp = st->GetTop();
while(str[i] != '$'&&(temp != '$'))
{
ip = str[i];
temp = st->GetTop();
if (IsTeminal(temp)||temp == '$')
{
if (temp == ip)
{
st->pop();
strst->pop();
i++;
for (int k=0;k<strst->length();k++)
{
strTemp[k] = str[k+i];
strTemp[k+1] = '\0';
}
stackTemp[len1-1] = '\0';
len1--;
//输出表格
cout<<"\n "<<stackTemp;
for (j=0;j<13-(int)strlen(stackTemp);j++)
{
cout<<" ";
}
cout<<"│";
for (j=0;j<18-strst->length();j++)
{
cout<<" ";
}
cout<<strTemp<<"│";
}
else
{
flag = true;
break;
}
}
else
{
if (!pt->IsEmpty(temp,ip))
{
pro = pt->GetProduction(temp,ip);
st->pop();
stackTemp[len1-1] = '\0';
len1--;
for (j=(int)strlen(pro.To)-1;j>=0;j--)
{
st->push(pro.To[j]);
stackTemp[len1++] = pro.To[j];
stackTemp[len1] = '\0';
}
//输出表格
cout<<"\n "<<stackTemp;
for (j=0;j<13-(int)strlen(stackTemp);j++)
{
cout<<" ";
}
cout<<"│";
for (j=0;j<18-strst->length();j++)
{
cout<<" ";
}
cout<<strTemp<<"│";
cout<<" "<<pro.From<<"→"<<pro.To;
}
else
{
flag = true;
break;
}
}
}
if (flag)
{
Error();
}
else
{
cout<<"\n ━━━━━━━┷━━━━━━━━━┷━━━━━━━━━";
cout<<"\n 检测成功! ";
cout<<endl;
}
delete stackTemp;
st->clear();
}
//输出分析表
void Parse::OutputParseTable()
{
pt->OutPut();
}
//执行主流程序
void Parse::Run()
{
char ch;
char Sentence[20];
//输入文法
GetGrammar();
//构造分析表
FormParseTable();
//输出分析表
OutputParseTable();
//作出一个表达式在分析表下的动作do
do
{
//输入表达式
cout<<"\n\n 请你输入你要验证的字符串:";
cin >>Sentence;
MadeMoves(Sentence);
cout<<"\n 是否继续进行测试?(Y/N): ";
cin >>ch;
}while(ch == 'y'||ch == 'Y');
cout<<"\n 按任意键退出....";
cout<<endl;
getch();
}
////////////////////////////////
//主函数
void main()
{
char ch;
do
{
//输入表达式
system("cls");
Parse parse;
parse.Run();
cout<<"\n 是否继续?(Y/N): ";
cin >>ch;
}while(ch == 'y'||ch == 'Y');
cout<<"\n 按任意键退出....";
cout<<endl;
getch();
}
///////////////////////////////////////////
//示例:
//文法:
//S→(A,A)
//A→a
//运行过程如下:
/*
2
S(A,A)
Aa
(a,a)
请你输入文法的条数:2
请输入你的文法
(如S→DEbase 终结符用小写,非终结符用大写,e表示空串)
1: S→(A,A)
2: A→a
你输入的文法是:
1: S→(A,A)
2: A→a
非终结符是:S A
终结符的:( , ) a
First集合:
First(S):(
First(A):a
Follow集合:
Follow(S):$
Follow(A):,)
LL1文法的预测分析表如下:
━━━┯━━━━━━━━━━━━━━━━━━━━
非终│ 输入字符
┝━━━━━━━━━━━━━━━━━━━━
结符│ ( , ) a $
━━━┿━━━━━━━━━━━━━━━━━━━━
S │S→(A,A) -- -- -- --
A │ -- -- -- A→a --
━━━┷━━━━━━━━━━━━━━━━━━━━
请你输入你要验证的字符串:(a,a)
下面是对(a,a)进行分析所做的移动:
━━━━━━━┯━━━━━━━━━┯━━━━━━━━━
STACK │ 输 入 │ 输 出
━━━━━━━┿━━━━━━━━━┿━━━━━━━━━
$S │ (a,a)$│
$)A,A( │ (a,a)$│ S→(A,A)
$)A,A │ a,a)$│
$)A,a │ a,a)$│ A→a
$)A, │ ,a)$│
$)A │ a)$│
$)a │ a)$│ A→a
$) │ )$│
$ │ $│
━━━━━━━┷━━━━━━━━━┷━━━━━━━━━
检测成功!
是否继续进行测试?(Y/N):
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -