实验一 词法分析器+【编译原理】
- 前言
- 推荐
- 实验一 词法分析器+
- keywords.txt
- operators.txt
- 测试
- 词法分析器的状态转移图
- 代码实现
- 最后
前言
2023-4-2 20:04:46
以下内容源自《【编译原理】》
仅供学习交流使用
推荐
实验一 词法分析器【编译原理】
实验一 词法分析器+
书接上文
要求:代码的高级功能
更多的关键字(运算符)
需要编写keywords.txt
更多的常数(科学计数法 浮点数 字符串常量)
需要重写analyzer
更多的功能(过滤无效字符、数值转换、宏展开、预包含处理)
需要重写analyzer
还有
出错位置没有行数
需要修改loadInput()逻辑
使其每读入一行,就进行语法分析处理
并且需要row行数属性来配合
下面实现C语言的词法分析
keywords.txt
除了32个关键字,还有用户预编译单词
并把34种运算符拆开为符号
有可能仍有遗漏
1 include
2 define
3 ifdef
4 ifndef
5 auto
6 break
7 case
8 char
9 const
10 continue
11 default
12 do
13 double
14 else
15 enum
16 extern
17 float
18 for
19 goto
20 if
21 int
22 long
23 register
24 return
25 short
26 signed
27 sizeof
28 static
29 struct
30 switch
31 typedef
32 union
33 unsigned
34 void
35 volatile
36 while
此处没有了
identifierList
constantList
operators.txt
新建一个运算符表
注意:
虽然有重复的但是他们的功能不一样
需要根据上下文环境确定具体功能
1 #
2 $
3 ‘
4 “
5 \
6 {
7 }
8 ;
9 (
10 )
11 [
12 ]
13 ->
14 .
15 !
16 ~
17 ++
18 --
19 +
20 -
21 *
22 &
23 *
24 /
25 %
26 +
27 -
28 <<
29 >>
30 <
31 <=
32 >
33 >=
34 ==
35 !=
36 &
37 ^
38 |
39 &&
40 ||
41 ?
42 :
43 =
44 +=
45 -=
46 *=
47 /=
48 %=
49 <<=
50 >>=
51 &=
52 ^=
53 |=
54 ,
测试
package s1;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SeniorLexicalAnalyzer extends AbstractLexicalAnalyzer{
public List<Symbol> operatorList=new ArrayList<>();//运算符表
//创建关键字表 根据表3.1实现
{
File file = new File("operators.txt");
if (file.exists()) {
System.out.println("operators.txt文件存在");
System.out.println("读取文件,加载运算符表");
loadOperatorList();
} else {
System.out.println("operators.txt文件不存在");
System.out.println("采用默认的运算符表");
initOperatorList();
}
}
//读取operators.txt文件的内容加载到operatorList中
public void loadOperatorList() {
try {
BufferedReader reader = new BufferedReader(new FileReader("operators.txt"));
String line;
while ((line = reader.readLine()) != null) {
String[] arr = line.split("\\s+");
operatorList.add(new Symbol(Integer.parseInt(arr[0]), arr[1]));
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//默认的运算符表
public void initOperatorList(){
keywordList.add(new Symbol(1,"="));
keywordList.add(new Symbol(2,"+"));
keywordList.add(new Symbol(3,"*"));
keywordList.add(new Symbol(4,"**"));
keywordList.add(new Symbol(5,","));
keywordList.add(new Symbol(6,"("));
keywordList.add(new Symbol(7,")"));
}
//重写 状态转移图实现
@Override
public void analyzer() {
}
//测试词法分析器
private void testAnalyzers(){
}
//重写出错处理,跳过1下,继续分析
@Override
public void procError(){
System.out.println("词法分析出错"+"\n"+"出错位置为"+position);
System.out.println("跳过错误,继续分析");
position++;
if(ch!=EOF){
ch=' ';
}
}
//测试关键词表的赋值
private void testKeywordList(){
for (Symbol s:keywordList) {
System.out.println(s);
}
}
//测试运算符表的赋值
private void testOperatorList(){
for (Symbol s:operatorList) {
System.out.println(s);
}
}
public static void main(String[] args) {
SeniorLexicalAnalyzer lex = new SeniorLexicalAnalyzer();
//测试
lex.testKeywordList();
lex.testOperatorList();
//测试
// new SeniorLexicalAnalyzer().testAnalyzers();
}
}
重申:
关键词表中的code没有什么意义
只有单词表中的code有意义
所以运算符表中就没有设置code
测试结果
keywords.txt文件存在
读取文件,加载关键词表
operators.txt文件存在
读取文件,加载运算符表
Symbol{id=1, value='include', code=0}
Symbol{id=2, value='define', code=1}
Symbol{id=3, value='ifdef', code=2}
Symbol{id=4, value='ifndef', code=3}
Symbol{id=5, value='auto', code=4}
Symbol{id=6, value='break', code=5}
Symbol{id=7, value='case', code=6}
Symbol{id=8, value='char', code=7}
Symbol{id=9, value='const', code=8}
Symbol{id=10, value='continue', code=9}
Symbol{id=11, value='default', code=10}
Symbol{id=12, value='do', code=11}
Symbol{id=13, value='double', code=12}
Symbol{id=14, value='else', code=13}
Symbol{id=15, value='enum', code=14}
Symbol{id=16, value='extern', code=15}
Symbol{id=17, value='float', code=16}
Symbol{id=18, value='for', code=17}
Symbol{id=19, value='goto', code=18}
Symbol{id=20, value='if', code=19}
Symbol{id=21, value='int', code=20}
Symbol{id=22, value='long', code=21}
Symbol{id=23, value='register', code=22}
Symbol{id=24, value='return', code=23}
Symbol{id=25, value='short', code=24}
Symbol{id=26, value='signed', code=25}
Symbol{id=27, value='sizeof', code=26}
Symbol{id=28, value='static', code=27}
Symbol{id=29, value='struct', code=28}
Symbol{id=30, value='switch', code=29}
Symbol{id=31, value='typedef', code=30}
Symbol{id=32, value='union', code=31}
Symbol{id=33, value='unsigned', code=32}
Symbol{id=34, value='void', code=33}
Symbol{id=35, value='volatile', code=34}
Symbol{id=36, value='while', code=35}
Symbol{id=1, value='#', code=0}
Symbol{id=2, value='$', code=0}
Symbol{id=3, value='‘', code=0}
Symbol{id=4, value='“', code=0}
Symbol{id=5, value='\', code=0}
Symbol{id=6, value='{', code=0}
Symbol{id=7, value='}', code=0}
Symbol{id=8, value=';', code=0}
Symbol{id=9, value='(', code=0}
Symbol{id=10, value=')', code=0}
Symbol{id=11, value='[', code=0}
Symbol{id=12, value=']', code=0}
Symbol{id=13, value='->', code=0}
Symbol{id=14, value='.', code=0}
Symbol{id=15, value='!', code=0}
Symbol{id=16, value='~', code=0}
Symbol{id=17, value='++', code=0}
Symbol{id=18, value='--', code=0}
Symbol{id=19, value='+', code=0}
Symbol{id=20, value='-', code=0}
Symbol{id=21, value='*', code=0}
Symbol{id=22, value='&', code=0}
Symbol{id=23, value='*', code=0}
Symbol{id=24, value='/', code=0}
Symbol{id=25, value='%', code=0}
Symbol{id=26, value='+', code=0}
Symbol{id=27, value='-', code=0}
Symbol{id=28, value='<<', code=0}
Symbol{id=29, value='>>', code=0}
Symbol{id=30, value='<', code=0}
Symbol{id=31, value='<=', code=0}
Symbol{id=32, value='>', code=0}
Symbol{id=33, value='>=', code=0}
Symbol{id=34, value='==', code=0}
Symbol{id=35, value='!=', code=0}
Symbol{id=36, value='&', code=0}
Symbol{id=37, value='^', code=0}
Symbol{id=38, value='|', code=0}
Symbol{id=39, value='&&', code=0}
Symbol{id=40, value='||', code=0}
Symbol{id=41, value='?', code=0}
Symbol{id=42, value=':', code=0}
Symbol{id=43, value='=', code=0}
Symbol{id=44, value='+=', code=0}
Symbol{id=45, value='-=', code=0}
Symbol{id=46, value='*=', code=0}
Symbol{id=47, value='/=', code=0}
Symbol{id=48, value='%=', code=0}
Symbol{id=49, value='<<=', code=0}
Symbol{id=50, value='>>=', code=0}
Symbol{id=51, value='&=', code=0}
Symbol{id=52, value='^=', code=0}
Symbol{id=53, value='|=', code=0}
Symbol{id=54, value=',', code=0}
词法分析器的状态转移图
C语言的标识符由字母、数字、下划线组成,并且首字母不能是数字(美元符号$也可以作为标识符)
C语言的常量
C语言中的运算符大全(内附优先级表)
代码实现
最后
祝大家逢考必过
点赞收藏关注哦