编译原理 实验3 算符优先分析 - 下载本文

编译原理 实验3 算符优先分析

一、实验目的

通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法,对给定的符号串进行分析的方法。 二、实验内容

1. 给定一文法G,输出G的每个非终结符的FIRSTVT集和LASTVT集。 2. 构造算符优先表。

3. 对给定的符号串进行分析,包含符号栈,符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。 三、程序思路

在文法框内输入待判断文法产生式,格式E->a|S,注意左部和右部之间是“->”,每个产生式一行,ENTER键换行。文法结束再输入一行G->#E#

1. 先做文法判断,即可判断文法情况。

2. 若是算符优先文法,则在优先表栏显示优先表。 3. 写入要分析的句子,按回车即可。 4. 在分析过程栏,可以看到整个归约过程情况 四、实验结果

FunctorFirst.h

#include #include #include #include

usingnamespace std;

#definerightlength 20 #defineproduct_num 20 #definenum_terminal 26

structProduction { };

structVT { };

structStack { };

classCMyDlg {

public:CMyDlg();

voidInputRule(); CStringshowLastVT(); CStringshowFirstVT();

CStringshownoTerminal(char G[]); CStringshowTerminal(char g[]);

CStringshowLeftS(char S[], int j, int k); voidInitAll();

CStringshowSentence(CString sen, int start); CStringshowStack(char S[], int n); voidInitarry(char arry[], int n); CStringProdtoCStr(Production prod); intselectProd(int i, int j, char S[]); voidpreFunctor(CString sen);

voidinsertFirstVT(Stack S[], int&sp, char P, char a); voidinsertLastVT(Stack S[], int&sp, char P, char a); voidShowPreTable(); voidcreatePreTable(); char P; char a;

bool vt[num_noterminal][num_terminal]; char Left;

char Right[rightlength]; int num;

// 产生式最多个数 // 非终结符最多个数

#definenum_noterminal 26

// 终结符最多个数

};

char pretable[num_terminal][num_terminal]; bool like_Q(Production prod, char Q); voidcreateLastVT();

bool likeQ_(Production prod, char Q); bool likeQa_(Production prod); bool like_aQ(Production prod); bool like_a(Production prod); bool likea_(Production prod); boolDignose(char c); intfindg(char c); intfindG(char c); voidcreateFirstVT(); voidcreateTerminal(); voidcreatenoTerminal();

voidbuildProduction(CString s); booltest(CString s); void parse(); CString gram; VT FirstVT; VT LastVT; int locProduct; char g[num_terminal]; int i_G; int i_g; CString m_sen;

// 已有产生式个数

char G[num_noterminal];

// 语法分析 // 存放文法;

Production production[product_num];

FunctorFirst.cpp

#include\

CMyDlg::CMyDlg() { }

boolCMyDlg::test(CStrings) {

bool t = 1;

for (int i = 0;i

// 测试是否是算符优先文法

}

if (s[i]> 64 &&s[i]< 91 &&s[i + 1]>64 &&s[i + 1]< 91) { }

t = 0; break;

return t;

voidCMyDlg::InputRule() { }

voidCMyDlg::buildProduction(CStrings) {

int i = 0; input.close();

cout << endl <<\这是算符优先文法!\<< endl; }

while (getline(input, line)) {

if (test(line.c_str()) == 0) { }

buildProduction(line.c_str());

cout << endl <<\这不是算符优先文法!\<< endl; exit(0);

cout <<\请输入语法文件的路径:\; cin >> infile; cout << endl;

ifstream input(infile.c_str()); if(!input) { }

cout << endl <<\打不开文件,请确认输入的路径有效###\<< endl; cout <<\请再次运行本程序!!!\<< endl << endl; exit(0); string infile; string line;

}

int j = 0; int k = 0;

for (k = 0;k

for (i = k + 1;i

int temp = i;

for (i = temp + 1;i

locProduct++;

if (s[i] != '|') { } else { }

locProduct++;

production[locProduct].Left = production[locProduct - 1].Left; j = 0;

if (s[i] != ' ') { }

production[locProduct].Right[j] = s[i]; j++;

production[locProduct].num = j;

if (s[i - 1] == '-'&&s[i] == '>')

break; if (s[k] != ' ') { }

production[locProduct].Left = s[k]; break;

// 得到左部

voidCMyDlg::createnoTerminal() {

i_G = 0; int j = 0;

// 建立非终结符索引

// 最后一个位置的下一个下标

for (int i = 0;i< locProduct;i++) {