?? parse.cpp
字號:
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stack>
#include "word_analysis.h"
using namespace std;
/*四則運算的語法規則
0 E->TP 1 P->ATP 2 P->$
3 T->FQ 4 Q->MFQ 5 Q->$
6 F->(E) 7 F->i 8 A->+
9 A->- 10 M->* 11 M->/
$表示空串
*/
void error(char *err){
printf("Error: %s",err);
}
//顯示棧中元素
void dump(stack< char > st)
{
int i,j;
char ch[100];
j=st.size();
for(i=0;i<j;i++)
{
ch[i]=st.top();
st.pop();
}
for(i=j-1;i>=0;i--)
{
printf("%c",ch[i]);
st.push(ch[i]);
}
}
//檢查是否在非終結符數組VN中
//如果在返回位置,否則返回-1
int checkVN(char x,char VN[7]){
int k=0;
for(;k<7;k++)
if(VN[k] == x)
return k;
return -1;
}
//檢查是否在終結符數組VT中
//如果在返回位置,否則返回-1
int checkVT(char x,char VT[8]){
int k=0;
for(;k<8;k++)
if(VT[k] == x)
return k;
return -1;
}
void init_E_M(char Expression[12][7],int M[7][8]){
int i,j;
strcpy(Expression[0],"TP"); strcpy(Expression[1],"ATP");
strcpy(Expression[2],"$"); strcpy(Expression[3],"FQ");
strcpy(Expression[4],"MFQ"); strcpy(Expression[5],"$");
strcpy(Expression[6],"(E)"); strcpy(Expression[7],"i");
strcpy(Expression[8],"+"); strcpy(Expression[9],"-");
strcpy(Expression[10],"*"); strcpy(Expression[11],"/");
for(i=0;i<7;i++)
for(j=0;j<8;j++)
M[i][j] = -1;
M[0][0]=0; M[0][2]=0; M[1][1]=2; M[1][3]=1; M[1][4]=1; M[1][7]=2; M[2][0]=3;
M[2][2]=3; M[3][1]=5; M[3][3]=5; M[3][4]=5; M[3][7]=5; M[3][5]=4; M[3][6]=4;
M[4][0]=6; M[4][2]=7; M[5][3]=8; M[5][4]=9; M[6][5]=10; M[6][6]=11;
}
int syntax(char* input){
char Expression[12][7];
char VN[8],VT[9];//vt=" ()i+-*/# "
int M_VN_VT[7][8];
unsigned int step=0;
bool flag = false;
stack< char > st;
char X;//目前棧頂
int xv=-1;//棧頂若為非終結符則為它在非終結符數組的位置
int av=-1;//目前終結符在終結符數組的位置
int expr;//表達式的標號
int i=0;
char* buff;
int place=0;
//初始化 終結符、非終結符數組
strcpy(VT,"()i+-*/#");
VT[8] = '\0';
strcpy(VN,"EPTQFAM");
VN[7] = '\0';
//初始化表達式,初始化預測分析表
init_E_M(Expression,M_VN_VT);
//將#和起始非終結符壓入棧
st.push('#');
st.push('E');
//得到詞法翻譯后的輸入串,以#結尾
buff = read_sym(input);
if(buff == NULL)
return 0;//詞法分析錯誤
av= checkVT(buff[place],VT);
//屏幕顯示提示
printf("Step:\tStack\tResidual inputString\n");
while(!flag)//循環條件:沒有文法匹配成功
{
X = st.top();
st.pop();
xv = checkVN(X,VN);
if(xv < 0 && X != '#') //如果是終結符
{
if(X == buff[place])
{
place++;
if(buff[place]== '$')
return 0;
av= checkVT(buff[place],VT);
}//if X==a
else{
printf("%c,%c,syntax analysis error!\n",buff[place],X);
printf("\t\tSomething Wrong!\n");
puts("Syntax analysis Failed!");
return 0;
}
}//if symvalid(x)
else if(X == '#')
{
if(X == buff[place])
{
flag = true;//Success!
// printf("\t\tMatch!\n");
break;
}
else
{
printf("%c,%c,syntax analysis error!\n",buff[place],X);
printf("\t\tSomething Wrong!\n");
puts("Syntax analysis Failed!");
return 0;
}
}//if(x == '#')
else if(M_VN_VT[xv][av] != -1)
{
expr = M_VN_VT[xv][av];
//如果產生式有部是空串
if(Expression[expr][0] == '$')
{
printf("%4d:\t",step++);
dump(st);
printf("\t\t%10s",&buff[place]);
printf("\n");
continue;
}//$
//產生式有部所有符號逆序進棧
for(i = strlen(Expression[expr])-1; i >= 0 ;i--)
st.push(Expression[expr][i]);
}//ifM_VN_VT[][]
else{
//出錯
error("Not Match character!");
puts("Syntax analysis Failed!");
return 0;
}
printf("%4d:\t",step++);
dump(st);
printf("\t\t%10s",&buff[place]);
printf("\n");
}
if(flag = true)
printf("Syntax analysis Succeed!\n");
return 1;
}
int main(){
unsigned int len;
char temp;
char input[BUFSIZE];
do{
printf("請輸入四則運算表達式,用于檢測真偽:\n");
gets(input);
//初始化輸入串,使之以#結尾
len=strlen(input);
input[len]='#';
input[len+1]='\0';
//語法分析
syntax(input);
printf("是否想繼續查詢?\n");
scanf("%c",&temp);
getchar();
}while(temp == 'y' || temp == 'Y');
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -