导航:首页 > 源码编译 > 华农编译原理语义分析实验代码

华农编译原理语义分析实验代码

发布时间:2024-03-04 02:58:25

1. 编译原理

编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。 编译原理是计算机专业设置的一门重要的专业课程。编译原理课程是计算机相关专业学生的必修课程和高等学校培养计算机专业人才的基础及核心课程,同时也是计算机专业课程中最难及最挑战学习能力的课程之一。编译原理课程内容主要是原理性质,高度抽象[1]。

中文名
编译原理[1]
外文名
Compilers: Principles, Techniques, and Tools[1]
领域
计算机专业的一门重要专业课[1]
快速
导航
编译器

编译原理课程

编译技术的发展

编译的基本流程

编译过程概述
基本概念
编译原理即是对高级程序语言进行翻译的一门科学技术, 我们都知道计算机程序由程序语言编写而成, 在早期计算机程序语言发展较为缓慢, 因为计算机存储的数据和执行的程序都是由0、1代码组合而成的, 那么在早期程序员编写计算机程序时必须十分了解计算机的底层指令代码通过将这些微程序指令组合排列从而完成一个特定功能的程序, 这就对程序员的要求非常高了。人们一直在研究如何如何高效的开发计算机程序, 使编程的门槛降低。[2]
编译器
C语言编译器是一种现代化的设备, 其需要借助计算机编译程序, C语言编译器的设计是一项专业性比较强的工作, 设计人员需要考虑计算机程序繁琐的设计流程, 还要考虑计算机用户的需求。计算机的种类在不断增加, 所以, 在对C语言编译器进行设计时, 一定要增加其适用性。C语言具有较强的处理能力, 其属于结构化语言, 而且在计算机系统维护中应用比较多, C语言具有高效率的优点, 在其不同类型的计算机中应用比较多。[3]
C语言编译器前端设计
编译过程一般是在计算机系统中实现的, 是将源代码转化为计算机通用语言的过程。编译器中包含入口点的地址、名称以及机器代码。编译器是计算机程序中应用比较多的工具, 在对编译器进行前端设计时, 一定要充分考虑影响因素, 还要对词法、语法、语义进行分析。[3]
1 词法分析[3]
词法分析是编译器前端设计的基础阶段, 在这一阶段, 编译器会根据设定的语法规则, 对源程序进行标记, 在标记的过程中, 每一处记号都代表着一类单词, 在做记号的过程中, 主要有标识符、关键字、特殊符号等类型, 编译器中包含词法分析器、输入源程序、输出识别记号符, 利用这些功能可以将字号转化为熟悉的单词。[3]
2 语法分析[3]
语法分析是指利用设定的语法规则, 对记号中的结构进行标识, 这包括句子、短语等方式, 在标识的过程中, 可以形成特殊的结构语法树。语法分析对编译器功能的发挥有着重要影响, 在设计的过程中, 一定要保证标识的准确性。[3]
3 语义分析[3]
语义分析也需要借助语法规则, 在对语法单元的静态语义进行检查时, 要保证语法规则设定的准确性。在对词法或者语法进行转化时, 一定要保证语法结构设置的合法性。在对语法、词法进行检查时, 语法结构设定不合理, 则会出现编译错误的问题。前端设计对精确性要求比较好, 设计人员能够要做好校对工作, 这会影响到编译的准确性, 如果前端设计存在失误, 则会影响C语言编译的效果。[3]

2. 急(高悬赏 帮个忙) 求编译原理课程设计---c语言实现c-的语法分析,在线等

新建一个文本文档在你工程目录下,名字起为"输入.txt",里面的内容可以为
begin a:=1+7*(6+3);b:=1end#

输出是在"输出.txt"中查看,以下为输出情况:

词法分析结果如下:
(1, begin)
(10, a)
(18, :=)
(11, 1)
(13, +)
(11, 7)
(15, *)
(27, ()
(11, 6)
(13, +)
(11, 3)
(28, ))
(26, ;)
(10, b)
(18, :=)
(11, 1)
(6, end)
(0, #)
语法分析结果如下:(以四元式形式输出)
( +, 6, 3, t1)

( *, 7, t1, t2)

( +, 1, t2, t3)

( =, t3, __, a)

( =, 1, __, b)

//提供一个编译原理的语义分析程序 你可以直接拆猜森复制 用TC进行调试
#include "stdio.h"
#include "string.h"
#include <malloc.h>
#include <conio.h>
#include "stdlib.h"

char prog[100],token[8],ch;
char *rwtab[6]={"begin","if","then","while","do","end"};
int syn,p,m,n,sum,q;
int kk;
//四元式表的结构如下:
struct
{
char result1[8];
char ag11[8];
char op1[8];
char ag21[8];
}quad[20];

char *factor();
char *expression();
int yucu();
char *term();
int statement();
int lrparser();
char *newtemp();
void scaner();
void emit(char *result,char *ag1,char *op,char *ag2);

void main()
{
FILE *fp1,*fp2;

if((fp1=fopen("输入.txt","rt"))==NULL)
{
printf("Cannot open 输入.txt\n");
getch();
exit(1);
}
if((fp2=fopen("输出.txt","wt+"))==NULL)
{
printf("Cannot create 输出.txt FILE.strike any key exit");
getch();
exit(1);
}

int j;
q=p=kk=0;
p=0;
//printf("Please Input a String(end with '#'旅亩):\n");
while(ch!='#')
{
ch = fgetc(fp1);
if(ch == EOF)
{
printf("文件为空,请检查后再尝试!");
return ;
}

prog[p++]=ch;
}
if(prog[p]=='#')
{
printf("输入的待分析的串不是以'#'结尾,请修改之后再尝试!\n");
return;
}
p=0;
char buffer1[200] = {0};
sprintf(buffer1,"词法分析结果如下:\n");
fputs(buffer1,fp2);
//printf("词法分析结果如下:\n");
do
{
scaner();
switch(syn)
{
case 11:
//printf("(%d,%d)\n"兆旦,syn,sum);
sprintf(buffer1,"(%d, %d) \n",syn,sum);
fputs(buffer1,fp2);
break;
default:
//printf("(%d,%s)\n",syn,token);
sprintf(buffer1,"(%d, %s)\n",syn,token);
fputs(buffer1,fp2);
break;
}
}while(syn!=0);
printf("\n");

p=0;
char buffer[200]={0};
sprintf(buffer,"语法分析结果如下:(以四元式形式输出)\n");
fputs(buffer,fp2);
//printf("语法分析结果如下:(以四元式形式输出)\n");
scaner();//扫描函数
lrparser();
if(q>19)
printf(" to long sentense!\n");
else
{

for (j=0;j<q;j++)
{
//printf("( %s, %s, %s, %s) \n\n",quad[j].op1,quad[j].ag11,quad[j].ag21,quad[j].result1);
sprintf(buffer,"( %s, %s, %s, %s) \n\n",quad[j].op1,quad[j].ag11,quad[j].ag21,quad[j].result1);
fputs(buffer,fp2);
}
}
printf("已把相应的词法和语法的结果保存到相应的文件中,请查阅!\n");
fclose(fp1);
fclose(fp2);
}
int lrparser()
{
int schain=0;
kk=0;
if (syn==1) //得到begin
{
scaner();//扫描下个字符
schain=yucu();
if(syn==6)//得到end
{
scaner();//扫描下个字符
if((syn==0)&&(kk==0)) //得到#
printf("Success!\n");
}
else
{
if(kk!=1)
printf("short of 'end' !\n");
kk=1;
getch();
exit(0);
}
}
else
{
printf("short of 'begin' !\n");
kk=1;
getch();
exit(0);
}
return (schain);
}
int yucu()
{
int schain=0;
schain=statement();
while(syn==26)
{
scaner();
schain=statement();
}
return (schain);
}
int statement()
{
char tt[8],eplace[8];
int schain=0;
if (syn==10)
{
strcpy(tt,token); //tt中保存的是第一个字符
scaner();
if(syn==18) //检测到=号
{
scaner();
strcpy(eplace,expression());
emit(tt,eplace,"=","__");
schain=0;
}
else
{
printf("short of sign ':=' !\n");
kk=1;
getch();
exit(0);
}
return (schain);
}
}
char *expression()
{
char *tp,*ep2,*eplace,*tt;
tp=(char *)malloc(12);
ep2=(char *)malloc(12);
eplace=(char *)malloc(12);
tt=(char *)malloc(12);

strcpy(eplace,term());

while((syn==13)||(syn==14))
{
if (syn==13)
strcpy(tt,"+");
else
strcpy(tt,"-");

scaner();
strcpy(ep2,term());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2);
strcpy(eplace,tp);
}
return (eplace);
}
char *term()
{
char *tp,*ep2,*eplace,*tt;
tp=(char *)malloc(12);
ep2=(char *)malloc(12);
eplace=(char *)malloc(12);
tt=(char *)malloc(12);

strcpy(eplace,factor());

while((syn==15)||(syn==16))
{
if (syn==15)
strcpy(tt,"*");
else
strcpy(tt,"/");
scaner();
strcpy(ep2,factor());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2);
strcpy(eplace,tp);
}
return (eplace);
}
char *factor()
{
char *fplace;
fplace=(char *)malloc(12);
strcpy(fplace,"");

if(syn==10) //得到字符
{
strcpy(fplace,token);
scaner();
}
else if(syn==11) //得到数字
{
itoa(sum,fplace,10);
scaner();
}
else if(syn==27) //得到)
{
scaner();
fplace=expression();
if(syn==28) //得到(
scaner();
else
{
printf("error on ')' !\n");
kk=1;
getch();
exit(0);
}
}
else
{
printf("error on '(' !\n");
kk=1;
getch();
exit(0);
}
return (fplace);
}
//该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2...
char *newtemp()
{
char *p;
char m[8];
p=(char *)malloc(8);

kk++;
itoa(kk,m,10);
strcpy(p+1,m);
p[0]='t';
return(p); //设置中间变量名放在一个字符数组中,字符数组的第一个字符为t第二个字符为m表示的数值
}
void scaner()
{
sum=0;
///for(m=0;m<8;m++)
//token[m++]=NULL;
memset(token,0,8);
m=0;
ch=prog[p++];
while(ch==' ')
ch=prog[p++];
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
{
while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
{
token[m++]=ch;
ch=prog[p++];
}
p--;
syn=10;
token[m++]='\0';
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
else if((ch>='0')&&(ch<='9'))
{
while((ch>='0')&&(ch<='9'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
}
else switch(ch)
{
case '<':m=0;
ch=prog[p++];
if(ch=='>')
{
syn=21;
}
else if(ch=='=')
{
syn=22;
}
else
{
syn=20;
p--;
}
break;
case '>':m=0;
ch=prog[p++];
if(ch=='=')
{
syn=24;
}
else
{
syn=23;
p--;
}
break;
case ':':m=0;
token[m++] = ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++] = ch;
}
else
{
syn=17;
p--;
}
break;

case '+': syn=13;token[0] = ch; break;
case '-': syn=14;token[0] = ch; break;
case '*': syn=15;token[0] = ch;break;
case '/': syn=16;token[0] = ch;break;
case '(': syn=27;token[0] = ch;break;
case ')': syn=28;token[0] = ch;break;
case '=': syn=25;token[0] = ch;break;
case ';': syn=26;token[0] = ch;break;
case '#': syn=0;token[0] = ch;break;
default: syn=-1;break;
}
}
//该函数是生成一个三地址语句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[q].result1,result);
strcpy(quad[q].ag11,ag1);
strcpy(quad[q].op1,op);
strcpy(quad[q].ag21,ag2);
q++; //统计有多少个四元式
}

3. 循环语句的语法分析及语义分析程序设计

目 录
1 课程任务书····································(2)
1问题描述·······································(3)
2文法及属性文法的描述···························(3)
2.1 while-do循环语句的文法·····················(3)
2.2while-do循环语句的结构翻译·················(3)
3语法分析及中间代码形式的描述···················(4)
3.1 语法分析方法·······························(4)
3.2 中间代码形式描述···························(4)
4简要的分析与概要设计···························(5)
4.1词法分析··································(5)
4.2递归下降翻译器的设计·······················(5)
4.3语法制导翻译·······························(5)
5 详细的算法描述································(6)
5.1 文法·······································(6)
5.2 查错·······································(6)
6 测试方法和测试结果···························(9)
6.1测试方法··································(9)
6.2测试结果··································(10)
7 设计的特点、不足、收获与体会·················(10)
7.1 设计的特点································(10)
7.2 不足、收获与体会··························(11)
8 参考文献·····································(11)

课程设计任务书
题 目: 循环语句的语法分析及语义分析程序设计(递归下降法)
1.目的
通过设计、编制、调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。

2.设计内容及要求
WHILE〈布尔表达式〉DO〈赋值语句〉
其中
(1)学号29至32的同学按顺序分别选择递归下降法、LL(1)、算符优先分析法(或简单优先法)、LR法完成以上任务,中间代码选用四元式。
(2)如1题写出符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。
(3)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

3.课程设计报告书的内容应包括:
1.设计题目、班级、学号、姓名、完成日期;
2.给出语法分析方法及中间代码形式的描述、文法和属性文法的设计;或者词法分析方法
3.及符号表和TOKEN代码的设计。
4.简要的分析与概要设计;
5.详细的算法描述;
6.源程序清单;
7.给出软件的测试方法和测试结果;
8.设计的评价、收获与体会。

4.时间安排:
第17周,周1-周4上午,周五全天

指导教师签名: 年 月 日
系主任(或责任教师)签名: 年 月 日

1问题描述
设计一个WHILE〈布尔表达式〉DO〈赋值语句〉循环语句的词法﹑语法及语义分析程序,语法分析选择递归下降法,采用用语法制导翻译输出中间代码四元式。
2文法及属性文法的描述。
2.1 while-do循环语句的文法
产生式为S-> while E do A,为便于语法制导翻译将其改写如下:
文法G(s)如下:
S-->WEDG (意思是while E do G)
G-->c=R
R-->dTe|d
T-->+|-|*|/
E-->aFb
F--> >|==|<

2.2 whlie-do循环语句的结构翻译:

3.语法分析方法及中间代码形式的描述
3.1语法分析方法
递归下降法的实现思想是为文法的每个非终结符号设计一个相对应的递归子程序,识别程序由一组这样的子程序组成。
它的优点是简单直观,易于构造,很多编译系统所实现
缺点是对文法要求很高,由于递归调用多,影响分析器的效率
其文法可以表示为:
E→T│E+T
T→F│T*F
F→i│(E)
可以用语法图来表示语言的文法,如图:

E

T

F

3.2中间代码形式描述
中间代码采用四元式输出,一个四元式是一个带有四个域的记录结构,这四个域分别称为op﹑arg1﹑arg2及result。域op包含一个代表运算符的内部码。语句while a<b do a=a+b的四元式输出形式如下:
100 ( <, a , b , 102 )
101 ( j , _ , _ , 105 )
102 ( + , a , b , n )
103 ( = , n , _ , a )
104 ( j , _ , _ , 100)
105
4.简要的分析与概要设计
4.1词法分析
词法分析程序的任务是:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号的中间程序。词法分析检查的错误主要是挑出源程序中出现的非法符号。所谓非法符号是指不是程序设计语言中允许出现的符号,就像自然语句中的错字。
4.2递归下降翻译器的设计
1.:对每个非终结符A构造一个函数过程,对A的每个继承属性设置一个形式参数,函数的返回值为A的综合属性,A对应的函数过程中,为出现在A的产生式中的每一个文法符号的每一个属性都设置一个局部变量。非终结符A对应的函数过程中,根据当前的输入符号决定使用哪个产生式候选。
2:每个产生式对应的程序代码中,按照从左到右的次序,对于单词符号,非3:终结符和语义动作分别做以下工作。
(1)对于带有综合属性x的终结符X,把x的值存入为X,x设置的变量中。然后产生一个匹配X的调用,并继续读入一个输入符号。
(2)对于每个非终结符号B,产生一个右边带有函数调用的赋值语句c=B(b1,b2,…,bk)
(3)对于语义动作,把动作的代码抄进分析器中,用代表属性的变量来代替对应属性的每一次引用。
4.3语法制导翻译
在语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译。属性文法的每个符号有属性,所以每个符号入栈时,必须连属性一起入栈,这样,栈符号就由文法符号及存放该符号属性的域所组成。由于属性类型不同,属性域存放的内容就要根据属性的类型来定。有的可能直接存放属性值,也有的存放的是指向属性值的指针。对于综合属性,其属性域不存放其属性值,而是存放一个指针,指向存贮该属性值的单元。对于继承属性,其属性域直接保存其属性值。继承属性的属性域刚入栈时为空,但是在该栈符号变成栈顶符号之前的某一时刻,它们必须接受相应的属性值,即在成为栈顶时,继承属性的属性域必须有值。
5详细的算法描述
5.1 文法
/*
文法G(s)
s-->WEDG
G-->c=R
R-->dTe|d
T -> +|-|*|/|%E-->aFb
F--> >|==|<
*/
5.2 查错
按照递归下降法求Wa<bDa=a+b,程序的执行顺序应该是S()W()EF()D()G()R()T()
S()
void S()
{
printf("%d\tS-->WEDG\n",total);total++;
W();
E();
}

W()
void W()
{
if(ch!='W')
{
printf("有非法字符%c请按回车返回!!",ch);
getchar();
getchar();
exit(1);
}
}

E()
void E()
{
ch=a[++i1];
if(ch!='a')
{
printf("有非法字符%c %c请按回车返回!!",ch);
getchar();
getchar();
exit(1);
}
printf("%d\tE-->aFb\n",total);total++;
F();
}

F()
void F()
{
int i;
ch=a[++i1];
i=i1+1;
if(a[i]!='b')
{
printf("有非法字符%c请按回车返回!!",a[i]);
getchar();
getchar();
exit(1);
}
switch(ch)
{
case '>':
printf("%d\tF-->>\n",total);total++;
break;
case '==':
printf("%d\tF-->==\n",total);total++;
break;
default:
printf("%d\tF--><\n",total);total++;
break;
}
D();
G();
}

D()
void D()
{
++i1;
ch=a[++i1];
if(ch!='D')
{
printf("有非法字符%c请按回车返回!!",ch);
getchar();
getchar();
exit(1);}
ch=a[++i1];
}

G()
void G()
{
int i=i1+1;
if(ch!='c'&&a[i]!='=')
{
printf("有非法字符%c %c请按回车返回!!",ch,a[i]);
getchar();
getchar();
exit(1);
}
printf("%d\tG-->c=R\n",total);total++;
R();
}

R()
void R()
{
int i;
i=i1+1;
i1=i1+2;
ch=a[i1];
if(a[i]!='='&&ch!='d')
{
printf("有非法字符%c %c请按回车返回!!",a[i],ch);
getchar();
getchar();
exit(1);
}
else
{
if((a[i1+1]=='+')||(a[i1+1]=='-')||(a[i1+1]=='*')||(a[i1+1]=='/'))
{
printf("%d\tR-->dTe\n",total);total++;
T();
}
else
{
printf("%d\tR-->d\n",total);total++;
W();
E();
}
}
}

T()
void T()
{
ch=a[++i1];
switch(ch)
{
case '+':
printf("%d\tT-->+\n",total);total++;
break;
case '-':
printf("%d\tT-->-\n",total);total++;
break;
case '*':
printf("%d\tT-->*\n",total);total++;
break;
default:
printf("%d\tT-->/\n",total);total++;
break;
}
ch='#';
}

6测试方法和测试结果
6.1测试方法
在C++环境下,设计几个有代表的用例,进行测试,例如:输入语句Wa<bDa=a+b#(其中d表示do ,w表示while)。若得出的不是预期的结果,那么程序就出现问题。如果有问题的话就进行单步调试找到程序中出现的逻辑问题。

6.2测试结果
测试结果如下:

7设计的特点、不足、收获与体会
7.1设计的特点
本次设计是采用递归下降的方法对输入的while--do 循环语句进行语法,语义分析,并输出四元式。因此程序中充分体现了递归下降的思想。

7.2设计的不足,收获与体会
本次的设计的不足主要是我没将程序一般化,实现不了用户自动输入代码进行词法分析的四元式输出,此程序只能实现对Wa<bDa=a+b#的分析与四元式输出,由于我所设计的栈中只能一个字符一个字符的存放,因此只能用D W分别表示do while;而且我对语法制导翻译这一块很不熟悉,因此我始终不能用程序实现语法制导翻译输出四元式,于是根据自己的理解,直接把四元式写了出来。
本次课程设计巩固了我所学习的关于递归下降法这一方面的知识,并且使我对WHILE—DO循环语句也有了更深刻的理解,提高了我的动手能力。

8 课程设计参考资料
1张幸儿 《编译原理》(第二版)清华大学出版社
2何炎祥 《编译原理》华中理工大学出版社
3陈火旺 《程序设计语言编译原理》(第3版)国防工业出版社

本科生课程设计成绩评定表
班级:软件0701姓名:周璐萍学号:0120710680129
序号 评分项目 满分 实得分
1 学习态度认真、遵守纪律 10
2 设计分析合理性 10
3 设计方案正确性、可行性、创造性 20
4 设计结果正确性 40
5 设计报告的规范性 10
6 设计验收 10
总得分/等级
评语:

注:最终成绩以五级分制记。优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下为不及格
源程序
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>

char a[50],g[50][50];
char ch;
int n1,i1=0,i2=0;
int total=0;

void S();
void D();
void G();
void W();
void E();
void R();
void T();
void F();

void main()
{
int j=0;

printf("文法G(s)为:\n");
printf("s-->DGWE\n");
printf("G-->c=R\n");
printf("R-->dTe|d\n");
printf("T-->+|-|*|/\n");
printf("E-->aFb\n");
printf("F--> >|==|<\n");

printf("请输入while-do语句(D代表do,W代表while),并以#结束:\n");
do{
scanf("%c",&ch);
a[j]=ch;
j++;
}while(ch!='#');
n1=j;
ch=a[0];

S();
printf("\n");

if (ch=='#')
{ printf("输出四元式为:\n");
printf("100 (<,a,b,102)\n");
printf("101 (j,_,_,105)\n");
printf("102 (+,a,b,n)\n");
printf("103 (=,n,_,a)\n");
printf("104 (j,_,_,100)\n");
printf("105 \n");

}

else {

printf("error\n");

printf("press any key to continue..\n");

getchar();getchar();

return;

}

printf("\n");

printf("press any key to continue..\n");

getchar();
getchar();
}

/*出错情况分析*/

void S()
{
printf("%d\tS-->WEDG\n",total);total++;
W();
E();
}

void W()
{

if(ch!='W')
{
printf("有非法字符%c请按回车返回!!",ch);
getchar();
getchar();
exit(1);
}
}

void E()
{
ch=a[++i1];
if(ch!='a')
{
printf("有非法字符%c %c请按回车返回!!",ch);
getchar();
getchar();
exit(1);
}
printf("%d\tE-->aFb\n",total);total++;
F();
}

void F()
{
int i;
ch=a[++i1];
i=i1+1;
if(a[i]!='b')
{
printf("有非法字符%c请按回车返回!!",a[i]);
getchar();
getchar();
exit(1);
}
switch(ch)
{
case '>':
printf("%d\tF-->>\n",total);total++;

break;
case '==':
printf("%d\tF-->==\n",total);total++;

break;
default:
printf("%d\tF--><\n",total);total++;

break;

}
D();
G();
}

void D()
{ ++i1;
ch=a[++i1];
if(ch!='D')
{ printf("有非法字符%c请按回车返回!!",ch);
getchar();
getchar();
exit(1);}
ch=a[++i1];

}

void G()
{ int i=i1+1;

if(ch!='c'&&a[i]!='=')
{ printf("有非法字符%c %c请按回车返回!!",ch,a[i]);
getchar();
getchar();
exit(1);}
printf("%d\tG-->c=R\n",total);total++;
R();
}

void R()
{
int i;
i=i1+1;
i1=i1+2;
ch=a[i1];
if(a[i]!='='&&ch!='d')
{
printf("有非法字符%c %c请按回车返回!!",a[i],ch);
getchar();
getchar();
exit(1);
}
else
{
if((a[i1+1]=='+')||(a[i1+1]=='-')||(a[i1+1]=='*')||(a[i1+1]=='/'))
{
printf("%d\tR-->dTe\n",total);total++;

T();

}
else
{
printf("%d\tR-->d\n",total);total++;

W();
E();
}
}

}

void T()
{
ch=a[++i1];
switch(ch)
{
case '+':
printf("%d\tT-->+\n",total);total++;

break;
case '-':
printf("%d\tT-->-\n",total);total++;

break;
case '*':
printf("%d\tT-->*\n",total);total++;

break;

default:
printf("%d\tT-->/\n",total);total++;

break;
}
ch='#';

}

指导教师签名:
2010 年月日

4. 编译原理

编译原理):利用编译程序从源语言编写的源程序产生目标程序的过程; 用编译程序产生目标程序的动作。 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。

编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成

(4)华农编译原理语义分析实验代码扩展阅读:

编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程序,按该语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程序是最终的一个语法单位。

编译程序的语法规则可用上下文无关文法来刻画。语法分析的方法分为两种:自上而下分析法和自下而上分析法。自上而下就是从文法的开始符号出发,向下推导,推出句子。

而自下而上分析法采用的是移进归约法,基本思想是:用一个寄存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分归约成该产生式的左邻符号。

5. 编译原理 什么是语义分析

在编译原理中,语法规则和词法规则不同之处在于:规则主要识别单词,而语法主要识别多个单词组成的句子。词法分析和词法分析程序:词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。语法分析(Syntax analysis或Parsing)和语法分析程序(Parser) 语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语义分析(Syntax analysis) 语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.

6. 编译原理简单吗

编译原理主要是讲了编译器的实现。
那什么是编译器呢?
编译器就是将 源程序→编译器 →目标机器代码的程序
本文将用一段最简单的代码进行说明

1 + 2 + 3

第一步. 词法分析
当代码从文件中被读入到编辑器时,将会进行词法分析
示例中的代码最终会转换为(下面为伪代码)

1 ADD 2 ADD 3

第二步. 语法分析
这一步编译器将会把词法分析的结果转换成AST(abstract syntax tree, 抽象语法树)
所有的操作数将会作为子节点,所有的操作符将会作为父节点。(不知道的同学可以看一下树的生成)

1 + 2 + 3 对应的树
3. 生成目标代码
对上面的树进行后序遍历,将会得到下面的伪代码

((1 2 +) 3 +)

生成的汇编伪代码为

START:

MOV VALUE, 0//初始化结果为0

ADD VALUE, 1

ADD VALUE, 2//(1 2 +)的汇编伪代码

ADD VALUE, 3

RET VALUE

END

最终汇编代码会被编译成机器代码,在计算机上执行。
下面为一般情况下的编译流程
1. 词法分析(生成代码对应的token序列,使用正则表达式)
2. 语法分析(生成AST)
3. 语义分析(对代码的语法进行检查)
4. 代码生成(生成可执行的代码)

7. 编译详细资料大全

编译(compilation , compile) 1、利用编译程式从源语言编写的源程式产生目标程式的过程。 2、用编译程式产生目标程式的动作。 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程式把人们熟悉兆猜吵的语言换成2进制的。 编译程式把一个兆晌源程式翻译成目标程式的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成;代码最佳化;目标代码生成。主要是进行词法分析和语法分析,又称为源程式分析,分析过程中发现有语法错误,给出提示信息。

编译语言是一种以编译器来实现的程式语言。它不像直译语言一样,由解释器将代码一句一句运行,而是以编译器,先将代码编译为机器码,再加以运行。理论上,任何程式语言都可以是编译式,或直译式的。它们之间的区别,仅与程式的套用有关。

基本介绍

编译程式,词法分析,语法分析,中间代码,代码最佳化,目标代码,表格管理,出错处理,

编译程式

将某一种程式设计语言写的程式翻译成等价的另一种语言的程式的程式, 称之为编译程式(compiler) .

词法分析

词法分析的任务是对由字符组成的单词进行处理,从左至右逐个字符地对源程式进行扫描,产生一个个的单词符号,把作为字符串的源程式改造成为单词符号串的中间程式。执行词法分析的程式称为词法分析程式或扫描器。 源程式中的单词符号经扫描器分析,一般产生二元式:单词种别;单词自身的值。单词种别通常用整数编码,如果一个种别只含一个单词符号,那么对这个单词符号,种别编码就完全代表它自身的值了。若一个种别含有许多个单词符号,那么,对于它的每个单词符号族侍,除了给出种别编码以外,还应给出自身的值。 词法分析器一般来说有两种方法构造:手工构造和自动生成。手工构造可使用状态图进行工作,自动生成使用确定的有限自动机来实现。

语法分析

编译程式的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程式,按该语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程式是最终的一个语法单位。编译程式的语法规则可用上下文无关文法来刻画。 语法分析的方法分为两种:自上而下分析法和自下而上分析法。自上而下就是从文法的开始符号出发,向下推导,推出句子。而自下而上分析法采用的是移进归约法,基本思想是:用一个暂存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分归约成该产生式的左邻符号。

中间代码

中间代码是源程式的一种内部表示,或称中间语言。中间代码的作用是可使编译程式的结构在逻辑上更为简单明确,特别是可使目标代码的最佳化比较容易实现中间代码,即为中间语言程式,中间语言的复杂性介于源程式语言和机器语言之间。中间语言有多种形式,常见的有逆波兰记号、四元式、三元式和树。

代码最佳化

代码最佳化是指对程式进行多种等价变换,使得从变换后的程式出发,能生成更有效的目标代码。所谓等价,是指不改变程式的运行结果。所谓有效,主要指目标代码运行时间较短,以及占用的存储空间较小。这种变换称为最佳化。 有两类最佳化:一类是对语法分析后的中间代码进行最佳化,它不依赖于具体的计算机;另一类是在生成目标代码时进行的,它在很大程度上依赖于具体的计算机。对于前一类最佳化,根据它所涉及的程式范围可分为局部最佳化、循环最佳化和全局最佳化三个不同的级别。

目标代码

目标代码生成是编译的最后一个阶段。目标代码生成器把语法分析后或最佳化后的中间代码变换成目标代码。目标代码有三种形式: ① 可以立即执行的机器语言代码,所有地址都重定位; ② 待装配的机器语言模组,当需要执行时,由连线装入程式把它们和某些运行程式连线起来,转换成能执行的机器语言代码; ③ 汇编语言代码,须经过汇编程式汇编后,成为可执行的机器语言代码。 目标代码生成阶段应考虑直接影响到目标代码速度的三个问题:一是如何生成较短的目标代码;二是如何充分利用计算机中的暂存器,减少目标代码访问存储单元的次数;三是如何充分利用计算机指令系统的特点,以提高目标代码的质量。

表格管理

编译过程中源程式的各种信息被保留在种种不同的表格,编译各阶段的工作都涉及到构造、查找、或更新有关的表格。 编译程式的公共辅助部分。对源程式中的各种量进行管理,登记在相应的表格。编译程式处理时通过查表得到所需的信息。

出错处理

如果编译过程中发现源程式有错误,编译程式应报告错误的性质和错误的发生的地点,并且将错误所造成的影响限制在尽可能小的范围内,使得源程式的其余部分能继续被编译下去,有些编译程式还能自动纠正错误,这些工作由错误处理程式完成。 需要注意的是,一般上编译器只做语法检查和最简单的语义检查,而不检查程式的逻辑。

阅读全文

与华农编译原理语义分析实验代码相关的资料

热点内容
画世界的app叫什么 浏览:824
vc6编译时显示无法执行 浏览:547
java动态初始化数组 浏览:638
概率论与数理统计答案pdf 浏览:681
得物app上面的鞋为什么这么贵 浏览:909
如何从爱思服务器注销游戏账号 浏览:944
幼儿编程教育培训多少钱 浏览:406
经常生气有什么东西能解压 浏览:903
代理服务器地址和端口可以怎么填 浏览:65
unity5手游编译模型 浏览:268
安卓无人机app源码 浏览:811
pl1编程语言 浏览:801
台达plc编程换算指令大全 浏览:176
手机上的编程游戏 浏览:110
服务器密码机有什么用 浏览:479
dos磁盘命令 浏览:957
单片机cpu52的功能 浏览:693
opc服务器怎么开发 浏览:375
觅喜是个什么app 浏览:405
加密cd机 浏览:948