/*本實驗參照學校實驗報告冊的演算法所作,行事倉促,有很多不足,望加指正*/
/*驗證文法1:
e->e+t|t
t->t*f|f
f->(e)|a
語句示例:a+a$
驗證文法2:
s->a|b|(t)
t->t,s|s
語句示例:(a,(a,a))$
因未加入對'|'的拆分,所以輸入文法是需手動拆分產生式.
本程式所輸文法,必須為算符優先文法
*//*結束符號是$;
vn中第乙個字元是開始符號;
first集、follow集和優先分析表t的字元順序和vt及vn一致
*/#include
#include
#include
#include
using namespace std;
#define ok 1
#define error 0
#define overflow -2
#define n 200
#define y 10
#define stack_init_size 100
#define stackincrement 10
int vtnum,vnnum,pronum;//依次是終結符、非終結符、產生式個數
int first[n][n];//firstvt集
int last[n][n];//lastvt集
int t[n][n];//優先關係表
char vt[n];
char vn[n]; //終結符和非終結符集
char old[n][n];//用於儲存產生式
typedef structsqe;
typedef structsqstack;//定義堆疊用於求firstvt和lastvt
void initstack(sqstack &);
void push(sqstack &,char,char);
int pop(sqstack &,char &,char &);
bool empty(sqstack &);
void first();
int test(char);
void insertf(char,char,sqstack &);
void last();
int tail(int);
void insertl(char,char,sqstack &);
void printf_ff();
void table();
void printf_t();
int control();
void main()
(*s1.top).vn=e;
(*s1.top).vt=v;
s1.top++;
int pop(sqstack &s1,char &e,char &v)
bool empty(sqstack &s1)
void first()//求所有非終結符的firstvt集
}while(!empty(s))//假設彈出元素是(q,a),找尋形如p->q...的產生式,對(p,a)呼叫insertf()
}void insertf(char a,char b,sqstack &s)//插入firstvt集,(a,b)是非終結符和終結符對
void last()//求所有非終結符的lastvt集,思想和求firstvt相同
}while(!empty(s))//假設彈出元素是(q,a),找尋形如p->...q的產生式
return (j-1);
}void insertl(char a,char b,sqstack &s)//插入lastvt集
void printf_ff()//輸出firstvt和lastvt
void printf_t()
printf("/n");
}printf("$ ");
for(j=0;j<=vtnum;j++)
printf("/n");
}int control()//主控程式,核心是當前符號a[p]和s[j]的關係
;//存放待分析字串
char q;//工作單元
int x,y,z,j=0,k=1,p=0;//j是棧的查詢指標,k是棧頂指標,p是字串指標,s[1]作為棧底
vt[vtnum]='$';
vtnum++;//把結束符'$'加入終結符集,後面將用到
printf("/n請輸入要分析的字串(以$結尾):");
cin>>a;
s[k]='$';//把$壓棧
s[k+1]='/0';
printf("/n分析過程:/n堆疊 優先關係 當前符號 輸入流 動作 /n");
if(test(s[k])<100)//判斷s[k]是否是終結符或'$',如果是,j=k,s[j]是從棧頂向下首個終結符或者'$'
j=k;
else
j=k-1;
dofor(x=1;s[x]!='/0';x++)
printf("%c",s[x]);
for(y=0;y ");
else if(t[test(s[j])][test(a[p])]==1)
printf(" < ");
else
printf(" = ");//輸出關係
printf(" %c ",a[p]);//輸出當前符號
z=0;
for(x=p+1;a[x]!='/0';x++)
for(x=0;xif(t[test(s[j])][test(a[p])]==2)//s[j]>a[p],找到最左素短語,歸約
while(!(t[test(s[j])][test(q)]==1));
k=j+1;
s[k]='n';//歸約,'n'代表任意非終結符
s[k+1]='/0';
}else//s[j]<=a[p],未找到最左素短語,移進
}while(!(k==2&&a[p]=='$'&&s[k]=='n'));
printf("$n = $ 結束 /n");
printf("/nsucceed,您輸入的句型和文法相符!/n");
return ok;
}
編譯原理 算符運算優先
1 移動規約分析法 自底向上的語法分析方法,也稱為 移動歸約分析法 2 文法g s s a 且a b則稱b是句型 b 相對於非終結符a的短語 素短語與最左素短語 g的句型的素短語是乙個短語,它至少包含乙個終結符,且除自身外不再包含其他素短語。處於句型最左邊的素短語為最左素短語 控制代碼 乙個句型的最...
編譯原理實驗四 算符優先文法語法分析
實驗任務 1 實現算符優先分析演算法。2 完成以下描述算術表示式的算符優先文法的算符優先分析過程。g e e e t e t t t t f t f f f e i 說明 終結符號i為使用者定義的簡單變數,即識別符號的定義。設計要求 1 構造該算符優先文法的優先關係矩陣或優先函式 2 輸入串應是詞法...
編譯原理 算符優先分析法
一 算符文法的定義 二 定義任意兩個終結符號之間的優先關係 解釋 1 ab兩個可以同時規約,故優先順序相等 2 將r的推導式代入p的產生式中,最終也會形成如 1 中一樣的p的產生式的形式,但此時需要對b先進行規約,再規約a,故a的優先順序小於b的優先順序 3 同理可得,b的優先順序小於a的優先順序 ...