编译原理实验-词法分析器(包含源码)
本实验是合肥工业大学编译原理实验的百年老题目,这里只提供实验1,若有需要2、3可以去博主的GitHub上面
链接
一、实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、功能描述
1) 从文件中读入c语言源程序
2) 统计行数和列数用于错误单词的定位
3) 删除空格类字符,包括回车、制表符空格
4) 按拼写单词,并用(内码,属性)二元式表示
5) 如果发现错误则报告出错
6) 根据需要是否填写标识符表供以后各阶段使用
7) 识别注释
8) 可识别小数
三、程序结构设计
四、详细的算法描述
五、测试方法和结果
测试方法
(1). C语言源程序存放在test.txt文件里面,直接打开读取此文件。
(2).可以识别注释,不分析;可识别小数
(3).可以识别的错误有:
标识符不规范的命名方式,如数字开头;
连续的算数运算符连在一起,如+-
错误的关系运算符,如<<
一个数字里面出现两个小数点,如3.1.4
一些非法的输入。
测试样例:
if i=0 then n++; //abc
a <=3b%);
12.3
1.3.4
<<
3+- 1
aa
测试结果
package bianYiYuanLi
;
import java
.io
.*
;
import java
.util
.*
;
public class work1 {
static ArrayList
<String> k
=new ArrayList<String>(Arrays
.asList("do","end","for","if","printf","scanf","then","while"));
static ArrayList
<String> s
=new ArrayList<String>(Arrays
.asList(",",";","(",")","[","]"));
static ArrayList
<String> a
=new ArrayList<String>(Arrays
.asList("+","-","*","/"));
static ArrayList
<String> r
=new ArrayList<String>(Arrays
.asList("<","<=",">",">=","=","<>"));
static ArrayList
<String> ci
=new ArrayList<>();
static ArrayList
<String> id
=new ArrayList<>();
static int hangX
=1;
static int lieY
=1;
static void searchDis(String str
) {
int i
=0;
char ch
=str
.charAt(0);
if ((ch
>=65&&ch
<=90)||(ch
>=97&&ch
<=122))
i
=1;
else if(ch
>=48&&ch
<=57)
i
=2;
else
i
=3;
if (i
==1) {
boolean find
=k
.contains(str
);
if(find
==true) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(1,"+str
+")","关键字","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else {
find
=id
.contains(str
);
if(find
==true) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(6,"+str
+")","标识符","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(6,"+str
+")","标识符","("+hangX
+","+lieY
+")");
System
.out
.println();
id
.add(str
);
}
}
}
else if(i
==2) {
boolean find
=ci
.contains(str
);
if(find
==true) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(5,"+str
+")","常数","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(5,"+str
+")","常数","("+hangX
+","+lieY
+")");
System
.out
.println();
ci
.add(str
);
}
}
else {
if(s
.contains(str
)) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(2,"+str
+")","分界符","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else if(a
.contains(str
)) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(3,"+str
+")","算术运算符","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else if(r
.contains(str
)) {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"(4,"+str
+")","关系运算符","("+hangX
+","+lieY
+")");
System
.out
.println();
}
else {
System
.out
.printf("%-10s%-10s%-10s%-10s",str
,"Error","Error","("+hangX
+","+lieY
+")");
System
.out
.println();
}
}
}
static void analysisString(String str2
) {
String strNow
="";
char ch1
;
for(int i
=0;i
<str2
.length();i
++) {
ch1
=str2
.charAt(i
);
if(ch1
==' ')
continue;
if((ch1
>=65&&ch1
<=90)||(ch1
>=97&&ch1
<=122)) {
strNow
+=ch1
;
i
++;
do {
ch1
=str2
.charAt(i
);
if((ch1
>=65&&ch1
<=90)||(ch1
>=97&&ch1
<=122)||(ch1
>=48&&ch1
<=57)) {
strNow
+=ch1
;
i
++;
}
else
break;
}while(i
<str2
.length());
i
--;
searchDis(strNow
);
strNow
="";
lieY
++;
continue;
}
else if(ch1
>=48&&ch1
<=57) {
strNow
+=ch1
;
i
++;
while(i
<str2
.length()){
ch1
=str2
.charAt(i
);
if((ch1
>=65&&ch1
<=90)||(ch1
>=97&&ch1
<=122)||(ch1
>=48&&ch1
<=57)||ch1
=='.') {
strNow
+=ch1
;
i
++;
}
else
break;
}
i
--;
int j
;
boolean errorDone
=false;
for(j
=0;j
<strNow
.length();j
++) {
char ch2
=strNow
.charAt(j
);
if((ch2
>=65&&ch2
<=90)||(ch2
>=97&&ch2
<=122)) {
System
.out
.printf("%-10s%-10s%-10s%-10s",strNow
,"Error","Error","("+hangX
+","+lieY
+")");
System
.out
.println();
errorDone
=true;
break;
}
}
int m
;
boolean tag
=false;
for(m
=0;m
<strNow
.length();m
++) {
char ch2
=strNow
.charAt(m
);
if(ch2
=='.'&&tag
) {
if(!errorDone
) {
System
.out
.printf("%-10s%-10s%-10s%-10s",strNow
,"Error","Error","("+hangX
+","+lieY
+")");
System
.out
.println();
}
errorDone
=true;
break;
}
else if(ch2
=='.'&&!tag
) {
tag
=true;
}
}
if(!errorDone
)
searchDis(strNow
);
strNow
="";
lieY
++;
continue;
}
else {
strNow
+=ch1
;
if(s
.contains(strNow
)) {
searchDis(strNow
);
strNow
="";
lieY
++;
continue;
}
else if(a
.contains(strNow
)||r
.contains(strNow
)) {
i
++;
while(i
<str2
.length()) {
ch1
=str2
.charAt(i
);
if(a
.contains(ch1
+"")||r
.contains(ch1
+"")) {
strNow
+=ch1
;
i
++;
}
else
break;
}
searchDis(strNow
);
i
--;
strNow
="";
lieY
++;
continue;
}
else {
searchDis(strNow
);
strNow
="";
lieY
++;
continue;
}
}
}
}
public static void main(String
[] args
) {
try {
RandomAccessFile inF
=new RandomAccessFile("test.txt","r");
String str1
=null
;
while((str1
=inF
.readLine())!=null
) {
for(int i
=0;i
<str1
.length()-1;i
++) {
if(str1
.charAt(i
)=='/'&&str1
.charAt(i
+1)=='/') {
str1
=str1
.substring(0, i
);
break;
}
}
analysisString(str1
);
hangX
++;
lieY
=1;
}
inF
.close();
}
catch(IOException e
) {
System
.out
.println(e
);
}
}
}