语法制导翻译

语法制导翻译
语法制导翻译

for循环语句翻译递归下降法输出三地址码/////////////

#define MAX 100

#include

#include

#include

char str[MAX];

char ch;

int turn;

char strToken[MAX];

int kind;

int n=0;//存放strtoken[]元素的个数

struct Word//结构体存放单词

{

int sort;

char word[MAX];//存放strtoken[]的内容

};

//record[x]=new Word;

Word *record[12];//放所有识别出来的单词,分别存放他们的编号以及字符串,x是其下标

////////////////////词法分析///////////////////////

int buffer()//载入

{

int i=0;

cout<<"输入程序,以“#”作为结束标志。"<

for(int n=0;n<=MAX;n++)

{

for(;i<=MAX;i++)

{

scanf("%c",&str[i]);

/////////////cin>>str[i]不可用,用C语言读入字符。

if(str[i]=='#')

break;///////如果尾数为识别码#,则表示程序读完,跳出循环.

}

break;

}

return(i);

bool IsLetter(char ch)///////////判断是否是字母

{

if(ch>=65&&ch<=90||ch>=97&&ch<=122)

return(true);

else

return(false);

}

bool IsDigit(char ch)//////////判断是否是数字

{

if(ch>=48&&ch<=57)

return(true);

else

return(false);

}

char GetChar(int i)///////读取字符

{

char ch;

ch=str[i];

return(ch);

}

char GetBC(char ch)////判断是不是空格或者换行,如果是,直接读取下一个字符直道不再空白为止{

if(ch==32||ch==10)

{

turn++;

ch=GetChar(turn);

ch=GetBC(ch);/////////递归实现

return(ch);

}

else

return(ch);

}

void Concat()/////////////连接,即为strtoken[]赋值

{

strToken[n]=ch;

n++;

int Reserve()/////以单词为单位查找保留字,是则返回编码,不是则返回0,用来区分标志符和保留字{

if(strcmp(strToken," DIM\0")==0)///////调用strcmp函数实现,

return(1);

else if(strcmp(strToken,"for\0")==0)

return(2);

else if(strcmp(strToken,"step\0")==0)

return(3);

else if(strcmp(strToken,"until\0")==0)

return(4);

else if(strcmp(strToken,"do\0")==0)

return(5);

else

return(6);

}

void clear()

{

n=0;

}

/////////////*语法递归分析*/////////////////

int A(int * c,int & q)

{

if(c[q++]==3)

{

if(c[q]==7)

{ q++;

return 1;

}

else {cout<<"step右部出错"<

}else {cout<<"error 'step'"<

}

int B(int * b,int & o)

if(b[o++]==4)

{

if(b[o]==7)

{ o++;

return 1;

}

else {cout<<"until右部出错"<

}else {cout<<"error 'until'"<

}

int S2(int * d,int & h)

{

if(d[h++]==6)

{

if(d[h++]==8)

{

if((d[h]==6||d[h]==7)) {h++; return 1;}

else {cout<<"赋值语句右部出错"<

}else {cout<<"赋值语句缺少赋值运算符"<

}

int S1(int * m,int & n)

{

if(S2(m,n))

{

if(A(m,n))

{

if(B(m,n)) return 1;

else return 0;

}else return 0;

}else return 0;

}

int S(int *a,int & z)

{

if (a[z++]==2)

{

if (S1(a,z))

{

if(a[z++]==5)

{

{

cout<<"succeed!"<

}else return 0;

}else {cout<<"error 'do'"<

}else return 0;

}else {cout<<"error 'for'"<

}

void main()

{

cout<<"*************产生式***************"<

cout<<" S ->for S1 do S2"<

cout<<" S1 ->S2AB"<

cout<<" S2 ->i=j"<

cout<<" A ->stepj"<

cout<<" B ->untilj"<

int num;

turn=0;

num=buffer()-1;

int x=0;//计识别的单词的个数

for(;turn<=num;turn++)//总循环,ch存放刚读入的字符,strtoken[]存放已识别的标志付或保留字,turn是数组str[]的下标

{

ch=GetChar(turn);

ch=GetBC(ch);

if(IsLetter(ch))

{

while(IsLetter(ch)&&turn<=num||IsDigit(ch)&&turn<=num)

{

Concat();

ch=GetChar(++turn);

}

strToken[n]='\0';

ch=NULL;//此ch不是标志符中的符号

kind=Reserve();

record[x]=new Word; record[x]->sort=kind;//12345或6 //cout<

cout<<"(";

for(int i=0;i

{

record[x]->word[i]=strToken[i];

cout<word[i];//输出识别的标志符或保留字}

cout<<","<

record[x]->word[i]='\0';

clear();

x++;

}

else if(IsDigit(ch))

{

while(IsDigit(ch)&&turn<=num)

{

Concat();

ch=GetChar(++turn);

}

ch=NULL;

turn=turn-1;

kind=7;

//////////////

record[x]=new Word;

record[x]->sort=kind;

////////////////

cout<<"(";

for(int i=0;i

{

record[x]->word[i]=strToken[i];

cout<word[i];

}

cout<<","<

record[x]->word[i]='\0';

clear();x++;

}

else if(ch=='=')

{

kind=8;

///////

record[x]=new Word;

record[x]->word[0]='=';

record[x++]->sort=kind;

cout<<"(=,"<

}

else

cout<<"error input!"<

}

//////////////////////*语法分析*////////////////

//int y;

/*for(y=0;y

{cout<sort<<" ";//打印单词的编号。

}cout<

int ana[MAX];//存放词法分析得到的单词序列的编号的序列int m;

for(m=0;m

{

ana[m]=record[m]->sort;//将sort作为数组保存起来

}

/////////语法分析///////

int j=0;

///////////////////制导翻译//////////////////

if(!S(ana,j)) cout<<"语法出错!"<

else

{ cout<<"三地址码如下:"<

cout<<"100 ";

int i=0;

while(record[1]->word[i]!='\0')

cout<word[i++];cout<word[0]; i=0;

while(record[3]->word[i]!='\0')

cout<word[i++];cout<

cout<<"101 goto 103"<

cout<<"102 ";

i=0;

while(record[1]->word[i]!='\0')

cout<word[i++];cout<<":=";

i=0;

while(record[1]->word[i]!='\0')

cout<word[i++];cout<<"+";

i=0;

while(record[5]->word[i]!='\0')

cout<word[i++];cout<

cout<<"103 if ";

i=0;

while(record[1]->word[i]!='\0')

cout<word[i++];cout<<"<";

i=0;

while(record[7]->word[i]!='\0')

cout<word[i++];

cout<<" goto 105"<

cout<<"104 goto 107"<

cout<<"105 ";

i=0;

while(record[9]->word[i]!='\0')

cout<word[i++];cout<<":=";

i=0;

while(record[11]->word[i]!='\0')

cout<word[i++];cout<

cout<<"106 goto 102"<

cout<<"107 end"<

}

}

语法制导翻译

for循环语句翻译递归下降法输出三地址码///////////// #define MAX 100 #include #include #include char str[MAX]; char ch; int turn; char strToken[MAX]; int kind; int n=0;//存放strtoken[]元素的个数 struct Word//结构体存放单词 { int sort; char word[MAX];//存放strtoken[]的内容 }; //record[x]=new Word; Word *record[12];//放所有识别出来的单词,分别存放他们的编号以及字符串,x是其下标 ////////////////////词法分析/////////////////////// int buffer()//载入 { int i=0; cout<<"输入程序,以“#”作为结束标志。"<>str[i]不可用,用C语言读入字符。 if(str[i]=='#') break;///////如果尾数为识别码#,则表示程序读完,跳出循环. } break; } return(i);

bool IsLetter(char ch)///////////判断是否是字母 { if(ch>=65&&ch<=90||ch>=97&&ch<=122) return(true); else return(false); } bool IsDigit(char ch)//////////判断是否是数字 { if(ch>=48&&ch<=57) return(true); else return(false); } char GetChar(int i)///////读取字符 { char ch; ch=str[i]; return(ch); } char GetBC(char ch)////判断是不是空格或者换行,如果是,直接读取下一个字符直道不再空白为止{ if(ch==32||ch==10) { turn++; ch=GetChar(turn); ch=GetBC(ch);/////////递归实现 return(ch); } else return(ch); } void Concat()/////////////连接,即为strtoken[]赋值 { strToken[n]=ch; n++;

语法制导翻译与生成中间代码附代码

《编译系统设计实践》 实验项目三:语法制导翻译与生成中间代码 学号: 姓名: 年级: 学院: 数计学院 专业: 计算机 本组其它成员:学号姓名 学号姓名 实验时间:2016-2017学年第一学期 任课教师: 一、实验目的 通过语法制导或翻译模式生成中间代码。 二、实验内容 在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出,若有错误将错误信息输出。 三、设计思路 1.分析过程

主函数,读取文件,存入字符串数组,调用语义分析,判断关键字,调用相应的语义规则(这里只有if与while与赋值语句),赋值语句调用表达式处理,if语句调用条件表达式处理,while也就是调用表达式处理,然后就是一个递归过程,不断的递归调用,按序输出三地址语句。在本例程序中选用expr及num作为运算数。 2.主要函数 string link() //字符串与数字的连接 string element() //获取表达式中的元素对象 string expression() //处理表达式 string expression_1() //处理表达式 string biaodashi() //处理表达式,转为三地址输出 string biaodashi_1() //递归---处理表达式,转为三地址输出 string getOperator() //判断并获取运算符 void condition(int L1,int L2) //输出if语句的条件的三地址代码 void yuyifenxi_list() //生成并输出条件返回地址 void yuyifenxi_list_1() //递归---生成并输出条件返回地址 void yuyifenxi(int next,int &flag) //判断关键字,调用相应的产生式分析 void readfile() //文件读入 四、测试报告 1.第一组测试: 图1-1 输入待翻译代码

语法制导翻译与生成中间代码

《编译系统设计实践》 实验项目三:语法制导翻译与生成中间代码 学号: 姓名: 年级: 学院:数计学院 专业:计算机 本组其它成员:学号姓名 学号姓名 实验时间:2016-2017学年第一学期 任课教师:

一、实验目的 通过语法制导或翻译模式生成中间代码。 二、实验内容 在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出,若有错误将错误信息输出。 三、设计思路 1.分析过程 主函数,读取文件,存入字符串数组,调用语义分析,判断关键字,调用相应的语义规则(这里只有if和while和赋值语句),赋值语句调用表达式处理,if语句调用条件表达式处理,while也是调用表达式处理,然后是一个递归过程,不断的递归调用,按序输出三地址语句。在本例程序中选用expr及num作为运算数。 2.主要函数 string link()//字符串和数字的连接 string element() //获取表达式中的元素对象 string expression()//处理表达式 string expression_1()//处理表达式 string biaodashi() //处理表达式,转为三地址输出 string biaodashi_1()//递归---处理表达式,转为三地址输出 string getOperator()//判断并获取运算符 void condition(int L1,int L2) //输出if语句的条件的三地址代码 void yuyifenxi_list() //生成并输出条件返回地址 void yuyifenxi_list_1() //递归---生成并输出条件返回地址 void yuyifenxi(int next,int &flag) //判断关键字,调用相应的产生式分析 void readfile()//文件读入 四、测试报告

相关文档
最新文档