编译原理实验-词法分析器(包含源码)
本实验是合肥工业大学编译原理实验的百年老题目,这里只提供实验1,若有需要2、3可以去博主的GitHub上面
一、实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、功能描述
1) 从文件中读入c语言源程序
2) 统计行数和列数用于错误单词的定位
3) 删除空格类字符,包括回车、制表符空格
4) 按拼写单词,并用(内码,属性)二元式表示
5) 如果发现错误则报告出错
6) 根据需要是否填写标识符表供以后各阶段使用
7) 识别注释
8) 可识别小数
三、程序结构设计
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200902230525471.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExMjg1MQ==,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200902230453448.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExMjg1MQ==,size_16,color_FFFFFF,t_70#pic_center)
四、详细的算法描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200902230623148.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExMjg1MQ==,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200902230636652.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExMjg1MQ==,size_16,color_FFFFFF,t_70#pic_center)
五、测试方法和结果
测试方法
(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
测试结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200902230851132.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDExMjg1MQ==,size_16,color_FFFFFF,t_70#pic_center)
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);
}
}
}