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;
}