语法分析器是编译原理的一个实验,本文将会详细给出实现的具体步骤,利用java进行示例讲解,完整源码可在 https://download.csdn.net/download/qq_40121502/10926525 下载。

一、实验目的

设计、编写一个语法分析程序,加深对语法分析原理的理解。

二、实验原理

语法分析器是在词法分析之后,根据词法分析的结果和定义的语法规则判断输入的程序是否有语法错误,LL(1)分析是使用显式栈而不是递归调用来完成分析。以标准方式表示这个栈非常有用,这样LL(1)分析程序的动作就可以快捷地显现出来。LL(1)的含义是:第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式(规则)进行推导。

三、实验内容

(1)程序利用Java语言,给出其词法的产生式。希望这个语言中包含数学运算表达式,赋值,函数调用,控制流语句(分支或循环),类型声明等基本元素。
(2)本实验设计的是基于LL(1) 分析的语法分析器,并用程序实现了对所写语言的LL(1) 分析测试。

四、实验方法

(1)定义文法语言,将文法用产生式表示。
(2)提取公共左因子,消除左递归。
(3)求FIRST和FOLLOW集。
(4)构造LL(1)预测分析表。
(5)根据分析表编写程序,测试程序。

五、实验设计

1.定义语法分析使用的文法语言:

<程序> ::= <语句><程序> | Ɛ;
<语句> ::= <变量定义语句> | <赋值语句> | <函数调用语句> | <if语句>
| <循环语句> | Ɛ
<变量定义语句> ::= <变量类型><标识符表>;
<赋值语句> ::= <标识符> = <表达式>;
<函数调用语句> ::= <标识符> ( <标识符表> );
<if语句> ::= if ( <条件表达式> ) { <语句> } <else语句>
<else语句> ::= else{ <语句> } | Ɛ
<循环语句> ::= while ( <条件表达式> ) { <语句> }
<标识符表> ::= <标识符>| <标识符表>,<标识符>
<条件表达式> ::= <表达式><比较运算符><表达式>
<比较运算符> ::= > | >= | < | <= | != | ==
<变量类型> ::= char | short | int | long | float | double
<表达式> ::= +T | -T | T | <表达式> + T | <表达式>-T
T ::= F | T*F | T/F
F ::= <标识符> | <无符号整数> | (<表达式 >)

2.将上述文法用产生式表示:

其中,S’:程序(语句的组合),S:语句,Q:else语句,L:标识符表,E:表达式,X:条件表达式,R:比较运算符,id:标识符,num:常量
S’ → S S’| Ɛ
S → A L; | id=E; | id(L); | if(X){S}Q | while(X){S} | Ɛ
A → char | short | int | long | float | double
Q → else{S} | Ɛ
L → id | L , id
X → ERE
R → > | >= | < | <= | == | !=
E → +T | -T | T | E+T | E-T
T → F | T*F | T/F
F → id | num | (E)

3.提取公共左因子:

S’ → S S’| Ɛ
S → A L; | id B | if(X){S}Q | while(X){S} | Ɛ
A → char | short | int | long | float | 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)

4.消除左递归:

S’ → S S’
S’ → Ɛ
S → A L;
S → id B
S → if(X){S}Q
S → while(X){S}
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 → float
A → double

5.求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)={ char , short , int , long , float , double }
First(B)={ ( , = }
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 , ( }

6.求FOLLOW集:

Follow (S’)={ $ }
Follow (S)={ $ , } }
Follow (B)={ $ , } }
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)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }

7.构造LL(1)的预测分析表:


LL(1)预测分析表中的数字分别代表的产生式如下:
0:S → A L;
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

六、数据结构

(1)使用ArrayList来存储当前栈的内容
(2)使用ArrayList来存储待读队列的内容,Integer此处为单词的种别码,用于表示词法分析器的分析结果。
自定义类Production,产生式类,包含String类型的完整产生式、String类型的产生式左侧符号、String[]类型的产生式右侧符号。(此处左右是相对于产生式中的→而言的)。

七、实现代码

语法分析器接收词法分析器的结果作为输入,即输入为单词种别码和相应的单词的序列。
例如:(种别码和单词间的逗号仅表示分隔)

1.初始化

首先定义了五个全局变量:

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

初始化种别码Map,要和词法分析器内单词对应的种别码相同:

private static void initMap() {map_s2i = new HashMap<>();map_s2i.put("char", 1);map_s2i.put("short", 2);map_s2i.put("int", 3);map_s2i.put("long", 4);map_s2i.put("float", 5);map_s2i.put("double", 6);map_s2i.put("final", 7);map_s2i.put("static", 8);map_s2i.put("if", 9);map_s2i.put("else", 10);map_s2i.put("while", 11);map_s2i.put("do", 12);map_s2i.put("for", 13);map_s2i.put("break", 14);map_s2i.put("continue", 15);map_s2i.put("void", 16);map_s2i.put("id", 20);map_s2i.put("num", 30);map_s2i.put("=", 31);map_s2i.put("==", 32);map_s2i.put(">", 33);map_s2i.put("<", 34);map_s2i.put(">=", 35);map_s2i.put("<=", 36);map_s2i.put("+", 37);map_s2i.put("-", 38);map_s2i.put("*", 39);map_s2i.put("/", 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("$", 60);map_i2s = new HashMap<>();map_i2s.put(1, "char");map_i2s.put(2, "short");map_i2s.put(3, "int");map_i2s.put(4, "long");map_i2s.put(5, "float");map_i2s.put(6, "double");map_i2s.put(7, "final");map_i2s.put(8, "static");map_i2s.put(9, "if");map_i2s.put(10, "else");map_i2s.put(11, "while");map_i2s.put(12, "do");map_i2s.put(13, "for");map_i2s.put(14, "break");map_i2s.put(15, "continue");map_i2s.put(16, "void");map_i2s.put(20, "id");map_i2s.put(30, "num");map_i2s.put(31, "=");map_i2s.put(32, "==");map_i2s.put(33, ">");map_i2s.put(34, "<");map_i2s.put(35, ">=");map_i2s.put(36, "<=");map_i2s.put(37, "+");map_i2s.put(38, "-");map_i2s.put(39, "*");map_i2s.put(40, "/");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(60, "$");
}

初始化产生式:规则自己定义

/*** 产生式类*/
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;}
}private static void initProductions() {productions[0] = new Production("S",new String[]{"A", "L", String.valueOf(map_s2i.get(";"))},"S --> A L;");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");
}

main()函数的部分:

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'压入栈

2.读入词法分析结果

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末尾加上$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();
}

注意到我们在stack和reader末尾都添加了,当两者的,当两者的,当两者的匹配时表示语法分析结束。

3.语法分析

语法分析的输出需要描述分析的过程,每一步分析需要列出当前栈、待读队列、下一步所用产生式。
示例输出如下:

语法分析的步骤是:
1.输出当前栈的内容:从栈内依次取出栈顶符号,判断该符号是种别码还是字符,若为种别码,需将其对应转换成单词,若转换时抛出NumberFormatException,则说明是字符。将结果放入输出的buffer中。
注意,此处引入StringBuffer sb仅为控制在控制台的输出格式对齐。
2.输出待读队列:遍历输出reader的内容。
3.将reader队列第一个和stack当前栈栈顶元素进行匹配。若相同,说明是同一个终结符;若不同,则根据LL(1)预测分析表预测下一步推导所用产生式。

main()函数部分:

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");
}

检测reader头部和stack顶部是否匹配,返回匹配结果

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;}
}

利用LL(1)预测分析表进行分析,返回单词种别码。

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 {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 {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 {return -1;}} else {System.out.println("语法错误");}return -1;
}

4.输出结果到文件

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();}
}

八、运行结果

输入词法分析器的代码块:

词法分析器结果:


语法分析结果:

……

至此,语法分析器编写完成。如有问题,欢迎交流指正。


2019-10-16补充stackPush方法:

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;
}

语法分析器实现过程(java)相关推荐

  1. Java实现LL1语法分析器

    实验内容要求 一.实验目的 加深对语法分析器工作过程的理解:加强对预测分析法实现语法分析程序的掌握:能够 采用一种编程语言实现简单的语法分析程序:能够使用自己编写的分析程序对简单的程序段 进行语法翻译 ...

  2. java语言生成语法分析_语法分析器自动生成工具一览

    最近打算重做以前的一个留下遗憾的工作,当中的一项小任务就是要求编写一个简易SQL语言的语法分析器. 本科的<编译原理>课程依稀在我脑中留下些许映象.当初的课程大作业是写一个叫Dicuf(貌 ...

  3. java实现语法分析器_200 行 JS 代码,带你实现代码编译器

    一.前言 对于前端同学来说,编译器可能适合神奇的魔盒 ,表面普通,但常常给我们惊喜. 编译器,顾名思义,用来编译,编译什么呢?当然是编译代码咯 . 其实我们也经常接触到编译器的使用场景: React ...

  4. 编译原理实验:Java实现SLR(1)语法分析器

    首先如果有熟悉Python的童鞋也可以看一看Python实现SLR(1)语法分析器,编译原理yyds!__FF_Y的博客-CSDN博客_python语法分析器,是我一个特别好的学长写的,这波属于传承了 ...

  5. 基于Java语言的语法分析器

    LR(0)语法分析器 实验目的: 根据LR(0)语法分析的原理,编写.调试一个语法分析代码程序,对输入的句子进行分析. 实验工具: 使用了Java语言进行编写 ,使用Java开发工具IntelliJ ...

  6. 编译原理实验-LL1语法分析器(自动生成First集、Follow集求法)java实现

    编译原理实验-LL1语法分析器(自动生成First.Follow)java 博主在做实验时,参考众多他人代码,发现bug众多,在@moni_mm代码基础上,与伙伴把能看到的BUG都做出修正,同时增添了 ...

  7. java实现语法分析器_语法分析 | 语法分析的任务

    在之前,我们有对编译器做过一定的介绍,我们认为编译器是具有一定流水线结构的软件系统.它可以分为前端,中端和后端这样的不同的阶段. 编译器前端 对于我们正在研究的前端,我们已经通过词法分析的学习掌握了从 ...

  8. 语法分析器 Java版

    想了解更多内容,移步至编译原理专栏 ==========================2021.12.22 更新=================================== 整理了一下代码 ...

  9. java编译器源码分析之语法分析器

    token流到抽象语法树的过程是语法分析. 前面认识到token流,这部分将介绍抽象语法树(AST). 那么什么是抽象语法树(AST)?AST长啥样?我们的token流是如何转变成AST的?下面围绕这 ...

  10. 算符优先文法编写java语法分析器,编译原理课程设计实验报告——基于算符优先分析方法的表达式语法分析器...

    内容简介: 一.设计目的 了解用算符优先法对表达进行语法分析的方法,掌握自顶向下的预测语法分析程序的手工构造方法. 二.设计内容 对简单表达式文法构造算符优先分析器. 三.设计要求 1.对下列简单表达 ...

最新文章

  1. LeetCode Flatten Binary Tree to Linked List (dfs)
  2. [YTU]_2637(编程题:类---矩形类)
  3. Sprint2-2.0
  4. leetcode 476. Number Complement | 476. 数字的补数(位运算)
  5. linux和windows输入法设置,关于输入法框架,这里有可以跨平台的linux和windows。。。。...
  6. AngularJS $watch 性能杀手
  7. 每个人都在谈论硒替代品-明智地选择!
  8. python中递归函数写法_python递归函数用法详解
  9. [渝粤教育] 东南大学 工程热力学 参考 资料
  10. 去除对象中的类型集合
  11. Spring 为啥默认把bean设计成单例的?这篇讲的明明白白的
  12. 12月15日学习内容整理:ORM中的queryset类型,中介模型,extra函数和分组补充
  13. 全面分析RHCE7(红帽认证工程师)考试题目之 ----NFS文件共享 篇
  14. SQL2005安装及链接
  15. xp精简版安装iis
  16. 使用OpenCV探测来至运动的结构
  17. R语言使用epiDisplay包的lroc函数可视化logistic回归模型的ROC曲线并输出诊断表、输出灵敏度、1-特异度、AUC值等、设置auc.coords参数指定AUC值在可视化图像中的位置
  18. 星际争霸2的移动机制-初探
  19. 怒江java培训班_Graal VM:微服务时代的Java
  20. 疯狂的“元宇宙”炒房:有玩家囤了100套房,不到半年翻6倍

热门文章

  1. 全国省份简称(备用)
  2. 腾讯笔试题:纸牌游戏
  3. 手机射频功放指标介绍
  4. 网易邮箱大师使用排雷
  5. 转 Unity知识点0001(Yanlz+协程+List+MeshRender+对象池+链条关节+PlayerPrefs+脚本生命周期+LOD+)
  6. EasyDarwin云平台:EasyCamera开源摄像机接入海康威视摄像机PS流转ES流
  7. 龙芯2F安装NetBSD
  8. 安装Solidworks 2018出现可执行文件未成功安装的解决方法 PreReqs\VCRedist10\vcredist_x86.exe
  9. 第五人格显示服务器维护中请稍后登录怎么办,第五人格维护登不上怎么办 服务器维护中详情...
  10. 这篇文章告诉你PDF转WORD免费软件有哪些?