辽宁师范学计算机信息技术学院
综合性实验报告
课程名称: 编译技术
实验题目:语法制导四元式(算术表达式)生成器
学生姓名:
专业: 计算机科学技术
学号:
实验日期: 2015
实验目
1 理解语法分析器原理语法制导翻译程实质
2 学会语法分析识语法成分变换中间代码形式中逆波兰记号形式语义分析方法编程实现算术表达式进行语法分析程基础进行语义分析
实验容
1 输入算术表达式源语言形式输出语法分析程(输入流变化程)四元式序列
2 定算术表达式首先通词法分析程识出类语法成分输出文件中然采预测分析方法进行分析语法检查出具体分析程包括分析步骤分析栈剩余符号产生式基础文法中插入语义动作语法分析程中遇语义动作做相应翻译工作终结果(算术表达式逆波兰式)输出源文件中
实验程
判断文法否LL(1)文法
(1)E>E+E
(2)E>E*E
(3)E>i|E
文法含左递消左递确定算法优先次序文法变:
(1)E>TG
(2)G>+TG|^
(3)T>FS
(4)S>*FS|^
(5)F>i|E
1推出^非终结符表:
E
G
T
S
F
否
否
否
2非终结符FIRST集合:
FIRST(E){(i}
FIRST(G){+ ∅}
FIRST(T){(i}
FIRST(S){* ∅}
FIRST(F){(i}
3非终结符FOLLOW集合:
FOLLOW(E){)#}
FOLLOW(G){)#}
FOLLOW(T){+)#}
FOLLOW(S){+)#}
FOLLOW(F){*+)#}
4产生式SELECT集合:
SELECT(E>TG){(i}
SELECT(G>+TG){+}
SELECT(G>^){)#}
SELECT(T>FS){(i}
SELECT(S>*FS){*}
SELECT(S>^){+)#}
SELECT(F>E){(}
SELECT(F>i){i}
5:
SELECT(G>+TG)∩SELECT(G>∅) {+}∩{)#} ∅
SELECT(S>*FS)∩SELECT(S>∅) {*}∩{+)#} ∅
SELECT(F>E)∩SELECT(F>i) {i}∩{(} ∅
文法LL(1)文法
二构造预测分析表
i
+
*
(
)
#
E
TG
TG
E
G
+TG
^
^
T
FS
FS
S
∅
*FS
^
^
F
i
(E)
三程序开始
1预测试算术表达式:
4+(467e10)*(789)+5#
分析:i+(i)*(i)+i# 写入文件中
边分析边编织逆波兰式数组stack1存放
1 存入9文法产生式:
E>TG
E2>E
G>+TG
G2>^
T>FS
S>*FS
S2>^
F>i
F2>(E)
2 存入预测分析表格(二)
3 利 终结符数组:vt非终结符数组:vn预测分析表table分析栈stack等等分析串str2进行分析分许程存入optxt中
具体代码:
#include
#include
#include
#include
char str2[20]{0} 存放识字符串i+(i)*(i)+i#
FILE *op 存储算术表达式文件a+(467e10)*(789)+b#
FILE *fp 存储分析程文件
char vt[7]{'i''+''*''('')''''#'} 终结符
char vn[5]{'E''G''T''S''F'} 非终结符
typedef struct type{ 产生式类型定义
char left 非终结符
char right[5] 产生式右边字符
}type
type EE1GG1TSS1FF1 8产生式
type table[7][7] 预分析表
char stack[30]{0} 分析栈
char stack1[30]{0} 存储逆波兰式
int s1st0 s>栈顶st>前需分析字符
void analy1(char str1[]){ 分析>i+(i)*(i)+i#
int i0j0p0q0
char s[30]{0} 辅助堆栈
while(str1[i]'#'){
switch(str1[i]){
case 'a'str2[j++]'i'stack1[q++]'a' break
case 'b'str2[j++]'i'
stack1[q++]s[p2]
stack1[q++]s[p]s[p]'\0's[p]'\0'
stack1[q++]'b'
break
case '+'s[p++]'+' str2[j++]'+'break
case '*'stack1[q++]s[p]
s[p]'\0'
str2[j++]'*'
s[p++]'*'
break
case '('str2[j++]'('break
case ')'stack1[q++]s[p]s[p]'\0'
stack1[q++]'b'
str2[j++]')'break
case ''s[p++]'@'
if(str2[j1]'i')break
else str2[j++]''
break
case ''stack1[q++]''
if(str2[j1]'i')break
else str2[j++]'i'
break
case '0'stack1[q++]'0'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '1'stack1[q++]'1'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '2'stack1[q++]'2'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '3' stack1[q++]'3'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '4' stack1[q++]'4'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '5' stack1[q++]'5'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '6' stack1[q++]'6'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '7'stack1[q++]'7'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '8' stack1[q++]'8'
if(str2[j1]'i')break
else str2[j++]'i'
break
case '9' stack1[q++]'9'
if(str2[j1]'i')break
else str2[j++]'i'
break
case 'e'stack1[q++]s[p]s[p]'\0'
if(str2[j1]'i'){
s[p++]'e'
break
}
else str2[j++]'i'
break
}
i++
}
stack1[q++]s[p]s[p]'\0'
str2[j]'#'
}
void store(){ 8产生式存入
printf(产生式:\n)
Eleft'E'
strcpy(ErightTG)
printf(c>s\nEleftEright)
E1left'E'
strcpy(E1rightE)
printf(c>s\nE1leftE1right)
Gleft'G'
strcpy(Gright+TG)
printf(c>s\nGleftGright)
G1left'G'
strcpy(G1right^)
printf(c>s\nG1leftG1right)
Tleft'T'
strcpy(TrightFS)
printf(c>s\nTleftTright)
Sleft'S'
strcpy(Sright*FS)
printf(c>s\nSleftSright)
S1left'S'
strcpy(S1right^)
printf(c>s\nS1leftS1right)
Fleft'F'
strcpy(Frighti)
printf(c>s\nFleftFright)
F1left'F'
strcpy(F1right(E))
printf(c>s\n\nF1leftF1right)
}
int length(char a[]){ 求数组长度
int il0
for(i0i<5i++)
if(a[i]'\0') l++
return l
}
void tables(){ 建立分析表
int ij
for(i0i<4i++) 初始化分析表
for(j0j<6j++)
table[i][j]left'N' 表left置N’
table[0][5]E1 table[0][0]table[0][3]E 存入文法
table[1][1]G table[1][4]table[1][6]G1
table[2][0]T table[2][3]T
table[3][2]S table[3][1]table[3][4]table[3][6]S1
table[4][0]F table[4][3]F1
printf(表达式文法预测分析表:\n)
printf( \t)
for(i0i<7i++) printf(c\tvt[i])
printf(\n)
for(i0i<5i++){
printf(c\tvn[i])
for(j0j<7j++)
printf(s\ttable[i][j]right)
printf(\n)
}
printf(\n)
}
void write(char str[]){ 字符串写入文件fp
fputs(strfp)
}
void fun(int hint l){ 推导产生式倒序存入分析栈中
int ilength(table[h][l]right)1
s
for(i i>1 i )
stack[++s]table[h][l]right[i] 产生式逆序入栈
if(stack[s]'^')
stack[s]'\0'
fputc(table[h][l]leftfp)
write(>)
write(table[h][l]right)
write(\n)
}
void print(int n){ 写入文件
fprintf(fpd\t\tn++) 步骤
fprintf(fps\t\tstack) 分析栈
fprintf(fps\t\tstr2) 剩余输入串
}
void analy2(){
int ijn0finish0hl
char Xa
store() 产生式
tables() 预测分析表格
write(********************分析********************\n)
write(步骤\t\t分析栈\t\t剩余字符\t\t产生式\n)
stack[++s]'#' #入栈
stack[++s]'E' E入栈
astr2[st] 前剩余串左字符
while(s>1){
Xstack[s] 栈顶字符
print(++n)
for(i0i<5i++){
if(Xvn[i]){ 栈顶非终结符时E G T S F
hi 行号
for(j0j<7j++){
if(avt[j]){
lj 列号
break
}
}
if(table[h][j]left'N'){ 空时
fun(hl)
}
}
}
for(i0i<7i++){ 栈顶终结符时i + * ( ) #
if(Xvt[i]){
stack[s]'\0'
str2[st++]' '
astr2[st] 前剩余串左字符
fputc(Xfp)
if(X'#') write(接受\n)
else write(匹配\n)
}
}
}
}
void main(){
char str1[300]{0} 预分析算术表达式a+(467e10)*(789)+b#
char h[]\n
fpfopen(Hfptxtr)
fgets(str1300fp) fgets读取行 fgetc读取字符 fread想长度
fclose(fp)
analy1(str1)
fpfopen(Hfptxta) 会覆盖原数
fwrite(hsizeof(h)1fp) 换行
fwrite(stack1sizeof(stack1)1fp) 写入逆波兰式
fclose(fp)
printf(分析符号串:s\n\nstr2)
opfopen(Hoptxtw)
fputs(str2fp) 写入i+(i)*(i)+i#
write(\n)
analy2()
fclose(op)
}
四运行结果截屏:
源文件:
屏幕输出:
分析程:
运行源文件:
实验结果分析
文档香网(httpswwwxiangdangnet)户传
《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
该内容是文档的文本内容,更好的格式请下载文档