一、实验目的
通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、实验内容
用 VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;同时进行标识符登记符号表的管理。
以下是实现词法分析设计的主要工作:
(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 的机内表示)
(5)如果发现错误则报告出错
(6)根据需要是否填写标识符表供以后各阶段使用。
单词的基本分类:
关键字:由程序语言定义的具有固定意义的标识符。也称为保留字例如 if、 for、while、printf ; 单词种别码为 1。
标识符:用以表示各种名字,如变量名、数组名、函数名;
常数: 任何数值常数。如 125, 1,0.5,3.1416;
运算符:+、-、*、/;
关系运算符: <、<=、= 、>、>=、<>;
分界符: ;、,、(、)、 [、];
话不多说,直接上代码:
package WordAnalyzise;
/**
* @author Zou
* @file_name WordAnalyzise.java
* @date 2019年10月28日
*/
import java.util.*;
import java.io.*;
public class WordAnalyzise {
static String k[]={"do","end","then","if","printf","scanf","then","while","auto","break","case","char",
"const","continue","default","double","else","enum","extern","float","goto","int","long","register",
"return","short","signed","sizeof","static","struct","switch",
"typedef","union","unsigned","void","volatile","inline"};//1 关键字
static char s[]={',',';','(',')','[',']','{','}'};//2 分界符
static char m[]={'+','-','*','/'};//3 算术运算符
static String r []={"<","<=","=",">",">=","<>"};//4 关系运算符
ArrayList ci= new ArrayList<>();//5 常数
ArrayList id= new ArrayList<>();//6 标识符
int pint;// 搜索指示器
String strtoken="";// 存放构成单词符号的字符串
int row;// 行数
int line;// 列数
char ch;// 存放最新读入源程序字符
String instring;// 存放输入源程序
WordAnalyzise(){// 初始化
instring="if i=0 then n++;\na<= 3b %);";// 默认输入源程序
row=1;// 行数置 1
line=1;// 列数置 1
pint=-1;// 搜索指示器置 -1
}
public static void main(String args[]) throws Exception{
WordAnalyzise one = new WordAnalyzise();
System.out .println(" 单 词 二 元 序 列 类 型 位 置(行,列) ");
one.handle();
// one.readstr();
// one.readtext();
}
boolean isdigit( char c){// 判断字符 c是否是数字
if (c>=48&&c<=57) return true ;
return false ;
}
boolean isletter( char c){// 判断字符 c是否是字母
if ((c>64&&c<91)||(c>96&&c<123)) return true ;
return false ;
}
boolean isline( char c){// 判断字符 c是否是下划线
if (c=='_') return true ;
return false ;
}
boolean remove(){// 用于在判断关系运算符时,判断是否是要再读一个字符
char b=instring.charAt(pint+1);
if (b=='='||b=='>'){// 当其后的字符是 =或>时, 要再读一个字符。否则不要再读。
return true ;
}
return false ;
}
boolean sremove(){//用于判断算数运算符时,是否需要再读一个字符
char b = instring.charAt(pint);
char bn=instring.charAt(pint+1);
String s = Character.toString(b)+Character.toString(bn);
if ("++".equals(s)||"--".equals(s)){
return true;
}
return false;
}
void getbc(){// 检查空白直到读入字符非空白
while (ch==' '){
getchar();
}
}
void getchar(){// 读入下一个字符
pint++;
if (pint<=instring.length()-1){// 当指针没有越界时, 可读字符
ch=instring.charAt(pint);
if (ch=='\n'){// 当读到换行符时,行数加一,列数置一。再读下一个字符
change_r_l();
getchar();
}
}
else ch=' ';// 当指针越界时,置 ch为空白符
}
void retract(){// 读入前一个字符
pint--;
ch=instring.charAt(pint);
}
void words(){// 识别字符串
strtoken="";// 先将strtoken 置空
while (isletter(ch)||isdigit(ch)||isline(ch)){// 当是字母,数字,下划线时继续识别字符串
strtoken=strtoken+ch;// 将新识别的字符加到 strtoken后
getchar();
}
}
void num(){// 识别数字串
strtoken="";// 先将strtoken 置空
while (isdigit(ch)){// 当数字时继续识别数字串
strtoken=strtoken+ch;// 将新识别的字符加到 strtoken后
getchar();
}
if (isletter(ch)||isline(ch)){// 识别完数字串而其后是字母,下划线时出错处理
while (isletter(ch)||isline(ch)||isdigit(ch)){// 当是字母,数字,下划线时继续识别错误数字串
strtoken=strtoken+ch;// 将 新 识 别 的 字 符 加 到strtoken 后
getchar();
}
show(0,strtoken,' ');// 输出错误数字串
strtoken="";// 将strtoken 置空返回
}
}
void show( int i,String s, char a){// 各种输出处理
switch (i){
case -1:System. out .println(a+" "+"Error"+" Error "+"("+row+","+line+")");
break ;
case 0:System. out .println(s+" "+"Error"+" Error "+"("+row+","+line+")");
break ;
case 1:System. out .println(s+" "+"(1,"+s+")"+" 关 键 字"+"("+row+","+line+")");
break ;
case 2:System. out .println(a+" "+"(2,"+a+")"+" 分 界 符"+"("+row+","+line+")");
break ;
case 3:System. out .println(a+" "+"(3,"+a+")"+" 算 术 运 算 符"+"("+row+","+line+")");
break ;
case 4:System. out .println(s+" "+"(4,"+s+")"+" 关 系 运 算 符"+"("+row+","+line+")");
break ;
case 5:System. out .println(s+" "+"(5,"+s+")"+" 常 数"+"("+row+","+line+")");
break ;
case 6:System. out .println(s+" "+"(6,"+s+")"+" 标 识 符"+"("+row+","+line+")");
break ;
}
line++;// 列数加一
}
void change_r_l(){// 改变行列数
row++;
line=1;
}
void handle(){// 输入串处理
pint=-1;// 将搜索指示器置 -1
System.out .println(" 要处理的语句为 : "+instring);
getchar();// 读入一个字符
while (pint