【编译原理】作业:简单的词法分析器(Java)
课堂上留的作业,简单的词法分析器,花了一天时间做完,写个小笔记
程序思路来自 四季写爱 ,感兴趣的可以去看看
以下是我的代码:
import java.io.File;
import java.io.FileReader;
import java.util.Scanner;
public class Lexer {
public static void main(String[] args) throws Exception {
char[] chars = readFile();
analyze(chars);
}
public static void analyze(char[] opt){
int variableCounter = 0; //标识符计数器
String temp; //当前字符串
char current; //当前字符
for (int i = 0; i < opt.length; i++){
temp = "";
current = opt[i];
if (current == ' ' || current == '\t' || current =='\r'){ //空格处理
}else if (isLetter(current) || current == '_'){ //读取到字母或者_
while (isLetter(current) || isDigit(current) || current == '_'){ //字母或_开头可能出现的情况
temp+=current; //拼接到当前字符串
current = opt[++i];
}
i--; //不匹配while条件时的回退
if (isKeyWord(temp)){ //关键字匹配
System.out.println(temp + "是关键字");
}else if (isVariableName(temp)){ //标识符匹配
variableCounter++;
System.out.println("<id(" + temp + ")," + variableCounter + ">");
}
}else if (isDigit(current)){
while (isDigit(current) || current == '.' || current == 'E' || current == 'e' ||current == '-' || current == '+'){ //数字开头可能出现的情况
temp+=current;
current = opt[++i];
}
i--;
if (isUnsignedNumber(temp)){
System.out.println("<" + temp + ">");
}
}else if (isOperator(temp+=current)){ //操作符情况
System.out.println("<" + temp + ">");
}
}
}
/**
* 获取文件字符流
* @return 返回给定文件的字符流
* @throws Exception
*/
public static char[] readFile() throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the src of your file:");
String src = sc.nextLine();
File file = new File(src);
FileReader fileReader = new FileReader(file);
int length = (int) file.length();
char buf[] =new char[length+1];
fileReader.read(buf);
fileReader.close();
sc.close();
return buf;
}
/**
* 判定变量名
* @param opt 判定对象
* @return true是合法变量名,false非法变量名
*/
public static boolean isVariableName(String opt){
char[] chars = opt.toCharArray();
boolean flag = true;
if (!isLetter(chars[0]) && chars[0] != '_'){
flag = false;
return flag;
}
for (int i = 1; i < chars.length; i++){
if (!isLetter(chars[i]) && chars[i] != '_' && !isDigit(chars[i])){
flag = false;
return flag;
}
}
return flag;
}
/**
* 判定无符号数
* @param opt 判定对象字符串
* @return true是无符号数,false不是无符号数
*/
public static boolean isUnsignedNumber(String opt){
char[] chars = opt.toCharArray();
boolean flag = true;
boolean dot = false;
boolean exponent = false;
if (!isDigit(chars[0])){ //第一个字符不是数字
flag = false;
return flag;
}
for (int i = 1; i < chars.length; i++){
//非数字,小数点,Ee的字符判定
if (!isDigit(chars[i]) && chars[i] != 'e' && chars[i] != 'E' && chars[i] != '.' ){
flag = false;
return flag;
}
//.的判定
if (chars[i] == '.' && !dot){ //第一次出现小数点
dot = true; //包含小数点
}else if(chars[i] == '.' && dot){ //第二次出现小数点
flag = false;
return flag;
}
//Ee的判定
if ((chars[i] == 'e' || chars[i] == 'E') && !exponent) { //第一次出现指数e
exponent = true; //指数e
i++;
//Ee后的符号判定及处理
if(i == chars.length){ //数组越界处理,说明字符串以e结尾
flag = false;
return flag;
}
if (chars[i] != '-' && chars[i] != '+') { //指数后面的符号
i--; //回溯
}
}else if((chars[i] == 'e' || chars[i] == 'E') && exponent){ //第二次出现指数e
flag =false;
return flag;
}
}
return flag;
}
/**
* 判断关键字
* @param opt 被判断的字符串
* @return true是关键字,false不是关键字
*/
public static boolean isKeyWord(String opt){
//保留字集
String[] keyWordSet = {"if", "while", "else", "switch"};
boolean flag = false;
for (int i = 0; i < keyWordSet.length; i++) {
if (opt.equals(keyWordSet[i])){
flag = true;
return flag;
}
}
return flag;
}
/**
* 判别无符号数
* @param opt 被判别的字符
* @return true是数字,false不是数字
*/
public static boolean isDigit(char opt){
if (opt >= '0' && opt <= '9'){
return true;
}
return false;
}
/**
* 判别字母
* @param opt 被判别的字符
* @return true是字母,false不是字母
*/
public static boolean isLetter(char opt){
if ((opt >= 'a' && opt <= 'z')||(opt >= 'A' && opt <= 'Z')) {
return true;
}
return false;
}
/**
* 判断操作符
* @param opt 被判断的字符
* @return true是操作符,false非操作符
*/
public static boolean isOperator(String opt){
boolean flag = false;
String[] operators = {"+", "-", "*", "/", "="};
for (int i = 0; i < operators.length; i++){
if (opt.equals(operators[i])){
flag = true;
return flag;
}
}
return flag;
}
}
提供的文件:

运行结果:


浙公网安备 33010602011771号