编译原理实验(词法分析器+语法分析器(递归下降法))

1.分析C++词法,判断首位为数字的错误变量
通过对C++词法分析程序(GETSYM)的分析,并在此基础上按照教材附录A中给出的C++语言的语法描述,编写一个C++语言的词法分析程序。此程序应具有如下功能:
输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。
有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。

这里借鉴了一些其他博主的,然后我进行了一些改进,适用于我们实验课

#include<bits/stdc++.h>
using namespace std;
string KEYWORD[19]={"if","else","void","return","while","then","for","do",      //关键字
                    "int","char","double","float","case","cin","cout","include","using","namespace","iostream"};
char SEPARATER[8]={';',',','{','}','[',']','(',')'};    //分隔符
char OPERATOR[9]={'+','-','*','/','>','<','=','!','#'};     //运算符
char Muloperator[9][2]={{'+','='},{'-','='},{'*','='},{'/','='},{'+','+'},{'-','-'},{'<','='},{'>','='},{'=','='}};
char FILTER[4]={' ','\t','\r','\n'};                    //过滤符
const int IDENTIFIER=100;         //标识符值
const int CONSTANT=101;           //常数值
const int FILTER_VALUE=102;       //过滤字符值
/**判断是否为关键字**/
bool IsKeyword(string word){
    for(int i=0;i<19;i++){
        if(KEYWORD[i]==word){
            return true;
        }
    }
    return false;
}
/**判断是否为分隔符**/
bool IsSeparater(char ch){
    for(int i=0;i<8;i++){
        if(SEPARATER[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为运算符**/
bool IsOperator(char ch){
    for(int i=0;i<9;i++){
        if(OPERATOR[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为多位运算符**/
bool IsMuloperator(char ch[]){
    for(int i=0;i<9;i++){
        if(ch[0]==Muloperator[i][0]&&ch[1]==Muloperator[i][1])return true;
    }
    return false;
}
/**判断是否为过滤符**/
bool IsFilter(char ch){
    for(int i=0;i<4;i++){
        if(FILTER[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为大写字母**/
bool IsUpLetter(char ch){
    if(ch>='A' && ch<='Z') return true;
    return false;
}
/**判断是否为小写字母**/
bool IsLowLetter(char ch){
    if(ch>='a' && ch<='z') return true;
    return false;
}
/**判断是否为数字**/
bool IsDigit(char ch){
    if(ch>='0' && ch<='9') return true;
    return false;
}
/**返回每个字的值**/
template <class T>
int value(T *a,int n,T str){
	for(int i=0;i<n;i++){
		if(a[i]==str) return i+1;
	}
	return -1;
}
/**词法分析**/
void analyse(FILE * fpin){
    char ch=' ';
    string arr="";
    int hang=1;
    int i=0;
    while((ch=fgetc(fpin))!=EOF){
        i++;
        arr="";
        if(IsFilter(ch)){
            if(ch=='\n')hang++;
        }              //判断是否为过滤符
        else if(IsLowLetter(ch)){       //判断是否为关键字(变量名,或者关键字)
            while(IsLowLetter(ch)){
				arr += ch;
				ch=fgetc(fpin);
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
			if(IsKeyword(arr))cout<<hang<<"   关键字   "<<arr<<endl;
			else cout<<hang<<"   标识符   "<<arr<<endl;
        }
        else if(IsDigit(ch)){       //判断是否为数字(整数或者浮点数)     2b等不可识别符
            bool dian=false;
            bool worry=false;
            while(IsDigit(ch)||ch=='.'){//||(ch=='.'&&IsDigit(fgetc(fpin)))){
                arr += ch;
                ch=fgetc(fpin);
                if(ch=='.')dian=true;
                if(IsUpLetter(ch)||IsLowLetter(ch)){
                    worry=true;
                    arr+=ch;ch=fgetc(fpin);
                    while(IsUpLetter(ch)||IsLowLetter(ch)||IsDigit(ch)){
                        arr+=ch;ch=fgetc(fpin);
                    }
                    break;
                }
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
            if(worry)cout<<hang<<"   不可识别符   "<<arr<<endl;
            else if(!dian)cout<<hang<<"   整形数   "<<arr<<endl;
            else cout<<hang<<"   浮点数   "<<arr<<endl;
        }
        else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){//是否为山峰变量名(push_back())
            while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
                arr += ch;
                ch=fgetc(fpin);
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
            cout<<hang<<"   标识符   "<<arr<<endl;
        }
        else if(IsOperator(ch)){
            char noo[2];
            int cur=0;
            noo[cur++]=ch;
            arr+=ch;
            ch=fgetc(fpin);
            if(IsOperator(ch)){//下一个是字符
                noo[cur++]=ch;
                arr+=ch;
                if(IsMuloperator(noo))cout<<hang<<"   运算符   "<<arr<<endl;
                else {
                    if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
                    cout<<hang<<"   不可识别符   "<<arr<<endl;
                }
            }
            else {
                if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
                cout<<hang<<"   运算符   "<<arr<<endl;
            }
        }
        else if(IsSeparater(ch)){
            arr+=ch;
            cout<<hang<<"   分隔符   "<<arr<<endl;
        }
        else cout<<hang<<"   不可识别符   "<<ch<<endl;
    }

}
int main()
{
    char inFile[40];
    FILE *fpin;
    fpin=fopen("input.c","r");
    cout<<"------词法分析如下------"<<endl;
    analyse(fpin);
    return 0;
}
/*
cout<<"请输入源文件名(包括路径和后缀):";
    while(true){
        cin>>inFile;
        if(()!=NULL)
            break;
        else{
            cout<<"文件名错误!"<<endl;
            cout<<"请输入源文件名(包括路径和后缀):";
        }

    }
    */

2.语法分析器,分析LL(1)文法,用递归下降法(就是递归写。。。)
(1)本分析程序所分析的文法如下:
G[E]:
E→eBaA
A→a|bAcB
B→dEd|aC
C→e|dC
(2)针对上述文法编写一递归子程序分析程序,该程序的输入是任意符号串,输出是本次输入的符号串是否是该文法的句子的结论。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3;
string a;
int pos,len;
int A(int x);
int B(int x);
int C(int x);
int E(int x);
int A(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='a')return pos+1;
    if(a[pos]=='b'){
        pos=A(pos+1);
        if(pos<0)return -1;
        if(a[pos]=='c'){
            pos=B(pos+1);
            if(pos<0)return -1;
            else return pos;
        }
        else return -1;
    }
    else return -1;
}

int B(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='d'){
        pos=E(pos+1);
        if(pos<0)return -1;
        if(a[pos]=='d')return pos+1;
        else return -1;
    }
    else if(a[pos]=='a'){
        pos=C(pos+1);
        if(pos<0)return -1;
        return pos;
    }
    else return -1;
}

int C(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='e'){
       return pos+1;
    }
    else if(a[pos]=='d'){
        pos=C(pos+1);
        if(pos<0)return -1;
        return pos;
    }
    else return -1;
}

int  E(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='e'){
        pos++;
        pos=B(pos);
        if(pos<0)return -1;
        if(a[pos]=='a'){
            pos++;
            pos=A(pos);
            if(pos<0)return -1;
            else return pos;
        }
        else return -1;
    }
    else return -1;
}

int main(){
    freopen("1.txt","r",stdin);
    while(cin>>a){
        a+='#';
        len=a.size()-1;
        if(E(0)==len)cout<<a<<"\n\tis\tTrue\n";
        else cout<<a<<"\n\tis\tFalse\n";
    }
    return 0;
}

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值