用C或C++语言编写一门语言的词法分析器
(1)阅读已有编译器的经典词法分析源程序。
选择一个编译器,如:TINY,其它编译器也可(需自备源代码)。阅读词法分析源程序,理解词法分析程序的手工构造方法——状态图代码化。尤其要求对相关函数与重要变量的作用与功能进行稍微详细的描述。若能加上学习心得则更好。TINY语言请参考《编译原理及实践》第2.5节(见压缩包里附带的文档)。
(2)确定今后其他实验中要设计编译器的语言,如TINY语言,又如更复杂的C-语言(其定义在《编译原理及实践》附录A中)。也可选择其它语言,不过要有该语言的详细定义(可仿照C-语言)。一旦选定,不能更改,因为要在以后继续实现编译器的其它部分。鼓励自己定义一门语言。
(3)根据该语言的关键词和识别的词法单元以及注释等,确定关键字表,画出所有词法单元和注释对应的DFA图。
(4)仿照前面学习的词法分析器,编写选定语言的词法分析器。
(5)准备2~3个测试用例,要求包含正例和反例,测试编译结果。
关键代码
void display(string str,int a,ofstream &output){
output<<a<<": "<<str<<endl;
string str1="";
int count=0;
int j=0;
while(str[j]!='\0'){
if(str[j]=='{'){
flag=1;
num++;
}
if(flag==1){
output<<"\t"<<a<<": ";
while(str[j]!='}'){
if(str[j+1]!='\0'){
str1+=str[j];
j++;
}
else break;
}
if(str[j]=='}'){
str1+=str[j];
output<<str1<<endl;
str1="";
flag=0;
j++;
num--;
}
else{
if(str[j]!='\0'){
str1+=str[j];
}
output<<str1<<endl;
str1="";
j++;
}
}
else{
while((str[j]>='a'&&str[j]<='z')||(str[j]>='A'&&str[j]<='Z')){
if((str[j+1]>='a'&&str[j+1]<='z')||(str[j+1]>='A'&&str[j+1]<='Z')){
str1+=str[j];
j++;
}/*else if(str[j+1]>='0'&&str[j+1]<='9'){
output<<"\t"<<a<<": "<<"error, miss a ' ' "<<endl;
str1="";
j++;
}*/else{
str1+=str[j];
if(save(str1)==1){
output<<"\t"<<a<<": "<<"Reversed Word: "<<str1<<endl;
}
else{
output<<"\t"<<a<<": "<<"ID, name= "<<str1<<endl;
}
str1="";
j++;
}
}
while(str[j]>='0'&&str[j]<='9'){
if(str[j+1]>='0'&&str[j+1]<='9'){
count=count*10+str[j]-'0';
j++;
}/*else if((str[j+1]>='a'&&str[j+1]<='z')||(str[j+1]>='A'&&str[j+1]<='Z')){
output<<"\t"<<a<<": "<<"error, miss a ' ' "<<endl;
count=0;
j++;
}*/
else{
count=count*10+str[j]-'0';
output<<"\t"<<a<<": "<<"NUM, val= "<<count<<endl;
j++;
count=0;
}
}
if(pluss(str[j])==1||reduce(str[j])==1||multiply(str[j])==1||division(str[j])==1||equal(str[j])==1||lesss(str[j])==1||LP(str[j])==1||RP(str[j])==1||semicolon(str[j])==1){
output<<"\t"<<a<<": "<<str[j]<<endl;
j++;
}
if(str[j]==':'){
str1+=str[j];
if(str[j+1]=='='){
str1+=str[j+1];
output<<"\t"<<a<<": "<<str1<<endl;
j+=2;
str1="";
}
else{
output<<"\t"<<a<<": "<<"error, miss a '='"<<endl;
str1="";
j++;
}
}
if(str[j]=='}'){
output<<"\t"<<a<<": "<<str[j]<<endl;
j++;
num--;
continue;
}
if(str[j]!='\0'){
if(others(str[j])==1){
output<<"\t"<<a<<": "<<"error, inavild"<<endl;
j++;
}
}
}
}
}
测试用例
{ Sample program
in TINY language -
computes factorial
}
read x; { input an integer }
if 0 < x then { don’t compute if x <= 0 }
fact := 1;
repeat
fact := fact * x;
x := x - 1
until x = 0;
write fact { output factorial of x }
and
输出结果
1: { Sample program
1: { Sample program
2: in TINY language -
2: in TINY language -
3: computes factorial
3: computes factorial
4: }
4: }
5: read x; { input an integer }
5: Reversed Word: read
5: ID, name= x
5: ;
5: { input an integer }
6: if 0 < x then { don’t compute if x <= 0 }
6: Reversed Word: if
6: NUM, val= 0
6: <
6: ID, name= x
6: Reversed Word: then
6: { don’t compute if x <= 0 }
7: fact := 1;
7: ID, name= fact
7: :=
7: NUM, val= 1
7: ;
8: repeat
8: Reversed Word: repeat
9: fact := fact * x;
9: ID, name= fact
9: :=
9: ID, name= fact
9: *
9: ID, name= x
9: ;
10: x := x - 1
10: ID, name= x
10: :=
10: ID, name= x
10: -
10: NUM, val= 1
11: until x = 0;
11: Reversed Word: until
11: ID, name= x
11: =
11: NUM, val= 0
11: ;
12: write fact { output factorial of x }
12: Reversed Word: write
12: ID, name= fact
12: { output factorial of x }
13: and
13: ID, name= and