⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text2.cpp

📁 语法分析关于first集和follow集。可运行可使用。自己看吧。没问题的。 还有不知为什么不能归为源码一栏 那个谁谁有空看下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        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 + -