编译原理实验
- 编译原理实验1 词法分析
- 编译原理实验2 语法分析
编译原理实验1 词法分析
//词法分析程序(识别关键字、标识符、常数、运算符、界符)
#include
#include
using namespace std;
#include
#include
#include
#define norw 25 //关键字个数
#define al 10 //符号的最大长度
#define nmax 14 //number的最大位数
#define getchdo if(-1==getch()) return -1
char ch; //获取字符的缓冲区,getch使用
double num,num1,num2 ; //常数转换
int cc,ll; //getch使用的计数器,cc表示当前字符(ch)的位置
int lines=0; //字符所在的行号
int errors=0; //错误的个数
char line[81]; //读取行缓冲区
enum symbol{ //符号类型
number,becomes,nul,leq,lss,geq,gtr,plus_,minus_,
times,slash,lparen,rparen,lmparen,rmparen,lbparen,
rbparen,eql,comma,period,neq,semicolon,ident,breaksym,
casesym,charsym,classsym,continuesym,dosym,doublesym,
elsesym,enumsym,externsym,falsesym,floatsym,forsym,
friendsym,ifsym,intsym,longsym,namespacesym,mainsym,
returnsym,switchsym,truesym,usingsym,voidsym,whilesym
};
enum symbol sym; //当前的符号
enum symbol wsym[norw]; //关键字对应的符号值
enum symbol ssym[256]; //单字符的符号值
char id[al+1]; //当前ident,多出的一个字节用于存放0
char a[al+1]; //临时符号,多出的一个字节用于存放0
char word[norw][al]; //关键字
FILE *fin; //指向文件的指针
void init() //初始化
{
int i;
for(i=0;i<=255;i++) //设置单字符符号
{
ssym[i]=nul;
}
ssym['+']=plus_;
ssym['-']=minus_;
ssym['*']=times;
ssym['/']=slash;
ssym['(']=lparen;
ssym[')']=rparen;
ssym['[']=lmparen;
ssym[']']=rmparen;
ssym['{']=lbparen;
ssym['}']=rbparen;
ssym['=']=eql;
ssym[',']=comma;
ssym['.']=period;
ssym['#']=neq;
ssym[';']=semicolon;
//设置关键字名字,按照字母顺序,便于折半查找
strcpy(&(word[0][0]),"break");
strcpy(&(word[1][0]),"case");
strcpy(&(word[2][0]),"char");
strcpy(&(word[3][0]),"class");
strcpy(&(word[4][0]),"continue");
strcpy(&(word[5][0]),"do");
strcpy(&(word[6][0]),"double");
strcpy(&(word[7][0]),"else");
strcpy(&(word[8][0]),"enum");
strcpy(&(word[9][0]),"extern");
strcpy(&(word[10][0]),"false");
strcpy(&(word[11][0]),"float");
strcpy(&(word[12][0]),"for");
strcpy(&(word[13][0]),"friend");
strcpy(&(word[14][0]),"if");
strcpy(&(word[15][0]),"int");
strcpy(&(word[16][0]),"long");
strcpy(&(word[17][0]),"main");
strcpy(&(word[18][0]),"namespace");
strcpy(&(word[19][0]),"return");
strcpy(&(word[20][0]),"switch");
strcpy(&(word[21][0]),"true");
strcpy(&(word[22][0]),"using");
strcpy(&(word[23][0]),"void");
strcpy(&(word[24][0]),"while");
//设置关键字符号
wsym[0]=breaksym;
wsym[1]=casesym;
wsym[2]=charsym;
wsym[3]=classsym;
wsym[4]=continuesym;
wsym[5]=dosym;
wsym[6]=doublesym;
wsym[7]=elsesym;
wsym[8]=enumsym;
wsym[9]=externsym;
wsym[10]=falsesym;
wsym[11]=floatsym;
wsym[12]=forsym;
wsym[13]=friendsym;
wsym[14]=ifsym;
wsym[15]=intsym;
wsym[16]=longsym;
wsym[17]=mainsym;
wsym[18]=namespacesym;
wsym[19]=returnsym;
wsym[20]=switchsym;
wsym[21]=truesym;
wsym[22]=usingsym;
wsym[23]=voidsym;
wsym[24]=whilesym;
}
int getch()
{//每次读一行,存入line缓冲区,line被getsym取空后再读一行
if(cc==ll)
{
if(feof(fin))
{
cout<='a'&&ch<='z') //标识符或关键字以a~z开头
{
k=0;
do{
if(k='a'&&ch<='z'||ch>='0'&&ch<='9');
a[k]=0;
strcpy(id,a);
i=0;
j=norw-1;
do{
k=(i+j)/2;
if(strcmp(id,word[k])<=0)
{
j=k-1;
}
if(strcmp(id,word[k])>=0)
{
i=k+1;
}
}while(i<=j);
if(i-1>j)
{
sym=wsym[k]; //关键字
cout<<"line"<='0'&&ch<='9') //检测是否为数字
{
k=0;
num=0;
sym=number;
do{
if(ch==46)
{
getchdo;
i=1;
do{
for(j=1;j<=i;j++)
{
num2=ch-'0';
num1=num2/10;
getchdo;
}
num=num+num1;
}while(ch>='0'&&ch<='9');
break;
}
num=10*num+ch-'0';
k++;
getchdo;
}while(ch>='0'&&ch<='9'||ch==46);
k--;
if(k>nmax)
{
cout<='a'&&ch<='z')
{
cout<')
{
getchdo;
if(ch=='=')
{
sym=geq; //>=
cout<<"line"<="<
cout<<"line"<"<
编译原理实验2 语法分析
//语法分析
/*
E→eBaA
A→a,A→bAcB
B→dEd,B→aC
C→e,C→dC
eadeaa#
edeaebd#
edeaeaadabacae#
*/
#include
using namespace std;
char ch; //获取字符的缓冲区,getch使用
int cc,i=0; //cc表示当前读入字符,i表示当前判断字符
char m[81]; //用于存储输入的字符串
int A(),B(),C();
int getch()
{
cc=0;
while(cin>>ch)
{
if(ch=='@')
{
m[cc]='@';
return -1;
}
if(ch=='#')
{
m[cc]=0;
return -1;
}
else
{
if(ch>='a'&&ch<='z')
{
m[cc]=ch;
cc++;
}
else
{
cout<<"\n输入字符串有误!"<