編譯原理_常量定義語句語法分析

一、作用
  判斷常量語句定義是否合法,合法則輸出分析結果,不合法則輸出原由。

二、不合法原由
    1、是否有關鍵字“const”開頭定義
    2、是否有“;”結束定義;
    3、句子中格式行的空格處理;
    4、常量名是否合法(首字符是字母);
    5、整形常量不能有前導零;
    6、整形常量中不能有除數字以外的其他字符;
    7、字符常量中只能有一個字符;
    8、字符型常量不能爲空;
    //9、字符串常量不能爲空;
    10、浮點型常量“0.”型的,不能有多餘的前導零;
    11、浮點型常量中不能有除數字及小數點外的其他字符;
    12、浮點型常量中不能出現多個小數點。

三、代碼測試
  見《yufa測試數據及測試結果》

四、測試數據意義分析
    const a=234,b="asdas",c='f',s=435.345;
    正確數據
    sconst a=234,b="asdas",c='f',s=435.345;
    關鍵字錯誤
    const a=234,b="asdas",c='f',s=435.345
    句尾無“;”
    const a=234,b="asdas",c = 'f' ,s =435.345;
    句中有格式空格
    const a=234,b="asdas",1c='f',s=435.345;
    const a=234,_b="asdas",c='f',s=435.345;
    const a=234,,b="asdas",c='f',s=435.345;
    常量名錯誤
    const a=0234,b="asdas",c='f',s=435.345;
    整型常量有前導零
    const a=23ed4,b="asdas",c='f',s=435.345;
    “整型常量”中有非數字字符
    const a=234,b="asdas",c='ff',s=435.345;
    “字符型常量”中有多個字符
    const a=234,b="asdas",c='',s=435.345;
    “字符型常量”值爲空
    const a=234,b="",c='f',s=435.345;
    “字符串型常量”值爲空
    const a=234,b="asdas",c='f',s=00.345;
    “浮點型常量”有多餘前導零
    const a=234,b="asdas",c='f',s=43sdf5.345;
    “浮點型常量”中有非數字非小數點字符
    const a=234,b="asdas",c='f',s=43.5.345;
    “浮點型常量”中有多個小數點
五、問題分析
   程序中仍不能解決的問題有:
    1、若字符串中有空格,無法處理,會被直接刪除;
    2、若語句中有多餘的或在字符串中有“,”會導致程序崩潰;

    3、若語句中有非英文字符,可能會導致程序崩潰。



測試數據:

const a=234,b="asdas",c='f',s=435.345;
sconst a=234,b="asdas",c='f',s=435.345;
const a=234,b="asdas",c='f',s=435.345
const a=234,b="asdas",c = 'f' ,s =435.345;
const a=234,b="asdas",1c='f',s=435.345;
const a=234,_b="asdas",c='f',s=435.345;
const a=234,,b="asdas",c='f',s=435.345;
const a=0234,b="asdas",c='f',s=435.345;
const a=23ed4,b="asdas",c='f',s=435.345;
const a=234,b="asdas",c='ff',s=435.345;
const a=234,b="asdas",c='',s=435.345;
const a=234,b="",c='f',s=435.345;
const a=234,b="asdas",c='f',s=00.345;
const a=234,b="asdas",c='f',s=43sdf5.345;
const a=234,b="asdas",c='f',s=43.5.345;


測試結果:

const a=234,b="asdas",c='f',s=435.345;
@the constent is lagel ,fllow is the result of Analysis:
*********************************
a(int , 234)
b(String , "asdas")
c(char , 'f')
s(float , 435.345)

num_int = 1 ;
num_float = 1 ;
num_char = 1 ;
num_string = 1 ;

*********************************
The Analysis is finish!
Please input a string again!

-------------------------------------------------

sconst a=234,b="asdas",c='f',s=435.345;
It is not a constant declaration statement! <const>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=435.345
It is not a constant! <;>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c = 'f' ,s =435.345;
@the constent is lagel ,fllow is the result of Analysis:
*********************************
a(int , 234)
b(String , "asdas")
c(char , 'f')
s(float , 435.345)

num_int = 1 ;
num_float = 1 ;
num_char = 1 ;
num_string = 1 ;

*********************************
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",1c='f',s=435.345;
<1c>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,_b="asdas",c='f',s=435.345;
<_b>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,,b="asdas",c='f',s=435.345;
<,b>: the name is illege!

The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=0234,b="asdas",c='f',s=435.345;
<0234> :is not a legal int! <0>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=23ed4,b="asdas",c='f',s=435.345;
<23ed4> :is not a legal int! <other charecater>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='ff',s=435.345;
<'ff'> :is not a legal charThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='',s=435.345;
<''> :is not a legal charThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="",c='f',s=435.345;
<""> :is not a legal StringThe Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=00.345;
<00.345> :is not a legal float! <00>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=43sdf5.345;
<43sdf5.345> :is not a legal float! <other charecater>
The Analysis is finish!
Please input a string again!

-------------------------------------------------

const a=234,b="asdas",c='f',s=43.5.345;
<43.5.345> :is not a legal float! <.. >
The Analysis is finish!
Please input a string again!

-------------------------------------------------



/*     @常量定義語法判斷     @作者:Amy     @版本:1.1 */ #include<iostream> #include<string> #include<vector> #include<stdio.h> #include<string.h> #include<ctype.h> using namespace std; struct node //常量定義分析 {     string name;    //常量名     string in; //常量內容     string type;    //常量類型//interger,char,int,float }content; string s,ss; vector<node> ve; int len; int num_int,num_float,num_char,num_string; char a[1000]; bool initial()//初始化,輸入數據 {     num_int=0;     num_float=0;     num_char=0;     num_string=0;     ve.clear();     if(gets(a))     {         s=a;         return true;     }     return false; }  bool judge_const()//判斷const是否正確 {     int x=s.find(" ",0);     ss=s.substr(0,x);//提取關鍵字const     for(int i=0;i<s.size();i++)     //去掉空格         if(s[i]==' ')s.erase(i--,1);     s.copy(a,s.size()-5,5);     len=s.size()-5;     a[len]='\0';     if(ss!="const")return false;     return true; }  bool jundge_tail()  //判斷是否有“;” {     if(a[len-1]!=';')return false;    return true;  }  void sent()//提取語句(每個定義) {     int side=0;     char name1[20],in[20];     a[len-1]=',';     while(sscanf(a+side,"%[^=]%[^,]",name1,in))     {         content.name=name1;         content.in=in;         content.in.erase(0,1);         ve.push_back(content);         side+=strlen(name1)+strlen(in)+1;         if(side==len)  //到結尾             break;     } }  bool judge_name()   //判斷常量名是否合語法 {     for(int i=0;i<ve.size();i++)         if(!isalpha(ve[i].name[0])){    //首字符不是字母             cout<<"<"<<ve[i].name<<">";             return false;         }     return true; }  void classf()   //根據常量特徵分類 {     for(int i=0;i<ve.size();i++){         if(ve[i].in[0]=='"')    //雙引號開始的是字符串             ve[i].type="String",num_string++;         else if(ve[i].in[0]=='\'')  //單引號開始的是字符             ve[i].type="char",num_char++;         else if(ve[i].in.find(".",0)<ve[i].in.size())   //帶小數點的是小數             ve[i].type="float",num_float++;         else  ve[i].type="int",num_int++;   //否則是整數     } }  bool judge_content()//判斷常量內容是否正確 {     char txt[20];     for(int i=0;i<ve.size();i++){         if(ve[i].type=="int"){             ve[i].in.copy(a,ve[i].in.size(),0);             a[ve[i].in.size()]='\0';             if(sscanf(a,"%[0-9]",txt)&&strlen(a)==strlen(txt)); //整數中沒有非數字字符             else             {                 cout<<"<"<<ve[i].in<<"> :is not a legal int! <other charecater>"<<endl;                  return false;             }             if(ve[i].in[0]=='0'){   //整數不能前導零                 cout<<"<"<<ve[i].in<<"> :is not a legal int! <0>"<<endl;                 return false;             }         }         if(ve[i].type=="float"){             ve[i].in.copy(a,ve[i].in.size(),0);             a[ve[i].in.size()]='\0';             if(sscanf(a,"%[0-9,.]",txt)&&strlen(a)==strlen(txt));   //小數中沒有非數字和非小數點的字符             else             {                 cout<<"<"<<ve[i].in<<"> :is not a legal float! <other charecater>"<<endl;                  return false;             }             if(ve[i].in[0]==ve[i].in[1]&&ve[i].in[1]=='0'){ //小數不能前導兩個零                cout<<"<"<<ve[i].in<<"> :is not a legal float! <00>"<<endl;                return false;             }             if(ve[i].in.find(".",ve[i].in.find(".",0)+1)<ve[i].in.size()){//小數中不能有多個小數點                 cout<<"<"<<ve[i].in<<"> :is not a legal float! <.. >"<<endl;                return false;             }         }         if(ve[i].type=="char"){             if(ve[i].in.size()!=3){                 cout<<"<"<<ve[i].in<<"> :is not a legal char";//常量中自能有一個字符                 return false;             }         }         else {             if(ve[i].in.size()<3){//字符串常量中不能爲空                 cout<<"<"<<ve[i].in<<"> :is not a legal String";                 return false;             }         }     }     return true; }  void output()//輸出結果,若無語法問題 {     cout<<"@the constent is lagel ,fllow is the result of Analysis:";     cout<<"\n*********************************\n";     for(int i=0;i<ve.size();i++)         cout<<ve[i].name<<"("<<ve[i].type<<" , "<<ve[i].in<<")"<<endl;     cout<<endl;     cout<<"num_int = "<<num_int<<" ;\n";     cout<<"num_float = "<<num_float<<" ;\n";     cout<<"num_char = "<<num_char<<" ;\n";     cout<<"num_string = "<<num_string<<" ;\n";     cout<<"\n*********************************\n"; } int main() {     bool x;     while(initial())     {         if(!judge_const())//判斷是否有關鍵字“const”         {             cout<<"It is not a constant declaration statement! <const>"<<endl;             goto end1;         }         if(!jundge_tail())//判斷句尾是否有“;”         {             cout<<"It is not a constant! <;>"<<endl;             goto end1;         }         sent();         if(!judge_name())//判斷常量名是否合法         {             cout<<": the name is illege!\n\n";             goto end1;         }         classf();   //分析常量類型         if(!judge_content())    //判斷常量初始化是否有誤             goto end1;         output();   //輸出結果(若沒有發現問題) end1:         cout<<"The Analysis is finish!\nPlease input a string again!"<<endl;         cout<<"\n-------------------------------------------------\n"<<endl;     }     return 0; } 



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