首页 > 编程学习 > 实验一 词法分析器+【编译原理】

实验一 词法分析器+【编译原理】

发布时间:2023/4/8 4:34:16

实验一 词法分析器+【编译原理】

  • 前言
  • 推荐
  • 实验一 词法分析器+
    • 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         $
345         \
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语言中的运算符大全(内附优先级表)

代码实现

最后

祝大家逢考必过
点赞收藏关注哦

Copyright © 2010-2022 mfbz.cn 版权所有 |关于我们| 联系方式|豫ICP备15888888号