?? yufayuyi.cpp
字號:
//基于LL(1)法的條件語句語法語義分析程序
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<iomanip.h>
#include<malloc.h>
enum keyword{ $right_paren,$left_paren,$mul,$div,$add,$sub,$fenhao,
$equal,$IF,$THEN,$ELSE,$greater,$less,$id,$num,$end};
typedef struct Token
{
keyword type;
char ch;
}Token;
typedef enum{JUMP,JG,JL,equal,END,add,mul,sub,div}OpKind;
typedef struct
{
int label; //標號
OpKind op; //操作符
char par1,par2; //操作數
union
{
char result; //結果
int address; //地址
};
}Quad; //四元式入口
#define MAX_TOKEN 256 //Token表大小
#define MAX_QUAD 256 //四元式數組大小
Token tokentable[MAX_TOKEN];
Quad quad[MAX_QUAD];
int token_index; //token表索引
int total_len; //token表有效長度
int quad_len; //四元式表有效長度
int quad_index; //四元式索引
Token cur;
Token queue[10];
int label,k,one; //標記接口
char curchar; //存儲當前待比較字符
char curtocmp; //存儲當前棧頂字符
ifstream ins;
int trueadd,falseadd,end;
int table[5][8]={{1,0,0,0,0,1,0,0},
{0,1,1,0,0,0,1,1},
{1,0,0,0,0,1,0,0},
{0,1,1,1,1,0,1,1},
{1,0,0,0,0,1,0,0}}; //存儲預測分析表,1為有產生式,0為沒有
int i,j;
int flag;
struct Lchar
{
char char_ch;
struct Lchar *next;
}Lchar,*temp,*top,*base;
int right; //定義開關項
bool initialize(char filename[255]);
bool accidence();
void print();
void backpath(int,int);
void ERROR();
void sentence();
void boolean();
bool nexttoken();
char newchar();
void push();
char dosome(void); //算法函數
void pushs(char pchar); //入棧函數
void pop(void); //出棧函數
void doforpush(int t); //根據數組下標計算的值產生式入棧
void changchartoint(); //根據curchar,curtocmp轉為數字以判斷是否有產生式
void semantic(); //語法語義分析
char LL1(); //LL(1)文法分析
void printQuad(); //輸出四元式
void ERROR(char str[20]);
void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress);
void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult);
void main()
{
cout<<" "<<endl
<<" "<<endl
<<" 基于LL(1)法的條件語句語法語義分析程序 "<<endl
<<" "<<endl
<<" "<<endl
<<"輸入待編譯文件名:";
char fname[100];
cin>>fname;
if(!initialize(fname))
return;
if(!accidence())
return;
char ch;
while(1)
{
if(ins.eof())
break;
ins>>ch;
}
cout<<endl<<"詞法分析結果如下:";
print();
cout<<endl;
cout<<"詞法分析結束。"<<endl<<endl;
semantic(); //語法語義分析
cout<<endl<<"輸出四元式:"<<endl;
printQuad();
if(right==1)
cout<<"分析成功"<<endl;
else
cout<<"分析失敗"<<endl;
cout<<"語法語義分析結束"<<endl;
}//main
char newchar()
{ char p;
p=char(k);
k++;
return p;
}
//文件打開初始化
bool initialize(char filename[100])
{
one=0;
token_index=0;
total_len=0;
quad_len=0;
quad_index=0;
label=0;
end=0;
k=48;
ins.open(filename,ios::nocreate | ios::in);
if(ins.fail())
{
cout<<"文件打開出錯!"<<endl;
return false;
}
return true;
}
//詞法分析
bool accidence()
{
int k=0;
char buf[16];
char ch;
while(1)
{
ins>>ch;
if(ins.fail())
break;
while(ch==' ')
{ ins>>ch;}
if(ch=='I')
{
ins>>buf;
if(strcmp(buf,"F")==0)
tokentable[total_len++].type=$IF;
}
else if(ch=='T')
{
ins>>buf;
if(strcmp(buf,"HEN")==0)
tokentable[total_len++].type=$THEN;
}
else if(ch=='E')
{
ins>>buf;
if(strcmp(buf,"LSE")==0)
tokentable[total_len++].type=$ELSE;
}
else if(ch=='>')
{
tokentable[total_len++].type=$greater;
}
else if(ch=='<')
{
tokentable[total_len++].type=$less;
}
else if(ch=='=')
{
tokentable[total_len++].type=$equal;
}
else if((ch>='A'&& ch<='Z' )|| (ch>='a' && ch<='z'))
{
tokentable[total_len].type=$id;
tokentable[total_len++].ch=ch;
}
else if(ch>='0' && ch<='9')
{ tokentable[total_len].type=$num;
tokentable[total_len++].ch =ch;
}
else
switch (ch)
{case '+' :
tokentable[total_len].type=$add;
tokentable[total_len++].ch =ch;
break;
case '-' :
tokentable[total_len].type=$sub;
tokentable[total_len++].ch =ch;
break;
case '/' :
tokentable[total_len].type=$div;
tokentable[total_len++].ch =ch;
break;
case '*' :
tokentable[total_len].type=$mul;
tokentable[total_len++].ch =ch;
break;
case ';' :
tokentable[total_len].type=$fenhao;
tokentable[total_len++].ch =ch;
break;
case '(' :
tokentable[total_len].type=$left_paren;
tokentable[total_len++].ch =ch;
break;
case ')' :
tokentable[total_len].type=$right_paren;
tokentable[total_len++].ch =ch;
break;
default:cout<<"!"<<endl;
}
}
return true;
}
//語法語義分析
void semantic()
{
if(!nexttoken())
ERROR("s(0)");
cout<<"開始進行語法語義分析:"<<endl
<<"所使用的產生式:"<<endl
<<"<if語句> -> if E then S else S"<<endl
<<"S->i=E"<<endl
<<"E->TA"<<endl
<<"A-> +TA|-TA|e"<<endl
<<"T->FB"<<endl
<<"B->*FB|/FB|e"<<endl
<<"F->M|(E)"<<endl
<<"M->id|num"<<endl
<<"語法語義分析過程如下:"<<endl;
if(cur.type==$IF)
{
boolean(); //分析布爾語句
if(!nexttoken())
ERROR("S(0)");
if(cur.type==$THEN)
{
backpath(trueadd,quad_len); //回填出口
sentence(); //分析語句
end=quad_len;
AD_ADDRESS(quad_len,JUMP,'-','-',end); //產生跳轉地址的四元式
if(cur.type==$ELSE)
{
backpath(falseadd,quad_len);
sentence();
backpath(end,quad_len);
}
else
ERROR("S(else)");
}
else
{
ERROR("S(then)");
}
}
else
ERROR("S(if)");
AD_RESULT(quad_len,END,0,0,'-'); //產生數值語句的四元式
}
//讀下一單詞
bool nexttoken()
{
if(token_index>=total_len)
return false;
if(tokentable[token_index].type==$fenhao)
token_index++;
cur.type=tokentable[token_index].type;
cur.ch=tokentable[token_index].ch;
token_index++;
return true;
}
//進隊列
void push()
{ one=0;
while(tokentable[token_index].type!=$fenhao)
{
queue[one].type=tokentable[token_index].type;
queue[one].ch=tokentable[token_index].ch;
cout<<queue[one].ch;
token_index++;
one++;
}
queue[one].type=$end;
queue[one].ch='#';
cout<<queue[one].ch;
}
//隊列下一個字符
void next()
{
cur.type=queue[one].type;
cur.ch =queue[one].ch ;
one++;
}
// 分析E->id < id | id > id語句
void boolean()
{
char a,b;
int c;
if(!nexttoken())
ERROR("E(0)");
if(cur.type==$id||cur.type==$num)
{
a=cur.ch;
if(!nexttoken())
ERROR("E(0)");
if(cur.type==$greater||cur.type==$less)
{
c=cur.type ;
if(!nexttoken())
ERROR("E(0)");
if(cur.type==$id||cur.type==$num)
b=cur.ch;
else
ERROR("E(id/num)");
if(c==$greater)
{
trueadd=quad_len-1;
falseadd=quad_len;
AD_ADDRESS(quad_len,JG,a,b,trueadd);
AD_ADDRESS(quad_len,JUMP,0,0,falseadd);
}
else
{
trueadd=quad_len;
falseadd=quad_len+1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -