imagemlt / ImagemltLex

编译原理实验 词法分析器lex

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ImagemltLex

实验1 词法分析器lex

实验目的:

  • Scanner生成器:根据lex文件生成对应的状态转换图,生成扫描器Scanner.java

  • Scanner.java: 根据输入的程序串,输出对应的token序列。

实现的思路:

  • 正则表达式转NFA,NFA转换为DFA,DFA化简后生成状态转移表。

一个案例

  • 输入的lex文件:

  • ( \(
    ) \)
    ASS =
    ; ;
    { {
    } }
    COMMA ,
    IF if
    ELSE else
    RETURN return
    TYPE (int)|(float)|(boolean)
    ID [a-zA-Z][a-zA-Z0-9]*
    DIGITS \d+
    arithmetic_op \+|-|\*|/
    logical_op (&&)|(==)|(\|\|)|([&|><])
    %%
    	private HashSet<Character> symbols=new HashSet<>(
    		Arrays.asList(new Character[]{
    			'(',')',',','=','+','-','*','/',';','{','}','&','|','>','<'
    		})
    	);
    	private String[] matchTable={"(,%s","),%s","ASS,%s",";,%s","{,%s","},%s","COMMA,%s","IF,%s","ELSE,%s","RETURN,%s","TYPE,%s","ID,%s","DIGITS,%s","arithmetic_op,%s","logical_op,%s",};
    
    %%
     public static void main(String args[]){
                try {
                    Scanner scanner=new Scanner(true);
                    Vector<Pair<Integer,String>> tokens=scanner.Scan(new FileReader("/tmp/Source.c"));
                    BufferedWriter writer=new BufferedWriter(new FileWriter("/tmp/tokens"));
                    for(Pair<Integer,String>token:tokens){
                        writer.write(String.format(scanner.matchTable[scanner.stateIds[token.getKey()]],token.getValue())+"\n");
                    }
                    writer.flush();
                    writer.close();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
    
    
    • 运行java -jar ImagemltLex.jar /tmp/lex /tmp/Scannner.java生成的Scanner如下:
  • import javafx.util.Pair;
    
    import java.io.BufferedReader;
    import java.io.*;
    import java.util.*;
    
    
    public class Scanner {
        public enum STATUS {
            START,
            END,
            NORMAL,
            BOTH
        };
    STATUS[] status={
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.START,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    	STATUS.END,
    };
    int[] stateIds={
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	11,
    	12,
    	8,
    	9,
    	6,
    	14,
    	14,
    	14,
    	13,
    	-1,
    	10,
    	1,
    	2,
    	0,
    	4,
    	7,
    	5,
    	3,
    };
    int[][] transitionTable={
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,34,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,20,20,20,20,20,20,20,20,20,20,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,-1,32,30,27,27,23,27,-1,27,20,20,20,20,20,20,20,20,20,20,-1,36,24,31,24,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,1,0,0,10,6,0,0,16,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,33,25,35,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},
    };
    int start=28;
    	private HashSet<Character> symbols=new HashSet<>(
    		Arrays.asList(new Character[]{
    			'(',')',',','=','+','-','*','/',';','{','}','&','|','>','<'
    		})
    	);
    	private String[] matchTable={"(,%s","),%s","ASS,%s",";,%s","{,%s","},%s","COMMA,%s","IF,%s","ELSE,%s","RETURN,%s","TYPE,%s","ID,%s","DIGITS,%s","arithmetic_op,%s","logical_op,%s",};
    
       public Vector<Pair<Integer,String>> Scan(String example) throws Exception{
           int begin=0,end=0;
           Vector<Pair<Integer,String>> ans=new Vector<>();
           if(example.length()==0)return ans;
           while(true){
               String subPattern="";
               int state=-1;
    
               if(symbols.contains(example.charAt(begin))){
                   end=begin;
                   while(end<example.length()&&symbols.contains(example.charAt(end))) {
                       end=end+1;
                       subPattern=example.substring(begin,end);
                       int cuState=match(subPattern);
                       if(cuState!=-1){
                           state=cuState;
                       }
                       else{
                           end--;
                           subPattern=subPattern.substring(0,subPattern.length()-1);
                           break;
                       }
                   }
                   if(state==-1)
                       throw new Exception("invalid token '"+subPattern+"'");
    
               }
               else if(begin<example.length() && (example.charAt(begin)==' ' || example.charAt(begin)=='\t')){
                   while(begin<example.length() && (example.charAt(begin)==' ' || example.charAt(begin)=='\t'))begin++;
                   if(begin==example.length())break;
                   end=begin-1;
                   continue;
               }
               else {
                   for (end = begin; end < example.length() && (example.charAt(end) != ' ' || example.charAt(begin)=='\t') && !symbols.contains(example.charAt(end)); end++);
                   subPattern=example.substring(begin,end);
                   state=match(subPattern);
                   if(state==-1)
                       throw new Exception("invalid token '"+subPattern+"'");
               }
               if(state!=-1) {
                   ans.add(new Pair<Integer, String>(state,subPattern));
                   if (debug)
                       System.out.printf(matchTable[stateIds[state]] + "\t%s\n", subPattern, subPattern);
               }
               if(end==example.length()){
                   break;
               }
               if(symbols.contains(example.charAt(end)) ||symbols.contains(example.charAt(begin)))begin=end;
               else begin=end+1;
    
           }
           return ans;
        }
    
    
    
        public Vector<Pair<Integer,String>> Scan(Reader reader) throws Exception{
            BufferedReader bufferedReader=new BufferedReader(reader);
            Vector<Pair<Integer,String>>ans=new Vector<>();
            String line=null;
            while((line=bufferedReader.readLine())!=null){
                Vector<Pair<Integer,String>> tmp=Scan(line);
                ans.addAll(tmp);
            }
            return ans;
        }
    
        public Vector<Pair<Integer,String>> Scan(InputStream stream) throws Exception{
            return Scan(new InputStreamReader(stream));
        }
    private int match(String input){
            Pair<Integer,Integer> tmp;
            boolean end=false;
            Integer matchState=-1;
            Stack<Pair<Integer,Integer>> matchStack=new Stack<>();
    
            Integer nextMatch=transitionTable[this.start][(int)input.charAt(0)];
            if(nextMatch!=-1){
                matchStack.push(new Pair<Integer,Integer>(nextMatch,1));
            }
    
            while(!matchStack.empty()){
                tmp=matchStack.pop();
                /*if(tmp.getKey().getStatus()== State.STATUS.BOTH || tmp.getKey().getStatus()== State.STATUS.END){
                    end=true;
                }*/
                if(tmp.getValue()==input.length()){
                    if(status[tmp.getKey()]==STATUS.BOTH || status[tmp.getKey()]== STATUS.END){
                        matchState=tmp.getKey();
                        break;
                    }
                }
                else {
                    char nextChar = input.charAt(tmp.getValue());
                    nextMatch=transitionTable[tmp.getKey()][(int)nextChar];
                    if(nextMatch!=-1){
                        matchStack.push(new Pair<Integer, Integer>(nextMatch,tmp.getValue()+1));
                    }
                }
    
            }
            return matchState;
        }
    private boolean debug=false;
        public Scanner(boolean debug) {
            this.debug=debug;
        }
     public static void main(String args[]){
                try {
                    Scanner scanner=new Scanner(true);
                    Vector<Pair<Integer,String>> tokens=scanner.Scan(new FileReader("/tmp/Source.c"));
                    BufferedWriter writer=new BufferedWriter(new FileWriter("/tmp/tokens"));
                    for(Pair<Integer,String>token:tokens){
                        writer.write(String.format(scanner.matchTable[scanner.stateIds[token.getKey()]],token.getValue())+"\n");
                    }
                    writer.flush();
                    writer.close();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
    
    }
    • 该scanner读取/tmp/Source.c文件的内容,并把读取到的token序列输出到/tmp/tokens文件中。
    • 运行javac Scanner.java,java Scanner后得到的token序列/tmp/tokens:
  • TYPE,float
    ID,func
    (,(
    TYPE,int
    ID,m
    COMMA,,
    TYPE,int
    ID,n
    ),)
    {,{
    RETURN,return
    ID,m
    arithmetic_op,+
    ID,n
    ;,;
    },}
    TYPE,int
    ID,main
    (,(
    ),)
    {,{
    TYPE,int
    ID,a
    COMMA,,
    ID,b
    ;,;
    ID,a
    ASS,=
    DIGITS,0
    ;,;
    IF,if
    (,(
    ID,a
    logical_op,>
    DIGITS,0
    ),)
    {,{
    ID,a
    ASS,=
    ID,func
    (,(
    ID,a
    COMMA,,
    ID,b
    ),)
    ;,;
    },}
    ELSE,else
    {,{
    ID,a
    ASS,=
    DIGITS,5
    ;,;
    },}
    RETURN,return
    DIGITS,1
    ;,;
    },}
    
    

    核心算法描述:

    • 项目的结构

      • DFA类:描述DFA
      • NFA类:描述NFA
      • Edge类:自动机中的每一个转换
      • State类:自动机中的每一个状态
      • io包中的两个类主要用于读取lex文件并提取正则表达式、输出Scanner的代码
    • 相关算法

      • class NFA

        • public static NFA Reg2NFA(String regExp)

          • 将正则表达式转换为对应的NFA
          • 使用栈(Stack)来辅助匹配括号、匹配|
        • public void star()

          • 表示NFA的*运算
        • public void or(NFA nfa2)

          • 表示对A|B的运算
        • public void cat(NFA nfa2)

          • 表示AB的运算
        • public void keepEnd_or(NFA nfa2)

          • 保持结束符的A|B运算
      • class DFA

        • public HashSet<State> getClosure(State state)
          • 获取某个状态的闭包
        • public HashSet<State> getTransClosure(HashSet<State> state,Character character)
          • 获取转移闭包函数
        • private HashSet<State> move(State state,Character c,Vector<HashSet<State>> vect)
          • move函数 DFA简化中使用
        • public HashMap<HashSet<State>, HashMap<Character,HashSet<State>>> getTransitionTable(NFA nfa)
          • 根据NFA生成DFA状态转换表,实现NFA转DFA的主要函数
        • public DFA(NFA nfa)
          • 构造函数,将NFA转化为对应的DFA
        • public void simplization()
          • DFA简化算法
      • 生成的Scanner

        • public Vector<Pair<Integer,String>> Scan(String example) throws Exception

          • 根据转换表进行扫描的函数实现,且加入了错误处理,当某个token不能被识别时将会抛出异常。

程序开发中遇到的一些问题以及解决方法

  • 运行效率低的问题:
    • 加入了几个用于标记的HashMap,从而避免了一些重复运算
    • HashSet的应用将许多细节算法的复杂度由$$O(n)$$ 降低到了$$O(log(n))$$ ,最开始的一版在处理某个比较长的正则时需要10分钟,优化后只需要不到1分钟。

感受:

  • RE转NFA转化DFA再最小化是难度最高的一个实现方式,在实现这个算法中巩固了词法分析方面的知识,并且巩固了java编程的一些技巧,以及java中的集合类的应用。

About

编译原理实验 词法分析器lex


Languages

Language:Java 100.0%