編譯原理,自上而下非遞歸語法分析自上而下的語法分析

/*要求:1. 使用的文法如下(見編譯陳第三版):E TE E + TE | T FT T * FT | F (E) | id2. 對於任意給定的輸入串(詞法記號流)進行語法分析,遞歸下降方法和非遞歸預測分析方法可以任選其一來實現。3. 要有一定的錯誤處理功能。即對錯誤能提示,並且能在一定程度上忽略儘量少的記號來進行接下來的分析。可以參考書上介紹的同步記號集合來處理。可能的出錯情況:idid*id, id**id, (id+id, +id*+id ……4. 輸入串以#結尾,輸出推導過程中使用到的產生式。例如: 輸入:id+id*id# 輸出:E TE T FT F idE + TE T FT ……如果輸入串有錯誤,則在輸出中要體現是跳過輸入串的某些記號了,還是彈棧,彈出某個非終結符或者是終結符了,同時給出相應的出錯提示信息。比如:idid*id對應的出錯信息是:“輸入串跳過記號id,用戶多輸入了一個id”;id**id對應的出錯信息是:“彈棧,彈出非終結符F,用戶少輸入了一個id”(id+id對應的出錯信息是:“彈棧,彈出終結符 ) ,用戶少輸入了一個右括號(或者說,括號不匹配)”

*/ 
  #include <iostream> 
#include "textanalyse.h"
#include<string>
#include<stack>
using namespace std;
string nexttoken(int index,list <string> stringlist)
{
    int k=0;
     list<string>::iterator i;
           for (i = stringlist.begin(); i != stringlist.end(); ++i)
                 //測試
              // cout<<*i<<endl;
              {

                  if(k==index)
                  {
                      return *i;
                  }
                  k++;
              }
    return " ";

}
string str[5][6]={{"E→TE'"," "," ","E→TE'","synch","synch"},
					{" ","E'→+TE'"," "," ","E'→ε","E'→ε"},
					{"T→FT'","synch"," ","T→FT'","synch","synch"},
					{" ","T'→ε","T'→*FT'"," ","T'→ε","T'→ε"},
					{"F→id","synch","synch","F→(E)","synch","synch"}};;
static map<string ,int> tablenum;
void inittable()
{
    tablenum.insert(map<string,int>::value_type("id",0));
    tablenum.insert(map<string,int>::value_type("+",1));
    tablenum.insert(map<string,int>::value_type("*",2));
    tablenum.insert(map<string,int>::value_type("(",3));
    tablenum.insert(map<string,int>::value_type(")",4));
    tablenum.insert(map<string,int>::value_type("$",5));

}
stack<string> s;
int index=0;
int findtablevalue(string key)
{

   map<string,int >::iterator l_it;;
   l_it=tablenum.find(key);
   if(l_it==tablenum.end())
             return -1;
   else
    return l_it->second;

}
void analyse(list<string>a)
{
    int max=a.size();

    s.push("$");
    s.push("E");
    for(index=0;index<max;index++)
    {
        if(s.top()=="E"&&(nexttoken(index,a)=="id"))
           {
               cout<<str[0][0]<<endl;
               s.pop();
               s.push("E'");
               s.push("T");
               index--;
           }
        else if(s.top()=="E'"&&(nexttoken(index,a)=="id"))
           {
               cout<<"error,user input duplicated id,ignore id"<<endl;


           }
        else if(s.top()=="T"&&(nexttoken(index,a)=="id"))
           {
               cout<<str[2][0]<<endl;
               s.pop();
               s.push("T'");
               s.push("F");
               index--;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)=="id"))
        {
          cout<<"error,user input duplicated id,ignore id"<<endl;
        }
        else if(s.top()=="F"&&(nexttoken(index,a)=="id"))
           {
               cout<<str[4][0]<<endl;
                s.pop();
               s.push("id");

               index--;
           }
        else if(s.top()=="E"&&(nexttoken(index,a)=="+"))
        {
            cout<<"error,user input duplicated id,ignore +"<<endl;
        }
        else if(s.top()=="E'"&&(nexttoken(index,a)=="+"))
           {
               cout<<str[1][1]<<endl;
               s.push("E'");
               s.push("T");
               s.push("+");
               index--;
           }
        else if(s.top()=="T"&&(nexttoken(index,a)=="+"))
           {
               cout<<"Pop stack T,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)=="+"))
           {
               cout<<str[3][1]<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="F"&&(nexttoken(index,a)=="+"))
           {
               cout<<"Pop stack F,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="E"&&(nexttoken(index,a)=="*"))
           {
               cout<<"error,user input duplicated id,ignore *"<<endl;

           }
        else if(s.top()=="E'"&&(nexttoken(index,a)=="*"))
           {
               cout<<"error,user input duplicated id,ignore *"<<endl;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)=="*"))
           {
               cout<<str[3][2]<<endl;
               s.pop();
               s.push("T'");
               s.push("F");
               s.push("*");
               index--;
           }
        else if(s.top()=="T"&&(nexttoken(index,a)=="*"))
           {

              cout<<"error,user input duplicated id,ignore *"<<endl;
           }
         else if(s.top()=="F"&&(nexttoken(index,a)=="*"))
           {

               cout<<"Pop stack F,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="E"&&(nexttoken(index,a)=="("))
           {
               cout<<str[0][3]<<endl;
               s.pop();
               s.push("E'");
               s.push("T");
               index--;
           }
        else if(s.top()=="E'"&&(nexttoken(index,a)=="("))
           {
               cout<<"error,user input duplicated id,ignore ("<<endl;
           }
        else if(s.top()=="T"&&(nexttoken(index,a)=="("))
           {
               cout<<str[2][3]<<endl;
               s.pop();
               s.push("T'");
               s.push("F");
               index--;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)=="("))
           {
               cout<<"error,user input duplicated id,ignore ("<<endl;
           }
        else if(s.top()=="F"&&(nexttoken(index,a)=="("))
           {
               cout<<str[4][3]<<endl;
               s.pop();
               s.push(")");
               s.push("E");
               s.push("(");
               index--;
           }
        else if(s.top()=="E"&&(nexttoken(index,a)==")"))
           {
               cout<<"Pop stack E,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="E'"&&(nexttoken(index,a)==")"))
           {
               cout<<str[1][4]<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="T"&&(nexttoken(index,a)==")"))
           {
               cout<<"Pop stack T,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)==")"))
           {
               cout<<str[3][4]<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="F"&&(nexttoken(index,a)==")"))
           {
               cout<<"Pop stack F,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="E"&&(nexttoken(index,a)=="$"))
           {
               cout<<"Pop stack E,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="E'"&&(nexttoken(index,a)=="$"))
           {
               cout<<str[1][5]<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="T"&&(nexttoken(index,a)=="$"))
           {
               cout<<"Pop stack T,lost id"<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="T'"&&(nexttoken(index,a)=="$"))
           {
               cout<<str[3][5]<<endl;
               s.pop();
               index--;
           }
        else if(s.top()=="F"&&(nexttoken(index,a)=="$"))
           {
               cout<<"Pop stack F,lost id"<<endl;
               s.pop();
               index--;
           }
      else if(s.top()=="id"&&(nexttoken(index,a)=="id"))
      {
          s.pop();
      }
      else if(s.top()=="id"&&(nexttoken(index,a)!="id"))
      {
           cout<<"error,user input duplicated id,id"<<endl;
      }
          else if(s.top()=="("&&(nexttoken(index,a)=="("))
      {
          s.pop();
      }
      else if(s.top()=="("&&(nexttoken(index,a)!="("))
      {
           cout<<"error,user input duplicated id,((error"<<endl;
      }
            else if(s.top()=="+"&&(nexttoken(index,a)=="+"))
      {
          s.pop();
      }
    else if(s.top()==")"&&(nexttoken(index,a)==")"))
      {
          s.pop();
      }
      else if(s.top()==")"&&(nexttoken(index,a)!=")"))
      {
           cout<<"error,user input duplicated id,))error"<<endl;
      }
            else if(s.top()=="+"&&(nexttoken(index,a)=="+"))
      {
          s.pop();
      }
      else if(s.top()=="+"&&(nexttoken(index,a)!="+"))
      {
           cout<<"error,user input duplicated id,+"<<endl;
      }
            else if(s.top()=="*"&&(nexttoken(index,a)=="*"))
      {
          s.pop();
      }
      else if(s.top()=="*"&&(nexttoken(index,a)!="*"))
      {
           cout<<"error,user input duplicated id,*"<<endl;
      }
      else if(s.top()=="$"&&(nexttoken(index,a)=="$"))
      {
          s.pop();
          cout<<"acc"<<endl;
          return;
      }
      else if(s.top()=="$"&&(nexttoken(index,a)!="$"))
      {
           cout<<"error,user input duplicated id,$"<<endl;
      }

    }


}

void E();
void EE();
void T();
void TT();
void F();
int main()
{
     analyse(File_output("a.txt"));
   /* cout<<nexttoken(0,File_output("a.txt"))<<endl;
    cout<<"1"<<endl;
    cout<<nexttoken(1,File_output("a.txt"))<<endl;
    cout<<"2"<<endl;
    cout<<nexttoken(2,File_output("a.txt"))<<endl;
    cout<<"3"<<endl;
    cout<<nexttoken(3,File_output("a.txt"))<<endl;*/
    return 0;
}
#include <iostream>
#include<string>
#include<map>
#include<sstream>
#include <fstream>
#include <list>

using namespace std;
static map<string ,int> dictionary;
void init()
{
    dictionary.insert(map<string,int>::value_type("for",1));
    dictionary.insert(map<string,int>::value_type("if",2));
    dictionary.insert(map<string,int>::value_type("then",3));
    dictionary.insert(map<string,int>::value_type("else",4));
    dictionary.insert(map<string,int>::value_type("while",5));
    dictionary.insert(map<string,int>::value_type("do",6));
    dictionary.insert(map<string,int>::value_type("var",10));
    dictionary.insert(map<string,int>::value_type("num",11));
    dictionary.insert(map<string,int>::value_type("+",13));
    dictionary.insert(map<string,int>::value_type("-",14));
    dictionary.insert(map<string,int>::value_type("*",15));
    dictionary.insert(map<string,int>::value_type("/",16));
    dictionary.insert(map<string,int>::value_type(":",17));
    dictionary.insert(map<string,int>::value_type(":=",18));
    dictionary.insert(map<string,int>::value_type("<",19));
    dictionary.insert(map<string,int>::value_type("<>",21));
    dictionary.insert(map<string,int>::value_type("<=",22));
    dictionary.insert(map<string,int>::value_type(">",23));
    dictionary.insert(map<string,int>::value_type(">=",24));
    dictionary.insert(map<string,int>::value_type("=",25));
    dictionary.insert(map<string,int>::value_type(";",26));
    dictionary.insert(map<string,int>::value_type("(",27));
    dictionary.insert(map<string,int>::value_type(")",28));
    dictionary.insert(map<string,int>::value_type("#",0));

}
int findbykey(string key)
{
   map<string,int >::iterator l_it;;
   l_it=dictionary.find(key);
   if(l_it==dictionary.end())
             return -1;
   else
    return l_it->second;
}
string keyword[6]={"for","if","then","else","while","do"};
bool isletter(char a)
{
    if((a>='a'&&a<='z')||(a>='A'&&a<='Z'))
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool isdigit(char a)
{
    if(a>='0'&&a<='9')
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool iskeyw(string keywords)
{
    for(int i=0;i<6;i++)
    {
        if(keyword[i]==keywords)
        {
            return true;
        }

    }

        return false;

}
bool isvar(string var) //ID=letter(letter | digit)*
{
       if(isletter(var[0]))
       {
           for(int i=0;i<var.length();i++)
           {
               if(isletter(var[i])||isdigit(var[i]))
               {

               }
               else
               {
                   return false;
               }
           }
           return true;
       }
       else
       {
           return false;
       }
}
bool isnum(string num)     //NUM=digit digit*   (xiaoshudian
{
    if(isdigit(num[0]))
       {
           int flag1=1;
           int flag2=1;
           for(int i=0;i<num.length();i++)
           {
               if(isdigit(num[i]))
               {

               }
               else if(num[i]=='.'&&isdigit(num[i+1])&&flag1)
                       {
                           flag1=0;
                       }
               else if (((num[i]=='E'||num[i]=='e')&&(num[i+1]=='+'||num[i+1]=='-'||isdigit(num[i+1]))&&flag2))
               {

                    flag2=0;
               }
               else if((num[i]=='+'||num[i]=='-')&&isdigit(num[i+1]))
               {

               }
               else
               {
                   return false;
               }
           }
           return true;
       }
       else
       {
           return false;
       }
}
string to_String(int n)
{
	string temp;
	stringstream ss;
	ss<<n;
   temp = ss.str();

	return temp;
}
string packet(string test,int type)
{
         int a;
         string req="";
         string aa;
        if(type==0)
        {
            a=findbykey(test);
            aa=to_String(a);
            req+="<" + aa;
            req+=",";
            req+=test;
            req+="> ";
        }
        else if(type==1)
        {
         a=findbykey("var");

            aa=to_String(a);
            req+="<" + aa;
            req+=",";
            req+="var";
            req+="> ";
        }
        else if(type==2)
        {
          a=findbykey("num");
           aa=to_String(a);
            req+="<" + aa;
            req+=",";
            req+="num";
            req+="> ";
        }



         return req;
}
string texthandle(string test,int linenum)
{
     if(iskeyw(test))
     {
          return packet(test,0);
     }
     else if(isvar(test))
     {
         return packet(test,1);
     }
     else if(isnum(test))
     {
         return packet(test,2);
     }
     else if(-1==findbykey(test))
     {
           string b="There are some errors in Line ";
           string bb;
          bb= to_String(linenum);
           b+=bb;
           return  b;
     }
     else
     {

         return packet(test,0);
     }
}

list<string> File_output(char* filename)
{
     int linenum=0;
     string test;
     fstream file;
     string pice;
      string expression="";
     list<string> words;
     file.open(filename,ios_base::in|ios_base::out) ;
     if(!file)
     {
         cout<<"error"<<endl;
     }
     else
     {
          while(getline(file, test))
        {
              linenum++;
              //處理邏輯
           /*
              劃分單詞,. 標點

           */
            string temp="";
           for(int i=0;i<test.length();i++)
           {


               if( test[i] == ' ' )
               {

               }
               else
               {

                    temp+=test[i];
                    if(test[i+1]==' '||test[i+1]=='\0')
                    {
                        /*words.push_back(temp);
                        pice=texthandle(temp,linenum);
                        expression+="\n";*/
                       // expression+=temp;

                       words.push_back(temp);
                          temp="";
                    }
               }

           }
          }
          //對單詞鏈表進行處理

        list<string>::iterator i;
         for (i = words.begin(); i != words.end(); ++i)
                 //測試
              cout<<*i<<endl;
        //cout<<expression<<endl;
     }

return words;

}

請大神告訴我:1.如何實現自動構建這種表呢?2.有沒有通用的方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章