【编译原理】词法分析器&语法分析器

简单编译器设计

采用Java语言对C++语言进行编译,具体的简单编译器设计

词法分析器-扫描器的设计与实现

基本符号表

在这里插入图片描述

状态转换图

在这里插入图片描述

代码实现


import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class LexicalAnalyzer {
    /**
     * 1表示标识符
     * 2表示常数
     * 3-9表示界符
     * 10-40表示关键字
     * 41-59表示运算符
     * 60表示字符串
     * */
    //关键字
    static String []keyWord={"class","new","static","break","continue","return","do","while","if","else","for","switch","case","default","char","double","float","int","long","short", "string","null","true","false","void","this","goto","endl","cout","cin","main"};
    //运算符
    static String []operation={"+","-","*","-=","*=","/=","<<",">>","==","!=",">","<","=",">=","<=","&&","||","!","."};
    //界符
    static String []symbol={",",";",":","(",")","{","}"};
    //标识符
    public ArrayList<String> identifer=new ArrayList<>();

    public ArrayList<String> keyWords=new ArrayList<>();
    public ArrayList<String> operations=new ArrayList<>();
    public ArrayList<String> symbols=new ArrayList<>();
    //指向当前所读到字符串的位置的指针
    public int p,lines;


    public static void main(String[] args) throws IOException {
        PrintStream oldPrintStream = System.out; //将原来的System.out交给printStream 对象保存
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        System.setOut(new PrintStream(bos)); //设置新的out

        LexicalAnalyzer lexicalAnalyzer = new LexicalAnalyzer();
        lexicalAnalyzer.init();
        File file = new File("C:\\Users\\28362\\Desktop\\收集箱\\编译原理\\put.txt");
        lexicalAnalyzer.lines=1;
        try(Scanner input=new Scanner(file)) {
            while (input.hasNextLine()){
                String str=input.nextLine();
                lexicalAnalyzer.analyze(str);
                lexicalAnalyzer.lines++;
            }
        }
        System.setOut(oldPrintStream);
        System.out.println(bos.toString());
        saveAsFile(bos.toString());
    }

    public void init()
    {
        Collections.addAll(keyWords, keyWord);
        Collections.addAll(operations, operation);
        Collections.addAll(symbols, symbol);
    }

    public void analyze(String str){
        p=0;
        char ch;
        str=str.trim();
        for (;p<str.length();p++){
            ch=str.charAt(p);
            if (Character.isDigit(ch)){
                digitCheck(str);
            }else if (Character.isLetter(ch)||ch=='_'){
                letterCheck(str);
            }
            else if (ch=='"'){
                stringCheck(str);
            }
            else if (ch==' '){
                continue;
            }else {
                symbolCheck(str);
            }
        }
    }

    /**
     * 数字的识别
     * 1、识别退出:
     *   1.1、遇到空格符
     *   1.2、遇到运算符或者界符
     * 2、错误情况:
     *   2.1、两个及以上小数点
     *   2.2、掺杂字母
     **/
    public void digitCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        //判断数字的小数点是否有且是否大于1
        int flag=0;
        boolean err=false;
        char ch;
        for (;p<str.length();p++) {
            ch = str.charAt(p);
            if (ch==' '||(!Character.isLetterOrDigit(ch)&&ch!='.')) {
                break;
            }else if (err){
                token+=ch;
            }
            else {
                token+=ch;
                if (ch == '.') {
                    if (flag == 1) {
                        err = true;
                    } else {
                        flag++;
                    }
                }else if (Character.isLetter(ch)){
                    err=true;
                }
            }
        }
        if (token.charAt(token.length()-1)=='.'){
            err=true;
        }
        if (err){
            System.out.println(lines+"line"+": "+token+" is wrong");
        }else {
//            System.out.println("<"+2+", "+Integer.toBinaryString(Integer.parseInt(token))+">");
            System.out.println(2+", "+Integer.toBinaryString(Integer.parseInt(token)));
        }
        if (p!=str.length()-1||(p==str.length()-1&&!Character.isDigit(str.charAt(p)))){
            p--;
        }
    }

    /**
     * 标识符,关键字的识别
     * 识别退出:
     *      字符不为字母 数字 下划线
     * 识别:字符串是否存在关键字里 不为关键字则为标识符
     * */
    public void letterCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        int num;
        char ch;
        for (;p<str.length();p++){
            ch=str.charAt(p);
            //isLetterOrDigit 确定指定的字符是否为字母或数字
            if (!Character.isLetterOrDigit(ch)&&ch!='_'){
                break;
            }else{
                token+=ch;
            }
        }
        if (keyWords.contains(token)){
            num = keyWords.indexOf(token)+10;
//            System.out.println("<"+num+", "+token+">");
            System.out.println(num+", "+token);
        }else {
            if (!identifer.contains(token))
                identifer.add(token);
            //System.out.println("<"+1+", "+"identifer["+identifer.indexOf(token)+"]"+">");
            System.out.println(1+", "+"identifer["+identifer.indexOf(token)+"]");
        }
        if (p!=str.length()-1||(p==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(p))&&str.charAt(p)!='_'))){
            p--;
        }
    }

    /**
     * 符号识别
     * 识别退出
     *   1、判断是否为界符
     *   2、双目运算符分开也为存在与运算符中
     *   3、单个字符为运算符 则往后继续识别添加一个字符
     */
    public void symbolCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        int num;
        if (symbols.contains(token)){
            num = symbols.indexOf(token) + 3;
//            System.out.println("<"+num+", "+token+">");
            System.out.println(num+", "+token);
            p--;
        }else {
            if (operations.contains(token)){
                if (p<str.length()){
                    ch=str.charAt(p);
                    if (operations.contains(token+ch)){
                        token+=ch;
                        p++;
                        if (p<str.length()){
                            ch=str.charAt(p);
                            if (operations.contains(token+ch)){
                                token+=ch;
                                num = 41+operations.indexOf(token);
//                                System.out.println("<"+num+", "+token+">");
                                System.out.println(num+", "+token);
                            }else{
                                p--;
                                num = 41+operations.indexOf(token);
//                                System.out.println("<"+num+", "+token+">");
                                System.out.println(num+", "+token);
                            }
                        }else{
                            num = 41+operations.indexOf(token);
//                            System.out.println("<"+num+", "+token+">");
                            System.out.println(num+", "+token);
                        }
                    }else {
                        p--;
                        num = 41+operations.indexOf(token);
//                        System.out.println("<"+num+", "+token+">");
                        System.out.println(num+", "+token);
                    }
                }
            }else {
                p--;
                System.out.println(lines+"line"+": "+token+" is wrong");
            }
        }
    }

    /**
     * 字符串检查
     * 识别 “  ”
     */
    public void stringCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        for (;p<str.length();p++){
            ch=str.charAt(p);
            token+=ch;
            if (ch=='"'){
                break;
            }
        }
        if (token.charAt(token.length()-1)!='"'){
            System.out.println(lines+"line"+": "+token+" is wrong");
        }else {
//            System.out.println("<"+60+","+token+">");
            System.out.println(60+","+"strings");
        }
    }

//    public void readLine() throws IOException{
//        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        String str;
//        str = br.readLine();
//        System.out.println(str);
//    }

    public static void saveAsFile(String str)
    {
        String fileName = "C:\\Users\\28362\\Desktop\\收集箱\\编译原理\\out.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(fileName);
            fileWriter.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

语法分析器的设计与实现

文法产生式

S‘:程序(语句的组合)S:语句 Q:else语句 L:标识符表 E:表达式

X:条件表达式 R:比较运算符 id:标识符 num:常量

S' -> S S'|Ɛ

S -> A L;|A main(){S'}|id = E;| id(L); | if(X){S}Q|while(X){S}|Ɛ

A -> int|char|short|long|float|double

Q -> else{S}|Ɛ

L -> id| L,id

X -> ERE

R -> >|>=|<|<=|==|!=

E -> +T|-T|E+T|E-T

T -> F|T*F|T/F

F -> id|num|(E)

提取公共左因子

S' → S S'|Ɛ

S → A A'|id B|if(X){S}Q|while(X){S}|Ɛ

A'→L;|main(){S'}

A → int|char|shor|long|double

B → (L); | =E;

L → id | L , id

Q → else{S} | Ɛ

X → ERE

R → > | >= | < | <= | == | !=

E → +T | -T | T | EM

M → +T | -T

T → F | TN

N → *F |/F

F → id | num | (E)

消除左递归

S’ → S S’
S’ → Ɛ
S → A A'
S → id B
S → if(X){S}Q
S → while(X){S}
S → Ɛ
A'→L;
A'→main(){S'}
B → (L);
B → =E;
L → id L’
L’→ , id L’
L’→ Ɛ
Q → else{S}
Q → Ɛ
X → ERE
E → TE’
E → +TE’
E → -TE’
E’ → ME’
E’ → Ɛ
M → +T
M → -T
T → FT’
T’ → NT’
T’ → Ɛ
N → *F
N → /F
F → id
F → num
F → (E)
R → >
R → >=
R → <
R → <=
R → ==
R → !=
A → char
A → short
A → int
A → long
A → double

求FIRST集

First(S’)={ char , short , int , long , float , double , id , if , while , Ɛ }
First(S)={ char , short , int , long , float , double , id , if , while , Ɛ }
First(A')={ id, main}
First(A)={ char , short , int , long, float  , double }
First(L)={ id }
First(L’)={ ,, Ɛ }
First(Q)={ else , Ɛ }
First(X)={ + , - , id , num , ( }
First(R)={ > , >= , < , <= , != , == }
First(E)={ + , - , id , num , ( }
First(E’)={ + , - , Ɛ }
First(M)={ + , - }
First(T)={ id , num , ( }
First(T’)={ * , / , Ɛ }
First(N)={ * , / }
First(F)={ id , num , ( }

求FOLLOW集

Follow (S’)={ #, } }
Follow (S)={ # , } }
Follow(A)={ id, main}
Follow(A')={# , }}
Follow (L)={ # , ) , ; , } }
Follow (L’)={ # , ) , ; , } }
Follow (Q)={#, } }
Follow (X)={ ) }
Follow (R)={ + , - , id , num , ( }
Follow (E)={ ) , ; , > , >= , < , <= , != , == }
Follow (E’)={ ) , ; , > , >= , < , <= , != , == }
Follow (M)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (T)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (T’)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (N)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }
Follow (F)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }

LL(1)预测分析表中的数字分别代表的产生式如下:

0:S → A A'
1:S → id B
2:S → if(X){P}Q
3:S → while(X){P}
4:S → Ɛ
5:B → (L);
6:B → =E;
7:L → id L’
8:L’→ ,id L’
9:L’→ Ɛ
10:Q → else{S}
11:Q → Ɛ
12:X → ERE
13:E → +TE’
14:E → -TE’
15:E → TE’
16:E’→ ME’
17:E’→ Ɛ
18:M → +T
19:M → -T
20:T → FT’
21:T’→ NT’
22:T’→ Ɛ
23:N → *F
24:N → /F
25:F → id
26:F → num
27:F → (E)
28:R → >
29:R → >=
30:R → <
31:R → <=
32:R → ==
33:R → !=
34:S’ → S S’
35:S’ → Ɛ
36:A → char
37:A → short
38:A → int
39:A → long
40:A → float
41:A → double
42:A'main(){S'}
43:A'→L;
44:S → A A'

预测分析表

在这里插入图片描述

代码实现

package parser;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Parser {
    private static ArrayList<String> stack = new ArrayList<>(); // 当前栈
    private static ArrayList<Integer> reader = new ArrayList<>(); // 待读队列
    private static Production[] productions = new Production[45]; // 产生式数组
    private static HashMap<Integer, String> map_i2s; // 种别码Map,种别码为键,单词为值
    private static HashMap<String, Integer> map_s2i; // 种别码Map,单词为键,种别码为值

    public static void main(String[] args) {
        int stackTop = 1;
        int readerTop = 0;
        int index = 0; // 当前步骤数
        initMap(); // 初始化种别码Map
        initProductions(); // 产生式初始化
        stack.add(0, String.valueOf(map_s2i.get("#"))); // 在stack底部加上#
        stack.add(stackTop, "S'"); // 将S'压入栈
        System.out.print("请输入词法分析结果的文件路径:");
        Scanner scanner = new Scanner(System.in);
        String filepath = scanner.next();
        StringBuffer outputBuffer = new StringBuffer(); // 输出到文件的StringBuffer

        // 通过词法分析器的输出结果,初始化reader
        try {
            readToReader(filepath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        reader.add(map_s2i.get("#")); // 在reader末尾加上#
        while (stackTop >= 0) {
            System.out.printf("%-6s", "第" + ++index + "步:");
            System.out.printf("%-10s", "当前栈:");
            outputBuffer.append("第" + index + "步: 当前栈:");
            StringBuffer sb = new StringBuffer(); // 引入StringBuffer仅为控制在控制台的输出格式对齐

            //获取当前栈的字符 用于显示
            for (int i = 0; i <= stackTop; i++) {
                String str = null;
                try {
                    str = map_i2s.get(Integer.valueOf(stack.get(i)));
                    if (str != null) {
                        sb.append(str + " ");
                        outputBuffer.append(str + " ");
                    }
                } catch (NumberFormatException e) {
                    sb.append(stack.get(i) + " ");
                    outputBuffer.append(stack.get(i) + " ");
                }
            }

            System.out.printf("%-30s", sb.toString());
            System.out.print("待读队列:");
            outputBuffer.append("        待读队列:");
            sb = new StringBuffer();

            //获取当前队列的字符 用于显示
            for (int i = 0; i < reader.size(); i++) {
                sb.append(map_i2s.get(reader.get(i)) + " ");
                outputBuffer.append(map_i2s.get(reader.get(i)) + " ");
            }
            System.out.printf("%-55s", sb.toString());

            //比较栈顶和队底的元素
            if (match(stackTop, readerTop)) {
                stackTop--;
                System.out.print("\n");
                outputBuffer.append("\n");
            } else {
                int i = ll1_table(stackTop, readerTop);
                stackTop += stackPush(stackTop, productions[i]); // 压栈
                System.out.printf("%-30s", "下一步所用产生式:" + productions[i].prod);
                System.out.println();
                outputBuffer.append("         下一步所用产生式:" + productions[i].prod + "\n");
            }
        }


        if (stackTop == -1) {
            System.out.println("语法分析成功");
            outputBuffer.append("Accept");
        }

        System.out.print("请输入语法分析结果文件的保存路径:");
        String outputPath = scanner.next();
        // 将StringBuffer的内容输出到文件
        File outputFile = new File(outputPath);
        if (outputFile.exists()) {
            outputFile.delete();
        }
        PrintWriter writer = null;
        try {
            outputFile.createNewFile();
            writer = new PrintWriter(new FileOutputStream(outputFile));
            writer.write(outputBuffer.toString());
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    /**
     * 读取文件内容,词法分析结果
     * @param filePath
     * @throws IOException
     */
    public static void readToReader(String filePath) throws IOException {
        InputStream is = new FileInputStream(filePath);
        String line; // 用来保存每行读取的内容
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        line = br.readLine(); // 读取第一行
        while (line != null) { // 如果 line 为空说明读完了
            int pos = line.indexOf(",");
            reader.add(Integer.valueOf(line.substring(0, pos)));
            line = br.readLine(); // 读取下一行
        }
        br.close();
        is.close();
    }

    /**
     * 压栈,将对应的文法产生式压入栈
     * @param stackTop
     * @param production
     * @return
     */
    private static int stackPush(int stackTop, Production production) {
        int len = production.r_str.length;
        stack.remove(stackTop);
        if ("ε".equals(production.r_str[0])) {
            }
        else {
            for (int i = len - 1; i >= 0; i--) {
                stack.add(production.r_str[i]);
            }
            return len - 1;
        }
        return -1;
    }

    /**
     * ll(1)预测分析表
     * 通过 栈顶的元素和读入的元素 返回对应的文法产生式
     * @param stackTop
     * @param readerTop
     * @return
     */
    private static int ll1_table(int stackTop, int readerTop) {
        if ("S".equals(stack.get(stackTop))) {
            if ("char".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {
                return 0;
            } else if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 1;
            } else if ("if".equals(map_i2s.get(reader.get(readerTop)))) {
                return 2;
            } else if ("while".equals(map_i2s.get(reader.get(readerTop)))) {
                return 3;
            } else if ("}".equals(map_i2s.get(reader.get(readerTop)))) {
                return 4;
            } else if ("#".equals(map_i2s.get(reader.get(readerTop)))) {
                return 4;
            } else {
                return -1;
            }
        } else if ("B".equals(stack.get(stackTop))) {
            if ("(".equals(map_i2s.get(reader.get(readerTop)))) {
                return 5;
            } else if ("=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 6;
            } else {
                return -1;
            }
        } else if ("L".equals(stack.get(stackTop))) {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 7;
            }
//            else if("main".equals(map_i2s.get(reader.get(readerTop))))
//            {
//                return 42;
//            }
            else {
                return -1;
            }
        } else if ("L'".equals(stack.get(stackTop))) {
            if (";".equals(map_i2s.get(reader.get(readerTop)))) {
                return 9;
            } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {
                return 9;
            } else if ("}".equals(map_i2s.get(reader.get(readerTop)))) {
                return 9;
            } else if ("#".equals(map_i2s.get(reader.get(readerTop)))) {
                return 9;
            } else if (",".equals(map_i2s.get(reader.get(readerTop)))) {
                return 8;
            } else {
                return -1;
            }
        } else if ("Q".equals(stack.get(stackTop))) {
            if ("}".equals(map_i2s.get(reader.get(readerTop)))) {
                return 11;
            } else if ("$".equals(map_i2s.get(reader.get(readerTop)))) {
                return 11;
            } else if ("else".equals(map_i2s.get(reader.get(readerTop)))) {
                return 10;
            } else {
                return -1;
            }
        } else if ("X".equals(stack.get(stackTop))) {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 12;
            } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {
                return 12;
            } else if ("+".equals(map_i2s.get(reader.get(readerTop)))) {
                return 12;
            } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {
                return 12;
            } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {
                return 12;
            } else {
                return -1;
            }
        } else if ("E".equals(stack.get(stackTop))) {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 15;
            } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {
                return 15;
            } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {
                return 15;
            } else if ("+".equals(map_i2s.get(reader.get(readerTop)))) {
                return 13;
            } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {
                return 14;
            } else {
                return -1;
            }
        } else if ("E'".equals(stack.get(stackTop))) {
            if ("+".equals(map_i2s.get(reader.get(readerTop)))) {
                return 16;
            } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {
                return 16;
            } else if (">".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if ("<".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if (";".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {
                return 17;
            } else {
                return -1;
            }
        } else if ("M".equals(stack.get(stackTop))) {
            if ("+".equals(map_i2s.get(reader.get(readerTop)))) {
                return 18;
            } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {
                return 19;
            } else {
                return -1;
            }
        } else if ("T".equals(stack.get(stackTop))) {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 20;
            } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {
                return 20;
            } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {
                return 20;
            }
        } else if ("T'".equals(stack.get(stackTop))) {
            if ("+".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("-".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("*".equals(map_i2s.get(reader.get(readerTop)))) {
                return 21;
            } else if ("/".equals(map_i2s.get(reader.get(readerTop)))) {
                return 21;
            } else if (">".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("<".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if (";".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else if (")".equals(map_i2s.get(reader.get(readerTop)))) {
                return 22;
            } else {
                return -1;
            }
        } else if ("N".equals(stack.get(stackTop))) {
            if ("*".equals(map_i2s.get(reader.get(readerTop)))) {
                return 23;
            } else if ("/".equals(map_i2s.get(reader.get(readerTop)))) {
                return 24;
            } else {
                return -1;
            }
        } else if ("F".equals(stack.get(stackTop))) {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 25;
            } else if ("num".equals(map_i2s.get(reader.get(readerTop)))) {
                return 26;
            } else if ("(".equals(map_i2s.get(reader.get(readerTop)))) {
                return 27;
            } else {
                return -1;
            }
        } else if ("R".equals(stack.get(stackTop))) {
            if (">".equals(map_i2s.get(reader.get(readerTop)))) {
                return 28;
            } else if (">=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 29;
            } else if ("<".equals(map_i2s.get(reader.get(readerTop)))) {
                return 30;
            } else if ("<=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 31;
            } else if ("==".equals(map_i2s.get(reader.get(readerTop)))) {
                return 32;
            } else if ("!=".equals(map_i2s.get(reader.get(readerTop)))) {
                return 33;
            } else {
                return -1;
            }
        } else if ("S'".equals(stack.get(stackTop))) {
            if ("char".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("if".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("while".equals(map_i2s.get(reader.get(readerTop)))) {
                return 34;
            } else if ("#".equals(map_i2s.get(reader.get(readerTop)))) {
                return 35;
            }
            else if ("}".equals(map_i2s.get(reader.get(readerTop)))) {
                return 35;
            }else {
                return -1;
            }
        } else if ("A".equals(stack.get(stackTop))) {
            if ("char".equals(map_i2s.get(reader.get(readerTop)))) {
                return 36;
            } else if ("short".equals(map_i2s.get(reader.get(readerTop)))) {
                return 37;
            } else if ("int".equals(map_i2s.get(reader.get(readerTop)))) {
                return 38;
            } else if ("long".equals(map_i2s.get(reader.get(readerTop)))) {
                return 39;
            } else if ("float".equals(map_i2s.get(reader.get(readerTop)))) {
                return 40;
            } else if ("double".equals(map_i2s.get(reader.get(readerTop)))) {
                return 41;
            } else if("id".equals(map_i2s.get(reader.get(readerTop)))){
                return 43;
            }else {
                return -1;
            }
        }else if("A'".equals(stack.get(stackTop)))
        {
            if ("id".equals(map_i2s.get(reader.get(readerTop)))) {
                return 43;
            } else if ("main".equals(map_i2s.get(reader.get(readerTop)))) {
                return 42;
            } else{
                return -1;
            }
        } else {
            System.out.println("语法错误");
        }
        return -1;
    }

    /**
     * 比较栈里面的符号
     * @param stackTop
     * @param readerTop
     * @return
     */
    private static boolean match(int stackTop, int readerTop) {
        try {
            int stackTopVal = Integer.valueOf(stack.get(stackTop)); // 未抛出异常说明是终结符
            if (stackTopVal == reader.get(0)) {
                stack.remove(stackTop);
                reader.remove(readerTop);
                return true;
            } else {
                return false;
            }
        } catch (NumberFormatException e) {
            // 抛出异常说明是非终结符
            return false;
        }
    }

    /**
     * 初始化产生式
     */
    private static void initProductions() {
        productions[0] = new Production("S",
                new String[]{"A", "A'"},
                "S --> AA'");
        productions[1] = new Production("S",
                new String[]{String.valueOf(map_s2i.get("id")), "B"},
                "S --> id B");
        productions[2] = new Production("S",
                new String[]{String.valueOf(map_s2i.get("if")), String.valueOf(map_s2i.get("(")), "X", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}")), "Q"},
                "S --> if(X){S}Q");
        productions[3] = new Production("S",
                new String[]{String.valueOf(map_s2i.get("while")), String.valueOf(map_s2i.get("(")), "X", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}"))},
                "S --> while(X){S}");
        productions[4] = new Production("S",
                new String[]{"ε"},
                "S --> ε");
        productions[5] = new Production("B",
                new String[]{String.valueOf(map_s2i.get("(")), "L", String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get(";"))},
                "B --> (L);");
        productions[6] = new Production("B",
                new String[]{String.valueOf(map_s2i.get("=")), "E", String.valueOf(map_s2i.get(";"))},
                "B --> =E;");
        productions[7] = new Production("L",
                new String[]{String.valueOf(map_s2i.get("id")), "L'"},
                "L --> id L'");
        productions[8] = new Production("L'",
                new String[]{String.valueOf(map_s2i.get(",")), String.valueOf(map_s2i.get("id")), "L'"},
                "L' --> ,id L'");
        productions[9] = new Production("L'",
                new String[]{"ε"},
                "L' --> ε");
        productions[10] = new Production("Q",
                new String[]{String.valueOf(map_s2i.get("else")), String.valueOf(map_s2i.get("{")), "S", String.valueOf(map_s2i.get("}"))},
                "Q --> else{S}");
        productions[11] = new Production("Q",
                new String[]{"ε"},
                "Q --> ε");
        productions[12] = new Production("X",
                new String[]{"E", "R", "E"},
                "X --> ERE");
        productions[13] = new Production("E",
                new String[]{String.valueOf(map_s2i.get("+")), "T", "E'"},
                "E --> +TE'");
        productions[14] = new Production("E",
                new String[]{String.valueOf(map_s2i.get("-")), "T", "E'"},
                "E --> -TE'");
        productions[15] = new Production("E",
                new String[]{"T", "E'"},
                "E --> TE'");
        productions[16] = new Production("E'",
                new String[]{"M", "E'"},
                "E' --> ME'");
        productions[17] = new Production("E'",
                new String[]{"ε"},
                "E' --> ε");
        productions[18] = new Production("M",
                new String[]{String.valueOf(map_s2i.get("+")), "T"},
                "M --> +T");
        productions[19] = new Production("M",
                new String[]{String.valueOf(map_s2i.get("-")), "T"},
                "M --> -T");
        productions[20] = new Production("T",
                new String[]{"F", "T'"},
                "T --> FT'");
        productions[21] = new Production("T'",
                new String[]{"N", "T'"},
                "T' --> NT'");
        productions[22] = new Production("T'",
                new String[]{"ε"},
                "T' --> ε");
        productions[23] = new Production("N",
                new String[]{String.valueOf(map_s2i.get("*")), "F"},
                "N --> *F");
        productions[24] = new Production("N",
                new String[]{String.valueOf(map_s2i.get("/")), "F"},
                "N --> /F");
        productions[25] = new Production("F",
                new String[]{String.valueOf(map_s2i.get("id"))},
                "F --> id");
        productions[26] = new Production("F",
                new String[]{String.valueOf(map_s2i.get("num"))},
                "F --> num");
        productions[27] = new Production("F",
                new String[]{String.valueOf(map_s2i.get("(")), "E", String.valueOf(map_s2i.get(")"))},
                "F --> (E)");
        productions[28] = new Production("R",
                new String[]{String.valueOf(map_s2i.get(">"))},
                "R --> >");
        productions[29] = new Production("R",
                new String[]{String.valueOf(map_s2i.get(">="))},
                "R --> >=");
        productions[30] = new Production("R",
                new String[]{String.valueOf(map_s2i.get("<"))},
                "R --> <");
        productions[31] = new Production("R",
                new String[]{String.valueOf(map_s2i.get("<="))},
                "R --> <=");
        productions[32] = new Production("R",
                new String[]{String.valueOf(map_s2i.get("=="))},
                "R --> ==");
        productions[33] = new Production("R",
                new String[]{String.valueOf(map_s2i.get("!="))},
                "R --> !=");
        productions[34] = new Production("S'",
                new String[]{"S", "S'"},
                "S' --> SS'");
        productions[35] = new Production("S'",
                new String[]{"ε"},
                "S' --> ε");
        productions[36] = new Production("A",
                new String[]{String.valueOf(map_s2i.get("char"))},
                "A --> char");
        productions[37] = new Production("A",
                new String[]{String.valueOf(map_s2i.get("short"))},
                "A --> short");
        productions[38] = new Production("A",
                new String[]{String.valueOf(map_s2i.get("int"))},
                "A --> int");
        productions[39] = new Production("A",
                new String[]{String.valueOf(map_s2i.get("long"))},
                "A --> long");
        productions[40] = new Production("A'",
                new String[]{String.valueOf(map_s2i.get("float"))},
                "A --> float");
        productions[41] = new Production("A",
                new String[]{String.valueOf(map_s2i.get("double"))},
                "A --> double");
        productions[42] = new Production("A'",
                new String[]{String.valueOf(map_s2i.get("main")),String.valueOf(map_s2i.get("(")),String.valueOf(map_s2i.get(")")), String.valueOf(map_s2i.get("{")), "S'", String.valueOf(map_s2i.get("}"))},
                "A' --> main(){S'}");
        productions[43] = new Production("A'",
                new String[]{"L", String.valueOf(map_s2i.get(";"))},
                "A' --> L;");
        productions[44] = new Production("S",
                new String[]{"A","A'"},
                "S --> AA'");
    }

    /**
     * 存储符号表,散列表
     */
    private static void initMap(){
        //HashMap 散列表
        map_s2i = new HashMap<>();
        map_s2i.put("id",1);//标识符
        map_s2i.put("num",2);//常数
        map_s2i.put(",",3);
        map_s2i.put(";",4);
        map_s2i.put(":",5);
        map_s2i.put("(",6);
        map_s2i.put(")",7);
        map_s2i.put("{",8);
        map_s2i.put("}",9);
        map_s2i.put("class",10);
        map_s2i.put("new",11);
        map_s2i.put("static",12);
        map_s2i.put("break",13);
        map_s2i.put("continue",14);
        map_s2i.put("return",15);
        map_s2i.put("do",16);
        map_s2i.put("while",17);
        map_s2i.put("if",18);
        map_s2i.put("else",19);
        map_s2i.put("for",20);
        map_s2i.put("switch",21);
        map_s2i.put("case",22);
        map_s2i.put("default",23);
        map_s2i.put("char",24);
        map_s2i.put("double",25);
        map_s2i.put("float",26);
        map_s2i.put("int",27);
        map_s2i.put("long",28);
        map_s2i.put("short",29);
        map_s2i.put("string",30);
        map_s2i.put("null",31);
        map_s2i.put("true",32);
        map_s2i.put("false",33);
        map_s2i.put("void",34);
        map_s2i.put("this",35);
        map_s2i.put("goto",36);
        map_s2i.put("endl",37);
        map_s2i.put("cout",38);
        map_s2i.put("cin",39);
        map_s2i.put("main",40);
        map_s2i.put("+",41);
        map_s2i.put("-",42);
        map_s2i.put("*",43);
        map_s2i.put("-=",44);
        map_s2i.put("*=",45);
        map_s2i.put("/=",46);
        map_s2i.put("<<",47);
        map_s2i.put(">>",48);
        map_s2i.put("==",49);
        map_s2i.put("!=",50);
        map_s2i.put(">",51);
        map_s2i.put("<",52);
        map_s2i.put("=",53);
        map_s2i.put(">=",54);
        map_s2i.put("<=",55);
        map_s2i.put("&&",56);
        map_s2i.put("||",56);
        map_s2i.put("!",58);
        map_s2i.put(".",59);
        map_s2i.put("strings",60);//字符串
        map_s2i.put("#",61);

        map_i2s = new HashMap<>();
        map_i2s.put(1,"id");//标识符
        map_i2s.put(2,"num");//常数
        map_i2s.put(3,",");
        map_i2s.put(4,";");
        map_i2s.put(5,":");
        map_i2s.put(6,"(");
        map_i2s.put(7,")");
        map_i2s.put(8,"{");
        map_i2s.put(9,"}");
        map_i2s.put(10,"class");
        map_i2s.put(11,"new");
        map_i2s.put(12,"static");
        map_i2s.put(13,"break");
        map_i2s.put(14,"continue");
        map_i2s.put(15,"return");
        map_i2s.put(16,"do");
        map_i2s.put(17,"while");
        map_i2s.put(18,"if");
        map_i2s.put(19,"else");
        map_i2s.put(20,"for");
        map_i2s.put(21,"switch");
        map_i2s.put(22,"case");
        map_i2s.put(23,"default");
        map_i2s.put(24,"char");
        map_i2s.put(25,"double");
        map_i2s.put(26,"float");
        map_i2s.put(27,"int");
        map_i2s.put(28,"long");
        map_i2s.put(29,"short");
        map_i2s.put(30,"string");
        map_i2s.put(31,"null");
        map_i2s.put(32,"true");
        map_i2s.put(33,"false");
        map_i2s.put(34,"void");
        map_i2s.put(35,"this");
        map_i2s.put(36,"goto");
        map_i2s.put(37,"endl");
        map_i2s.put(38,"cout");
        map_i2s.put(39,"cin");
        map_i2s.put(40,"main");
        map_i2s.put(41,"+");
        map_i2s.put(42,"-");
        map_i2s.put(43,"*");
        map_i2s.put(44,"-=");
        map_i2s.put(45,"*=");
        map_i2s.put(46,"/=");
        map_i2s.put(47,"<<");
        map_i2s.put(48,">>");
        map_i2s.put(49,"==");
        map_i2s.put(50,"!=");
        map_i2s.put(51,">");
        map_i2s.put(52,"<");
        map_i2s.put(53,"=");
        map_i2s.put(54,">=");
        map_i2s.put(55,"<=");
        map_i2s.put(56,"&&");
        map_i2s.put(57,"||");
        map_i2s.put(58,"!");
        map_i2s.put(59,".");
        map_i2s.put(60,"strings");//字符串
        map_i2s.put(61,"#");
    }

    /**
     * 定义产生式
     */
    private static class Production {
        String l_str;//
        String[] r_str;
        String prod;
        public Production(String l_str, String[] r_str, String prod) {
            this.l_str = l_str;
            this.r_str = r_str;
            this.prod = prod;
        }
    }

}


  • 2
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值