词法分析 java版
基于java的语法分析的程序,基本功能已经实现了
这个是要求
(1)关键字:
begin if then while do end
所有的关键字都是小写。
(2)运算符和界符
: = + - * / < <= <> > >= = ; ( ) #
(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:
ID = letter (letter | digit)*
NUM = digit digit*
(4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符
单词符号 | 种别码 | 单词符号 | 种别码 |
---|---|---|---|
begin | 1 | : | 17 |
If | 2 | := | 18 |
Then | 3 | < | 20 |
wile | 4 | <> | 21 |
do | 5 | <= | 22 |
end | 6 | > | 23 |
lettet(letterdigit)* | 10 | >= | 24 |
dight dight* | 11 | = | 25 |
+ | 13 | ; | 26 |
— | 14 | ( | 27 |
* | 15 | ) | 28 |
/ | 16 | # | 0 |
package t1;
import java.util.HashMap;
import java.util.Map;
/**
* @program: cc
* @description: 词法分析程序
* @author: Xuexuexue
* @create: 2021-06-07 16:12
*/
public class LexicalAnalysis {
public static Boolean isChar(char i) {
//这是一个字母 接下来判断他的下一个是否是字母
return 'a' <= i && i <= 'z' || 'A' <= i && i <= 'Z';
}
public static Boolean isNumber(char i) {
return '0' <= i && i <= '9';
}
/**
* 用于输出 语句
*
* @param i 编号
* @param mm 输出的字符串
*/
public static void outInf(Integer i, String mm) {
System.out.println("(" + i + "," + mm + ")");
}
public static void main(String[] args) {
//输入一个规定的字符串
String str = "begin x:=9: if x>9 then x:=2*x+1/3; end #";
//进行分析输出
int p = 0;
int q;
int syn;
String[] key1 = {"begin", "if", "then", "while", "do", "end"};
Map<String, Integer> key = new HashMap<>();
// ArrayList<String> key = new ArrayList<String>();
key.put("begin", 1);
key.put("If", 2);
key.put("Then", 3);
key.put("wile", 4);
key.put("do", 5);
key.put("end", 6);
key.put("lettet(letter|digit)*", 10);
key.put("dight dight*", 1);
key.put("+", 3);
key.put("—", 14);
key.put("*", 15);
key.put("/", 16);
key.put(":", 17);
key.put(":=", 18);
key.put("<", 20);
key.put("<>", 21);
key.put("<=", 22);
key.put(">", 23);
key.put(">=", 24);
key.put("=", 25);
key.put(";", 26);
key.put("(", 27);
key.put(")", 28);
key.put("#", 0);
try {
char[] m = str.toCharArray();
//因为是词法分析,为了体现算法,这里不再使用正则表达来匹配 使用for来循环实现
for (int ii = 0; ii <= m.length; ii++) {
char i = m[ii];
//先判断是否i在 单词符号的表中 可以用来判断符号
Integer integer = key.get(String.valueOf(i));
if (integer != null) {
//存在在字母表中我们进行输出
outInf(integer, String.valueOf(i));
} else {
//假如说不存在单词表那么可以确定是保留字 或者是 整型变量 或者是标识符
//如果是标识符的话 lettet(letter|digit)* 那么应该是一个字母 开头
if (isChar(i)) {
//创建 mm 来保存我们的字母的信息
String mm = String.valueOf(i);
// System.out.println("我们发现一个字母" + i);
//这是一个字母 接下来判断他的下一个是否是字母
while (true) {
//看看他的下一位是什么
i = m[++ii];
if (isChar(i) || isNumber(i)) {
// System.out.println("他的下一位依旧是字母" + i);
mm = mm + i;
} else {
ii--;
Integer integer1 = key.get(mm);
if (integer1 != null) {
outInf(integer1, mm);
} else {
outInf(10, mm);
}
break;
}
}
//完成了这次的字母的分析,下面的将不用运行
continue;
}
if (isNumber(i)) {
// System.out.println("我们发现一个数字" + i);
//数字问题直接复制前面的就行了
//创建 mm 来保存我们的字母的信息
String mm = String.valueOf(i);
//这是一个字母 接下来判断他的下一个是否是字母
while (true) {
//看看他的下一位是什么
i = m[++ii];
if (isNumber(i)) {
// System.out.println("这还是个数字" + i);
mm = mm + i;
} else {
ii--;
Integer integer1 = key.get(mm);
if (integer1 != null) {
//应该不会有数字开头的关键字吧
outInf(integer1, mm);
} else {
outInf(1, mm);
}
break;
}
}
}
}
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("发生越界异常,这个bug我还不晓得在哪出现的");
}
}
}