目录
实验题目
小型(简化)高级语言分析器前端
实验内容
设计并实现一个一遍扫描的编译前端,将简化高级语言的部分语法成分(含赋值语句、分支语句、循环语句等)翻译成四元式(或三地址代码),还要求有合理的语法出错报错和错误恢复功能。
待分析的简单语言的词法
- 关键字:main,if,while所有的关键字都是小写
- 运算符和界符: = + - * / < <= > >= == != ; ( ) { }
- 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:ID = letter(letter|digit)* NUM = digit digit*
- 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
各种单词符号的种别码
单词符号 | 种别码 |
main | 1 |
if | 2 |
while | 3 |
letter(letter|digit)* | 10 |
digit digit* | 20 |
= | 21 |
+ | 22 |
- | 23 |
* | 24 |
/ | 25 |
( | 26 |
) | 27 |
{ | 28 |
} | 29 |
; | 30 |
> | 31 |
< | 32 |
>= | 33 |
<= | 34 |
== | 35 |
!= | 36 |
‘\0’ | 1000 |
ERROR | -1 |
语法结构定义
<程序> ::= main()’{’<语句串>’}’
<语句串> ::= <语句>{;<语句>};
<语句> ::= <赋值语句> | <条件语句> | <循环语句>
<赋值语句> ::= ID=<表达式>
<条件语句> ::= if<条件><赋值语句>
<循环语句> ::= while<条件><赋值语句>
<条件> ::= <表达式><关系运算符><表达式>
<表达式> ::= <项>{+<项>|-<项>}
<项> ::= <因子>{*<因子>|/<因子>}
<因子> ::= ID | NUM | (<表达式>)
<关系运算符>::= > | < | >= | <= | == | !=
程序的输入与输出
输入:在命令提示符中输入所给文法的源程序字符串,以#为结束符。
输出:四元式序列
例如:
测试用例
main(){ /* 注释ouyonghao */
if A1f>=B20
A1f=314*B20+(C123-Dzx)/Ee;
B20:=ff21;
while A1f != B20
A1f=314*B20+(C123-Dzx)/Ee;
B20=ff21;
}#
测试结果
源代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef struct
{
int typenum;
char *word;
} WORD;
typedef struct
{
char result[20];
char number_left[20];
char op[20];
char number_right[20];
int statement_number;
} QUATERNION;
char m_getch();
void getbc();
void concat();
int letter();
int digit();
int reserve();
WORD *scanner();
char *newtemp();
void program(WORD *word);//程序
WORD *statement_string(WORD *word);//语句串
WORD *statement(WORD *word);//语句
WORD *assignment_statement(WORD *word);//赋值语句
WORD *conditional_statement(WORD *word);//条件语句
WORD *loop_statement(WORD *word);//循环语句
WORD *condition(WORD *word,char *buffer);//条件
WORD *expression(WORD *word,char *buffer);//表达式
WORD *term(WORD *word,char *buffer);//项
WORD *factor(WORD *word,char *buffer);//因子
WORD *relational_operators(WORD *word,char *buffer);//关系运算符
void set_quaternion(char *result,char *number_left,char *op,char *number_right,int flag);//构建四元式
void get_quaternion();//输出四元式
char input[255];
char token[255]="";
int p_input;
int p_token;
char ch;
int temp_number=0;
int line=1;
int quaternion_number=0;
QUATERNION my_quaternion[100];
char *reserved_word[]= {"main","if","while","ERROR"};
int main()
{
scanf("%[^#]",input);
p_input=0;
WORD *oneword;
oneword=scanner();
program(oneword);
get_quaternion();
return 0;
}
void filter()
{
int start=p_input-1;
if(ch=='/')
{
m_getch();
if(ch=='/')
{
m_getch();
while(ch!='\0'&&ch!='\n')
m_getch();
getbc();
}
else if(ch=='*')
{
m_getch();
int flag=0;
while(ch!='\0')
{
if(ch=='*')
{
m_getch();
if(ch=='/')
{
m_getch();
getbc();
flag=1;
break;
}
}
else m_getch();
}
if(flag!=1)
{
p_input=start+1;
ch=m_getch();
return;
}
}
else p_input--;
}
}
char m_getch()
{
ch=input[p_input];
p_input++;
return(ch);
}
void getbc()
{
while(ch==' '||ch==10)
{
if(ch=='\n')
line++;
ch=input[p_input];
p_input++;
}
}
void concat()
{
token[p_token]=ch;
p_token++;
token[p_token]='\0';
}
int letter()
{
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return 1;
else return 0;
}
int digit()
{
if(ch>='0'&&ch<='9')
return 1;
else return 0;
}
int reserve()
{
int number=0;
while(strcmp(reserved_word[number],"ERROR"))
{
if(!strcmp(reserved_word[number],token))
return number+1;
number++;
}
return 10;
}
WORD *scanner()
{
WORD *myword=(WORD *)malloc(sizeof(WORD));
myword->typenum=10;
myword->word="";
p_token=0;
m_getch();
getbc();
while(ch=='/'&&(input[p_input]=='/'||input[p_input]=='*'))
filter();
if(letter())
{
while(letter()||digit())
{
concat();
m_getch();
}
p_input--;
myword->typenum=reserve();
myword->word=token;
return myword;
}
else if(digit())
{
while(digit())
{
concat();
m_getch();
}
p_input--;
myword->typenum=20;
myword->word=token;
return myword;
}
else
{
switch(ch)
{
case'=':
m_getch();
if(ch=='=')
{
myword->typenum=35;
myword->word="==";
return myword;
}
p_input--;
myword->typenum=21;
myword->word="=";
return myword;
break;
case'+':
myword->typenum=22;
myword->word="+";
return myword;
break;
case'-':
myword->typenum=23;
myword->word="-";
return myword;
break;
case'*':
myword->typenum=24;
myword->word="*";
return myword;
break;
case'/':
myword->typenum=25;
myword->word ="/";
return myword;
break;
case'(':
myword->typenum=26;
myword->word="(";
return myword;
break;
case')':
myword->typenum=27;
myword->word=")";
return myword;
break;
case'{':
myword->typenum=28;
myword->word="{";
return myword;
break;
case'}':
myword->typenum=29;
myword->word="}";
return myword;
break;
case';':
myword->typenum=30;
myword->word=";";
return myword;
break;
case'>':
m_getch();
if(ch=='=')
{
myword->typenum=33;
myword->word=">=";
return myword;
}
p_input--;
myword->typenum=31;
myword->word=">";
return myword;
break;
case'<':
m_getch();
if(ch=='=')
{
myword->typenum=34;
myword->word="<=";
return myword;
}
p_input--;
myword->typenum=32;
myword->word="<";
return myword;
break;
case'!':
m_getch();
if(ch=='=')
{
myword->typenum=36;
myword->word="!=";
return myword;
}
p_input--;
myword->typenum=-1;
myword->word="ERROR";
return myword;
break;
case'\0':
myword->typenum = 1000;
myword->word = "OVER";
return myword;
break;
default:
myword->typenum=0;
myword->word="#";
return myword;
}
}
}
char *newtemp()
{
char *temp;
char number[20];
temp = (char *)malloc(20);
temp_number++;
sprintf(number,"%d",temp_number);
strcpy(temp+1,number);
temp[0] = 't';
return temp;
}
void program(WORD *word)//程序
{
if(word==NULL)return;
WORD *temp_word;
if(word->typenum!=1)
cout<<"第"<<line<<"行,main错误"<<endl;
temp_word=scanner();
if(temp_word==NULL)return;
if(temp_word->typenum!=26)
cout<<"第"<<line<<"行,(错误"<<endl;
temp_word=scanner();
if(temp_word==NULL)return;
if(temp_word->typenum!=27)
cout<<"第"<<line<<"行,)错误"<<endl;
temp_word=scanner();
if(temp_word==NULL)return;
if(temp_word->typenum!=28)
cout<<"第"<<line<<"行,{错误"<<endl;
temp_word=scanner();
temp_word=statement_string(temp_word);
if(temp_word==NULL)return;
if(temp_word->typenum!=29)
cout<<"第"<<line<<"行,}错误"<<endl;
return;
}
WORD *statement_string(WORD *word)//语句串
{
if(word==NULL)return NULL;
WORD *temp_word;
temp_word=statement(word);
if(temp_word==NULL)return NULL;
while(temp_word->typenum==30)
{
temp_word=scanner();
temp_word=statement(temp_word);
if(temp_word==NULL)return NULL;
}
return temp_word;
}
WORD *statement(WORD *word)//语句
{
if(word==NULL)return NULL;
WORD *temp_word;
if(word->typenum==10)temp_word=assignment_statement(word);
else if(word->typenum==2)temp_word=conditional_statement(word);
else if(word->typenum==3)temp_word=loop_statement(word);
return temp_word;
}
WORD *assignment_statement(WORD *word)//赋值语句
{
if(word == NULL)return NULL;
char result[20],number_left[20],buffer[255];
WORD *temp_word;
if(word->typenum==10)
{
strcpy(result,word->word);
temp_word = scanner();
if(temp_word->typenum==21)
{
temp_word = scanner();
temp_word = expression(temp_word,buffer);
if(temp_word == NULL)return NULL;
strcpy(number_left,buffer);
set_quaternion(result,number_left,"#","#",0);
return temp_word;
}
}
cout<<"第"<<line<<"行,表达式错误"<<endl;
WORD *theword = scanner();
while(theword->typenum!=30)theword=scanner();
return theword;
}
WORD *conditional_statement(WORD *word)//条件语句
{
if(word == NULL)return NULL;
WORD *temp_word;
if(word->typenum==2)
{
char goto_place_1[20],goto_place_2[20],buffer[255];
int temp=quaternion_number+2;
sprintf(goto_place_1,"%d",temp+1);
set_quaternion("if","#","goto",goto_place_1,0);
set_quaternion("goto","#","#","#",0);
temp_word=scanner();
temp_word=condition(temp_word,buffer);
strcpy(my_quaternion[temp-2].number_left,buffer);
temp_word=assignment_statement(temp_word);
sprintf(goto_place_2,"%d",quaternion_number+1);
strcpy(my_quaternion[temp-1].number_left,goto_place_2);
return temp_word;
}
cout<<"第"<<line<<"行,条件语句错误"<<endl;
WORD *theword = scanner();
while(theword->typenum!=30)theword=scanner();
return theword;
}
WORD *loop_statement(WORD *word)//循环语句
{
if(word == NULL)return NULL;
WORD *temp_word;
if(word->typenum==3)
{
char goto_place_1[20],goto_place_2[20],goto_place_3[20],buffer[255];
int temp_1=quaternion_number;
int temp_2=quaternion_number+2;
sprintf(goto_place_1,"%d",temp_2+1);
set_quaternion("if","#","goto",goto_place_1,0);
set_quaternion("goto","#","#","#",0);
temp_word=scanner();
temp_word=condition(temp_word,buffer);
strcpy(my_quaternion[temp_2-2].number_left,buffer);
temp_word=assignment_statement(temp_word);
sprintf(goto_place_2,"%d",quaternion_number+2);
strcpy(my_quaternion[temp_2-1].number_left,goto_place_2);
sprintf(goto_place_3,"%d",temp_1+1);
set_quaternion("goto",goto_place_3,"#","#",0);
return temp_word;
}
cout<<"第"<<line<<"行,循环语句错误"<<endl;
WORD *theword = scanner();
while(theword->typenum!=30)theword=scanner();
return theword;
}
WORD *condition(WORD *word,char *buffer)//条件
{
WORD *temp_word;
char buff1[255],buff2[255],buff3[255];
if(word->typenum==10||word->typenum==20)
{
strcpy(buff1,word->word);
temp_word = scanner();
}
temp_word=relational_operators(temp_word,buff2);
if(temp_word->typenum==10||temp_word->typenum==20)
{
strcpy(buff3,temp_word->word);
temp_word = scanner();
}
strcat(buff1,buff2);
strcat(buff1,buff3);
strcpy(buffer,buff1);
return temp_word;
}
WORD *expression(WORD *word,char *buffer)//表达式
{
WORD *temp_word;
char buff[255];
temp_word=term(word,buff);
if(temp_word == NULL)return NULL;
char *result,*number_left,*op,*number_right;
result = (char *)malloc(20);
number_left = (char *)malloc(20);
op = (char *)malloc(20);
number_right = (char *)malloc(20);
strcpy(number_left,buff);
while(temp_word->typenum == 22 || temp_word->typenum == 23)
{
strcpy(op,temp_word->word);
temp_word = scanner();
temp_word = term(temp_word,buff);
if(temp_word == NULL)return NULL;
strcpy(number_right,buff);
set_quaternion(result,number_left,op,number_right,1);
strcpy(number_left,result);
}
strcpy(buffer,number_left);
return temp_word;
}
WORD *term(WORD *word,char *buffer)//项
{
WORD *temp_word;
char buff[255];
temp_word = factor(word,buff);
if(temp_word == NULL)return NULL;
char *result,*number_left,*op,*number_right;
result = (char *)malloc(20);
number_left = (char *)malloc(20);
op = (char *)malloc(20);
number_right = (char *)malloc(20);
strcpy(number_left,buff);
while(temp_word->typenum == 24 || temp_word->typenum == 25)
{
strcpy(op,temp_word->word);
temp_word = scanner();
temp_word = factor(temp_word,buff);
if(temp_word == NULL)return NULL;
strcpy(number_right,buff);
set_quaternion(result,number_left,op,number_right,1);
strcpy(number_left,result);
}
strcpy(buffer,number_left);
return temp_word;
}
WORD *factor(WORD *word,char *buffer)//因子
{
char *number;
WORD *temp_word;
number = (char *)malloc(20);
strcpy(number,"");
if(word == NULL)return NULL;
if(word->typenum == 10||word->typenum==20)
{
strcpy(number,word->word);
temp_word = scanner();
}
else if(word->typenum == 26)
{
temp_word = scanner();
temp_word = expression(temp_word,number);
if(temp_word == NULL)return NULL;
if(temp_word->typenum == 27)
temp_word = scanner();
else
{
cout<<"第"<<line<<"行,)错误"<<endl;
strcpy(buffer,number);
WORD *theword = scanner();
while(theword->typenum!=30)theword=scanner();
return theword;
}
}
strcpy(buffer,number);
return temp_word;
}
WORD *relational_operators(WORD *word,char *buffer)//关系运算符
{
WORD *temp_word;
if(word == NULL)return NULL;
if(word->typenum>=31&&word->typenum<=36)
{
strcpy(buffer,word->word);
temp_word = scanner();
return temp_word;
}
else cout<<"第"<<line<<"行,关系运算符错误"<<endl;
return word;
}
void set_quaternion(char *result,char *number_left,char *op,char *number_right,int flag)//构建四元式
{
strcpy(my_quaternion[quaternion_number].number_left,number_left);
strcpy(my_quaternion[quaternion_number].op,op);
strcpy(my_quaternion[quaternion_number].number_right,number_right);
if(flag == 1)
{
char *temp = newtemp();
strcpy(result,temp);
strcpy(my_quaternion[quaternion_number].result,result);
}
else strcpy(my_quaternion[quaternion_number].result,result);
quaternion_number++;
return ;
}
void get_quaternion()//输出四元式
{
for(int i=0; i<quaternion_number; i++)
cout<<i+1<<"----"<<my_quaternion[i].result<<" "<<my_quaternion[i].number_left<<" "<<my_quaternion[i].op<<" "<<my_quaternion[i].number_right<<endl;
return;
}