编译原理实验报告3-LL(1)文法构造

发布时间 : 星期四 文章编译原理实验报告3-LL(1)文法构造更新完毕开始阅读

}

}

}

gp->P[i - 1].insert(0, 1, ch_i); for (; h <= s; h++) { }

gp->P[m - 1] += \;

gp->P[i - 1].erase(gp->P[i - 1].size() - 1, 1);

if (flagpos[h]) { }

splitstr[h] += newWord;

gp->P[i - 1] = gp->P[i - 1] + splitstr[h] + \;

simplify(gp); //化简无用的产生式

提取左因子(包括辅助函数):

//对字符串数组排序

void str_sort(string *str, int num) { }

/*子函数,提取左因子*/

void remove_left_gene(struct grammar *gp) {

char ch, newWord;

for (rule_a = 0; rule_a < m; rule_a++) {

int bre = -1; int oldpo = 0; int num = 0, ps = 3; string str[30],restr[30];

//前者用于判断,需要保持原样,后者用于对有公

//分割替换后的产生式

//遍历所有产生式

//标记已对产生式进行过左因子的提取

int rule_a, i, j, k, l, matchnum,oldmatchnum, resize,size; int i, j;

for (i = 0; i < num; i++) { }

for (j = i + 1; j < num; j++) { }

if (str[i] > str[j])

str[i].swap(str[j]);

共左因子的候选进行提取,可变

while (ps != gp->P[rule_a].size() + 1) { }

str_sort(str, num); str_sort(restr, num);

//对所有候选按ASCII码进行排序,以便于简

str[num] = strsplit(gp->P[rule_a], ps); restr[num] = str[num]; ps = ps + str[num].size() + 1; num++;

化对公共左因子的判断,只需先对前面候选判断

int ca_i; string Pa = \;

Pa.insert(0, 1, gp->Vn[rule_a]);

for (ca_i = 0; ca_i < num; ca_i++) { //对排序后的候选进行重组并存入文法 }

gp->P[rule_a] = Pa; int ipo = 0;

ipo = 0; size = 0; resize = 0; oldmatchnum = 0; int i_s = str[i].size(); for (j = 0; j < i_s; j++) { }

/*有公共左因子的处理过程*/

if (matchnum != oldmatchnum || j == i_s) {

bre ++;

string match, repstr, can, newP; match = str[i].substr(0, j);

//获取公共左因子

matchnum = 0; ch = str[i][j]; int kf = num;

for (k = i + 1; k < num && k < kf; k++) { //对i之后的候选进行判断,是否有与i对应 }

if (j == 0) { } else { }

if (oldmatchnum != matchnum) break;

//判断是否有公共左因子是i的第一个字符的

if (str[k][j] == ch) { } else { }

break; matchnum++;

//有公共左因子

//对候选的逐个字符遍历

//标记除了本身,有几个候选有公共左因子

//辅助免除对已判断过有左因子的候选的遍历

//遍历候选

for (i = 0; i < num; i++,i += ipo) {

if (ca_i == num - 1) else

Pa += str[ca_i] + \; Pa += str[ca_i];

的公共左因子

情况,有则特别处理

if (matchnum == 0)

break;

else { oldmatchnum = matchnum; kf = i + 1 + oldmatchnum; }

}

}

}

}

newWord = GetWord(gp->Vn); gp->Vn[m] = newWord; m++; newP = \;

newP.insert(0, 1, newWord); repstr = match + newWord; int renum = num; if (bre > 0) { }

//得到新的非终结符

//将新非终结符存入文法

//得到要被替换的有公共左因子的所有候选

//若对同一产生式还存在另一个公共左因子(之前

提取过一次左因子),需进行特别处理

size = resize = 0; renum = 0; ps = 3;

while (ps != gp->P[rule_a].size() + 1) { }

//分割变化后

的产生式

restr[renum] = strsplit(gp->P[rule_a], ps); ps = ps + restr[renum].size() + 1; renum++;

/*将已经提取过左因子的以候选为单位的字符串重新组合成产生式(包括新产生for (l = 0; l <= i - oldpo + oldmatchnum; l++) { }

gp->P[rule_a].replace(resize + 3, size + oldmatchnum, repstr); //原产生式以替换的方if (i + 1 + oldmatchnum > num) { break; } else oldpo = ipo = oldmatchnum;

if (l >= i - oldpo) { } else { }

resize += restr[l].size(); resize++;

size += restr[l].size(); can = restr[l].substr(j); if (can == \)

can = \;

if (l == i - oldpo + oldmatchnum) newP += can; else newP = newP + can + \; gp->P[m - 1] = newP;

式)*/

式进行改变

4、 主程序代码;

#include #include using namespace std;

struct grammar { };

int m = 0, n = 0;

char GetBC(FILE* fpi) { }

/*

整型函数,读入一行产生式分析出文法成员,参数分别是输入文本的文件指针、文法

第几行的产生式

*/

结构体的指针

void scanP(FILE* fpi,struct grammar *gp) {

char ch; string str; if (feof(fpi))

//存入一条产生式 //到达文件尾则返回

//读入产生式左部的非终结符

//将非终结符存入结构体

return;

char ch; do {

ch = fgetc(fpi); } while (ch == ' '); return ch;

//子函数,用于读取一个非空格字符

//全局变量,分别表示最近存入结构体的非终结符与终

结符是字符数组的第几个位置

char Vn[20]; char Vt[20]; char S;

string P[20];

//使用结构体定义文法 //非终结符 //终结符 //开始符号

//产生式

ch = GetBC(fpi);

if (ch >= 'A' && ch <= 'Z') {

str += ch; gp->Vn[m] = ch; m++;

ch = GetBC(fpi); if (ch == '-') {

str += ch; ch = GetBC(fpi); if (ch == '>') {

str += ch; while (1) {

ch = GetBC(fpi); if (ch == '\\n' || ch == ';')

break;

//读入换行符

联系合同范文客服:xxxxx#qq.com(#替换为@)