当前位置:文档之家› 编译原理-预测分析法(附源码)

编译原理-预测分析法(附源码)

预测分析法实验报告一、实验项目名称预测分析法二、实验目的根据某一LL(1)文法编制调试预测分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对预测分析法的理解。

三、实验环境Windows 10Microsoft Visual Studio 2015四、实验内容本次实验的LL(1)文法为表达式文法:E→E+T | TT→T*F | FF→i | (E)编写识别表达式文法的合法句子的预测分析程序,对输入的任意符号串,给出分析过程及分析结果。

分析过程要求输出步骤、分析栈、剩余输入串和所用产生式。

如果该符号串不是表达式文法的合法句子,要给出尽量详细的错误提示五、源程序清单、测试数据、结果#include<iostream>#include<string>using namespace std;const int NUM = 20;//初始化的栈的大小//非终结符数组集char Var[5] = { 'E','R','T','M','F' };//终结符数组集char Ter[6] = { 'i','+','*','(',')','#' };string pred[5][6] ={ { "TR","","","TR","","" },{ "","+TR","","","@","@" },{ "FM","","","FM","","" },{ ""," @","*FM","","@","@" },{ "i","","","(E)","","" } };typedef struct {char *top;char *base;int stacksize;int num;}Stack;// 栈结构体void init(Stack *ss) {//初始化栈ss->base = (char *)malloc(NUM * sizeof(char));if (!ss->base)exit(1);ss->top = ss->base;ss->stacksize = NUM;ss->num = 0;}void push(Stack *ss, char c) {//入栈操作if (ss->top - ss->base >= ss->stacksize)exit(1);*(ss->top) = c;ss->top++;ss->num++;}void pop(Stack *ss) {//出栈操作if (ss->top == ss->base)exit(1);ss->top--;ss->num--;}char getTop(Stack *ss) {//取得栈顶元素if (ss->top == ss->base)exit(1);return *(ss->top - 1);}int isT(char c) {//判断是否为终结符int i = 0;int ret = 0;for (i = 0; i<6; i++) {if (Ter[i] == c){ret = 1; break;}}return ret;}string isInPred(char v, char t) {//查找预测分析表,并返回产生式右部int i, j;for (i = 0; i<5; i++){if (Var[i] == v)break;}for (j = 0; j<6; j++){if (Ter[j] == t)break;}if (pred[i][j] !=""){return pred[i][j];}elsereturn"";}void displayStack(Stack *stack) { //输出分析站的内容string str;int i = 0;Stack ss = *stack;while (ss.num != 0){str += getTop(&ss);pop(&ss);}for (i = str.length() - 1; i >= 0; i--){cout << str.at(i);}}void predict(Stack stack, string input)//预测分析总函数{int a = 1;char b;char ctop;//当前栈顶符号char cinput;//当前输入符号int i = 0, j = 0, count = 0;int error = 0;cout <<"步骤"<<'\t'<<"栈"<<'\t'<<"输入缓冲区"<<'\t'<<"所用的产生式"<<endl;cout << count++ <<'\t';displayStack(&stack);cout <<'\t'<<input<<'\t'<<""<< endl;while (getTop(&stack) != '#'){string produce = "";ctop = getTop(&stack);cinput = input.at(i);if (isT(ctop))//栈顶符号为终结符{if (ctop == cinput){pop(&stack);i++;}else{error = 1; break;}produce +="\"";produce += ctop;produce +="\"匹配";}else//栈顶符号位非终结符{string str = isInPred(ctop, cinput);if (str !=""){pop(&stack);if (str !="@"){for (j = str.length() - 1; j >= 0; j--)push(&stack, str.at(j));}produce += ctop;produce +="→";produce += str;}else{error = 1; break;}}//栈顶符号位非终结符cout << count++ <<'\t';displayStack(&stack);cout <<'\t'<<input.substr(i) <<"\t\t"<< produce << endl;}if (error)cout <<"不接受"<< endl;elsecout <<"接受"<< endl;}void main(){while (1) {int sel;//继续或者退出程序选择string input;//输入串int i = 0, j = 0;Stack stack;init(&stack);push(&stack, '#');push(&stack, 'E');cout <<"----------------文法如下--------------"<< endl;cout <<"E→E+T | T"<< endl;cout <<"T→T*F | F"<< endl;cout <<" F→i | (E)"<< endl;cout <<"----------------请输入表达式(以#结尾)--------------"<< endl;cin >> input;cout <<"“R表示“E'”,”M“表示“T'”,”@“表示“空”"<< endl;predict(stack, input);sel=0;if (sel == 0)exit(0);elsesystem("cls");}}六、实验小结和思考本次实验的文法是写在程序中的,不可以自行输入,难度不是很难,并没有太大问题,只是一些未初始化的小问题。

以后要积极做实验,做的程序要更加灵活。

相关主题