编译技术课程设计
级 软件一班 班
学 号 2008008000XX 姓 名 软件一班万岁 指导老师 贺老师
二零一一年 三 月
一、目的
<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二
年级
六年级体育公开课教案九年级家长会课件PPT下载六年级家长会PPT课件一年级上册汉语拼音练习题六年级上册道德与法治课件
所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求
基本要求:
1(词法分析器 产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:
单词符号 种别编码 助记符 内码值 DIM 1 $DIM - IF 2 $IF - DO 3 $DO - STOP 4 $STOP - END 5 $END - 标识符 6 $ID - 常数(整) 7 $INT 内部字符串 = 8 $ASSIGN
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
二进形式 + 9 $PLUS - * 10 $STAR - ** 11 $POWER - , 12 $COMMA - ( 13 $LPAR - ) 14 $RPAR -
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如IF)WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的:
IF(5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为
IF i>0 i= 1;
而绝对不要写成
IFi>0 i=1; 因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:
2(语法分析器 能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的
算术表达式,其文法如下:
E?E+T|E-T|T
T?T*F|T/F|F
F?P^F|P
p?(E)|i
使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;
LR分析法等。
3(中间代码生成器 产生上述算术表达式的中间代码(四元式序列)
三、实现过程说明
给出各题目的详细算法描述,数据结构和函数说明,流程图。
1、词法分析器的流程图
开始
输入源文件路径
否
路径是否有效
是
打开源文件
初始化文件指针
识别指针内容
文件结束,是结束
否
是空格,空白或换将字符加入字符数否是字母吗否是数字吗否是界符吗否行吗组Word[]
是是是将字符加将字符加入字符数将字符入字符数组Word[]将字符跳过该字符加入字组Word[]加入字符数组符数组Word[]Word[]是指向下一字符指向下一字符指向下一字符是输出Word是字母惑数字输出word识别指针内容内容为不吗为界符可识别
否回退是数字吗将word与关键字表key进行匹配否
输出word为输出word否匹配,指向下一字符普通标示符为常数
是
输出word为关键字
2、语法分析器主程序图
3、中间代码生成器流程图:
四、源程序清单
词法分析器
#include "stdafx.h" #include "Word.h"
//构造函数,对数据成员初始化,并将关键字以及运算符读入
Word::Word()
{//打开关键字文件
fstream keywordfile("keyword.txt");
if(!keywordfile)
{
cout<<"error ! can't open keywordfile!"<
>tempword>>tempencode>>tempre>>tempvalue;
keywordlist.push_back(tempword);
keywordencode.push_back(tempencode);
keywordre.push_back(tempre);
keywordcodevalue.push_back(tempvalue);
}
//关闭关键字文件
keywordfile.close();
for(int i=0;i>tempword>>tempencode>>tempre>>tempvalue;
signlist.push_back(tempword);
signencode.push_back(tempencode);
signre.push_back(tempre);
signcodevalue.push_back(tempvalue);
}
//关闭符号文件
signwordfile.close();
for(int i=0;i='a' )
return true;
else if(s<='Z' && s>='A')
return true;
else
return false;
}
bool Word::digit()
{ if(s<='9' && s>='0')
return true;
return false;
}
//按token数组中的字符串中的前五项(即判别其是否为保留字),若是保留字则返回它的编
码
int Word::reserve()
{
int leng;//记录token数组中单词的长度
for(int i=0;i<100;i++)//计算token数组中单词的长度
{
if(token[i]==NULL)
{
leng=i;
break;
}
}
for(int i=0;i>tempre;
chartostring.close();
indentityre.push_back(tempre);
tempword="标识符";
tempencode=6;
tempvalue=indentityre.size();
indentitylist.push_back(tempword);
indentityencode.push_back(tempencode);
indentitycodevalue.push_back(tempvalue);
fstream indentityfile("indentityword.txt");
if(!indentityfile)
{ cout<<"Error! Can't open indentityword file"<>tempconstre;
chartoint.close();
constlist.push_back(tempword);
tempword="常数";
tempencode=7;
tempvalue=indentityre.size();
constencode.push_back(tempencode);
constre.push_back(tempconstre);
constvalue.push_back(tempvalue);
fstream constdigit("constdigit.txt");
if(!constdigit)
{
cout<<"Error! Can't open constdigit file!"<>s;
while(s==' ')
{
file>>s;
}
switch(s)
{
case 'a'; case 'b': case 'c': case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
while(letter()||digit())
{
concatentation();//将当前读入的字符送入token数组
file>>s;//继续读字符,直到字符不为数字或字母为止
}
//扫描指针回退一个字符
file.seekg(-1,ios::cur);
code=reserve();
if(!code)
{ buildlist();}
else
{
cout<>s;//继续读字符,直到字符不为数字为止
}
//扫描指针回退一个字符
file.seekg(-1,ios::cur);
buildlist();
break;
case '+':
concatentation();
signinfor();
break;
case '-':
concatentation();
signinfor();
break;
case '*':
concatentation();
signinfor();
break;
case '<':
concatentation();
file>>s;
if(s!='=')
{//扫描指针回退一个字符
file.seekg(-1,ios::cur);
signinfor();
}
else
{
concatentation();
signinfor();
}
break;
case '=':
concatentation();
file>>s;
if(s!='=')
{
//扫描指针回退一个字符
file.seekg(-1,ios::cur);
signinfor();
}
else
{
concatentation();
signinfor();
}
break;
case ';':
concatentation();
signinfor();
break;
case '#':
cout<
#include #include typedef struct {
char R;
char r;
int flag;
}array;
typedef struct {
char E;
char e;
}charLode;
typedef struct {
charLode *base;
int top;
}charstack;
char str[80][80],arr[80][80],brr[80][80];
array F[20];
int m,kk,p,ppp,FF=1; char r[10];
int crr[20][20],FLAG=0; char ccrr1[1][20],ccrr2[20][1];
void Initstack(charstack &s)//定义栈
{
s.base=new charLode[20];
s.top=-1;
}
void push(charstack &s,charLode w)
{
s.top++;
s.base[s.top].E=w.E;
s.base[s.top].e=w.e; }
void pop(charstack &s,charLode &w)
{
w.E=s.base[s.top].E;
w.e=s.base[s.top].e;
s.top--;
}
int IsEmpty(charstack s) {
if(s.top==-1)
return 1;
else return 0;
}
int IsLetter(char ch) {
if(ch>='A'&&ch<='Z')
return 1;
else return 0;
}
//judge1是判断是否是算符文法:若产生式中含有两个相继的非终结符则不是
算符文法
int judge1(int n)
{
int j=3,flag=0;
for(int i=0;i<=n;i++)
while(str[i][j]!='\0')
{
char a=str[i][j];
char b=str[i][j+1];
if(IsLetter(a)&&IsLetter(b))
{flag=1;break;}
else j++;
}
if(flag==1)
return 0;
else
return 1;
}
//judge2是判断文法G是否为算符优先文法:若不是算符文法或若文法中含空字或终结符的优先级不唯一则不是算符优先文法
void judge2(int n)
{
for(int i=0;i<=n;i++)
if(str[i][3]=='~'||judge1(n)==0||FLAG==1)//'~'代表空字
{cout<<"文法G不是算符优先文法!"<n)
cout<<"文法G是算符优先文法!"<
步骤
新产品开发流程的步骤课题研究的五个步骤成本核算步骤微型课题研究步骤数控铣床操作步骤
"<<" "<<"符号栈"<<" "<<"输入串"<<" "<<"动作"<>n;
for(i=0;i';
str[i][3]='#';
str[i][4]=str[0][0];
str[i][5]='#';
str[i][6]='\0';
cout<<"你定义的产生式如下:"<";
cout<<" ";
}
cout<
#include #include #include #include #define STACK_INIT_SIZE 50
#define STACKINCREMENT 5
#define ERROR 0 #define OVERFLOW -2 #define TRUE 1 #define FALSE 0 #define OK 1 #define NULL 0 void sub_E();
void sub_F();
void sub_T();
void sub_G();
void GEQ(char m);
void PRINT();
typedef struct Stack {
char *base;
char *top;
int stacksize;
}Stack;
int num=0;
char QT[10][4],T='A',c; struct Stack SEM;
struct initStack(Stack s) {
s.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE; return OK;
}
//初始化堆栈
char pop(Stack &s)
{
char e;
if(s.top==s.base)
{printf("栈中已无元素!");
exit(ERROR);
}
e=*--s.top;
return e;
}
//出栈
struct push(Stack &s,char e) {
if(s.top-s.base>=s.stacksize) {
s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT; }
*s.top++=e;
return OK;
}
//入栈
void main()
{
initStack(SEM);
printf("----表达式应由小写字母、运算符及小括号组成,并以\"#\"结束----\n");
printf("请输入表达式:");
c=getchar();
sub_E();
if(c=='#')
PRINT(); else
{
printf("无结束符或漏写运算符!");
exit(0); }
getchar();
}
void sub_E() {
sub_T();
R1: if(c=='+') {
c=getchar();
sub_T();
GEQ('+');
goto R1; }
else if(c=='-') {
c=getchar();
sub_T();
GEQ('-');
goto R1; }
else ;
}
void sub_T() {
sub_G();
R4: if(c=='*')
{
c=getchar();
sub_F();
GEQ('*');
goto R4; }
else if(c=='/') {
c=getchar();
sub_F();
GEQ('/');
goto R4;
}
}
void sub_F()
{
sub_G();
R5: if(c=='^')
{
c=getchar();
sub_G();
GEQ('^');
goto R5;
}
}
void sub_G()
{
if(c>='a'&&c<='z') {
push(SEM,c);
c=getchar(); }
else if(c=='(') {
c=getchar();
sub_E();
if(c==')')
c=getchar();
else
{
printf("括号不匹配!");
exit(0);
}
}
else
{
printf("非法符号!");
exit(0);
}
}
void GEQ(char m) {
QT[num][0]=m;
QT[num][2]=pop(SEM);
QT[num][1]=pop(SEM);
QT[num][3]=T;
push(SEM,T);
num++;
T++;
}
void PRINT()
{
printf("您输入的表达式所对应的四元式为:\n");
for(int i=0;i='A')
printf("\t%c%d",'t',QT[i][1]-'A'+1);
else
printf("\t%c",QT[i][1]);
if(QT[i][2]<='Z'&&QT[i][1]>='A')
printf("\t%c%d",'t',QT[i][2]-'A'+1);
else
printf("\t%c",QT[i][2]);
if(QT[i][3]<='Z'&&QT[i][1]>='A')
printf("\t%c%d",'t',QT[i][3]-'A'+1);
else
printf("\t%c",QT[i][3]);
printf(")\n");
}
}
六、
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
谈谈自己的收获与体会。
1、 通过这次实验,我对词法分析器有了进一步的了解,把理论知识应用于实验
中。也让我重新熟悉了C语言的相关内容,加深了对C语言知识的深化和用
途的理解。通过这次语义分析的实验, 我对高级语言的学习有了更深的认
识 ,了解得更透彻。
2、 我了解了高级语言转化为目标代码或汇编指令的过程,。对今后的学习将起很
大的作用,对以后的编程有很大的帮助. 本次实验虽然只是完成了一个简单的
程序,并且程序的主要框架课本上有给出,但在组织程序结构和深入了确上
学到了很多,加深对编译原理的理解,掌握编译程序的实现方法和技术。巩固
了前面所学的知识。