词法分析程序(Lexical Analyzer)要求:
- 从左至右扫描构成源程序的字符流
- 识别出有词法意义的单词(Lexemes)
- 返回单词记录(单词类别,单词本身)
- 滤掉空格
- 跳过注释
- 发现词法错误
程序结构:
输入:字符流(什么输入方式,什么数据结构保存)
处理:
–遍历(什么遍历方式)
–词法规则
输出:单词流(什么输出形式)
–二元组
单词类别:
1.标识符(10)
2.无符号数(11)
3.保留字(一词一码)
4.运算符(一词一码)
5.界符(一词一码)
单词符号 |
种别码 |
单词符号 |
种别码 |
begin |
1 |
: |
17 |
if |
2 |
:= |
18 |
then |
3 |
< |
20 |
while |
4 |
<= |
21 |
do |
5 |
<> |
22 |
end |
6 |
> |
23 |
l(l|d)* |
10 |
>= |
24 |
dd* |
11 |
= |
25 |
+ |
13 |
; |
26 |
- |
14 |
( |
27 |
* |
15 |
) |
28 |
/ |
16 |
# |
0 |
代码如下:
1 package com.bianyi_demo; 2 3 import java.io.File; 4 import java.io.FileReader; 5 6 public class LexicalAnalyze { 7 private char ch; 8 private String reservedWord[] = {"begin", "if", "then", "while", "do", "end"}; // 保留字 9 10 // 判断是否是保留字 11 boolean isReserveWord(String str) { 12 for (int i = 0; i < reservedWord.length; i++) { 13 if (reservedWord[i].equals(str)) 14 return true; 15 } 16 return false; 17 } 18 19 // 判断是否是字母 20 boolean isLetter(char letter) { 21 if ((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z')) 22 return true; 23 else 24 return false; 25 } 26 27 // 判断是否是数字 28 boolean isDigit(char digit) { 29 if (digit >= '0' && digit <= '9') 30 return true; 31 else 32 return false; 33 } 34 35 public void analyze(char[] chars) { 36 String array = ""; 37 for (int i = 0; i < chars.length; i++) { 38 ch = chars[i]; 39 array = ""; 40 41 if (ch == ' ' || ch == ' ' || ch == ' ' || ch == ' ') { 42 } else if (isLetter(ch)) { 43 while ((isLetter(ch) || isDigit(ch))) { 44 array += ch; 45 ch = chars[++i]; 46 } 47 // 回退一个字符 48 i--; 49 if (isReserveWord(array)) { 50 // System.out.println("这里是有显示的"); 51 // 保留字 52 // System.out.println(array); 53 if (array.equals("begin")) { 54 System.out.println("(begin, 1)"); 55 } else if (array.equals("if")) { 56 System.out.println("(if, 2)"); 57 } else if (array.equals("then")) { 58 System.out.println("(then, 3)"); 59 } else if (array.equals("while")) { 60 System.out.println("(while, 4)"); 61 } else if (array.equals("do")) { 62 System.out.println("(do, 5)"); 63 } else if (array.equals("end")) { 64 System.out.println("(end, 6)"); 65 } 66 } else { 67 if (array.equals("l(l|d)*")) 68 System.out.println("(l(l|d)*, 10)"); 69 else if (array.equals("dd*")) 70 System.out.println("(dd*, 11)"); 71 } 72 } else if (isDigit(ch) || (ch == '.')) { 73 while (isDigit(ch) || (ch == '.' && isDigit(chars[++i]))) { 74 if (ch == '.') 75 i--; 76 array = array + ch; 77 ch = chars[++i]; 78 } 79 // 属于无符号常数 80 System.out.println("(" + array + ", 11)"); 81 } else switch (ch) { 82 case '+': 83 System.out.println("(+, 13)"); 84 break; 85 case '-': 86 System.out.println("(-, 14)"); 87 break; 88 case '*': 89 System.out.println("(*, 15)"); 90 break; 91 case '/': 92 System.out.println("(/, 16)"); 93 break; 94 case '(': 95 System.out.println("((, 27)"); 96 break; 97 case ')': 98 System.out.println("(), 28)"); 99 break; 100 case '#': 101 System.out.println("(#, 0)"); 102 break; 103 case '=': 104 System.out.println("(=, 25)"); 105 break; 106 case '>': { 107 ch = chars[++i]; 108 if (ch == '=') 109 System.out.println("(>=, 24)"); 110 else { 111 System.out.println("(>, 23)"); 112 i--; 113 } 114 } 115 break; 116 case '<': { 117 ch = chars[++i]; 118 if (ch == '=') 119 System.out.println("(<=, 21)"); 120 else { 121 System.out.println("(<, 20)"); 122 i--; 123 } 124 } 125 break; 126 case ':': { 127 ch = chars[++i]; 128 if (ch == '=') 129 System.out.println("(:=, 18)"); 130 else { 131 System.out.println("(:, 17)"); 132 i--; 133 } 134 } 135 break; 136 } 137 } 138 } 139 140 public static void main(String[] args) throws Exception { 141 // 输入字符流:以txt文件的形式输入,将文件的字符读取到字符数组中去,采用遍历数组的方式,读取分类后输出 142 File file = new File("./txt/analyzeTest.txt"); 143 FileReader reader = new FileReader(file); 144 int length = (int) file.length(); 145 char buffer[] = new char[length + 1]; 146 reader.read(buffer); 147 reader.close(); 148 new LexicalAnalyze().analyze(buffer); 149 } 150 }
测试的文件:
程序运行结果如下图所示: