简单编译器设计
采用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;
}
}
}