本贴完全原创
根据《编译原理》何炎祥第三版第六章语法分析器实现
原理:简单优先分析算法
语言:Java若需要查看算符优先算法,请进入主页查看https://blog.csdn.net/qq_24065713/article/details/71375421
MainMethod.java
public class MainMethod {
public String jie="";
public String k = " ";
int s = 1;
public String jieguo = "步骤"+" "+"符号栈"+" "+"关系"+" "+"输入串"+" "+"操作"+"\n\n";
public boolean accept(StringBuffer stack1,StringBuffer stack2){
boolean result ;
outer:
while (true) {
char c1 = stack1.charAt(stack1.length() - 1);//符号栈倒数第一个字符
char c2 = stack2.charAt(0);//输入串第一个字符
char c3 = stack1.charAt(stack1.length() - 2);//符号栈倒数第二个字符
if (c1=='S'&&c2=='$'&&c3=='$') {//判断是简单优先算法的条件
jie = "OK";
return true;
}
switch (c1) {//根据符号栈最后一位字符判断是什么操作
case '$':
if (DaXiao(c1, c2) == -1) {//比较c1,c2的优先级,根据优先级判断操作方式
stack1.append(c2);//移进操作
stack2.deleteCharAt(0);//删除原输入串第一位字符
jieguo = jieguo+s++;//计数,拼接字符串方式
jieguo = jieguo +k+stack1 + k+"</="+k+stack2+k+"移进"+"\n";//结果用字符串拼接方式显示
} else {//$优先级最小,所以不可能出现其他情况
result = false;
jie = jie + "$无法匹配";
break outer;
}
break;
case '(':
if (DaXiao(c1, c2) == 0 || DaXiao(c1, c2) == -1) {
stack1.append(c2);
stack2.deleteCharAt(0);
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+"</="+k+stack2+k+"移进"+"\n";
} else {
result = false;
jie = jie + "(无法匹配";
break outer;
}
break;
case 'a':
if (DaXiao(c1, c2) == 1) {
stack1.deleteCharAt(stack1.length() - 1);
stack1.append('S');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"S->a"+"\n";
}else {
result = false;
jie = jie + "a无法匹配";
break outer;
}
break;
case 'S':
if (DaXiao(c1, c2) == 1) {
stack1.deleteCharAt(stack1.length() - 1);
stack1.append('T');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"T->S"+"\n";
} else if (DaXiao(c1, c2) == 0) {
stack1.append(c2);
stack2.deleteCharAt(0);
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+"</="+k+stack2+k+"移进"+"\n";
} else {
result = false;
jie = jie + "S无法匹配";
break outer;
}
break;
case 'T':
if (DaXiao(c1, c2) == 1) {
if (DaXiao(c3, c1) == -1||DaXiao(c3, c1) == 10)//由于T可能有两种产生情况,所以要另外判断句柄
{
stack1.deleteCharAt(stack1.length() - 1);
stack1.append('R');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"R->T"+"\n";
}
else if (DaXiao(c3, c1) ==0||DaXiao(c3, c1) ==1)//由于T可能有两种产生情况,所以要另外判断句柄,
{
stack1.deleteCharAt(stack1.length()-1);
stack1.deleteCharAt(stack1.length()-1);
stack1.deleteCharAt(stack1.length()-1);
stack1.append('T');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"T->S,T"+"\n";
} else {
result = false;
jie = jie + "T无法匹配";
break outer;
}
} else {
result = false;
jie = jie + "T无法匹配";
break outer;
}
break;
case 'R':
if (DaXiao(c1, c2) == 0) {
stack1.append(c2);
stack2.deleteCharAt(0);
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" = "+k+stack2+k+"移进"+"\n";
} else {
result = false;
jie = jie + "R无法匹配";
break outer;
}
break;
case ')':
if (DaXiao(c1, c2) == 1) {
if (DaXiao(c3, c1) != -1)//由于T可能有两种产生情况,所以要另外判断句柄,
{
stack1.deleteCharAt(stack1.length()-1);
stack1.deleteCharAt(stack1.length()-1);
stack1.deleteCharAt(stack1.length()-1);
stack1.append('S');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"S->(R)"+"\n";
}
}
else {
result = false;
jie = jie + ")无法匹配";
break outer;
}
break;
case ',':
if (DaXiao(c1, c2) == 0 || DaXiao(c1, c2) == -1) {
stack1.append(c2);
stack2.deleteCharAt(0);
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+"</="+k+stack2+k+"移进"+"\n";
} else {
result = false;
jie = jie + ",无法匹配";
break outer;
}
break;
case '^':
if (DaXiao(c1, c2) == 1) {
stack1.deleteCharAt(stack1.length() - 1);
stack1.append('S');
jieguo = jieguo+s++;
jieguo = jieguo +k+stack1 + k+" > "+k+stack2+k+"S-a"+"\n";
}else {
result = false;
jie = jie + "^无法匹配";
break outer;
}
break;
default:
jie = jie +"输入非法字符";
return false;
}
}
return result;
}
public int DaXiao(char c1,char c2){
if(c1=='$') return -1;//$
else if(c1 == 'S'&&c2 ==',')return 0;//S
else if (c1 == 'S'&& (c2==')'||c2 == '$'))return 1;
else if(c1=='R'&&c2 ==')')return 0;
else if(c1=='R'&&c2 =='$')return 1;
else if (c1=='T'&&(c2 == ')'||c2 == '$')) return 1;//T
else if (c1 == 'a' &&(c2=='a'||c2 == ')'||c2 == '$'))return 1;//a
else if (c1 == '^' &&(c2=='a'||c2 == ')'||c2 == '$'))return 1;//^
else if (c1 == ',' &&(c2=='S'||c2 == 'a'||c2 == '^'||c2 == '('))return -1;//,
else if (c1 == ',' &&c2=='T')return 0;
else if (c1 == ',' &&c2=='$')return 1;
else if (c1 == '(' &&(c2=='S'||c2 == 'T'||c2 == 'a'||c2 == '^'||c2 == '('))return -1;//(
else if (c1 == '(' &&c2=='R')return 0;
else if (c1 == '(' &&c2=='$')return 1;
else if (c1 == ')' &&(c2==','||c2 == ')'||c2 == '$'))return 1;//)
else return 10;//不存在关系
}
}
WaiKe.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* Created by 吴为 on 2017/4/24.
*/
public class WaiKe {//GUI
public WaiKe(){
JFrame jFrame = new JFrame("简单优先分析算法");
JPanel jPanel = new JPanel();
JButton jButton = new JButton("开始分析");
TextArea textArea = new TextArea();
JTextField jTextField1 = new JTextField("待 输 入 文 法");
JTextField jTextField2 = new JFormattedTextField(" ");
TextArea textArea1 = new TextArea();
textArea1.setText(" | R S T a ^ , ( )\n" +
"---------------------------------------------------------------------------\n" +
"R| =\n" +
"S| = >\n" +
"T| >\n" +
"a| > >\n" +
"^| > >\n" +
",| < = < < < \n" +
"(| = < < < < < \n" +
")| > >");
jFrame.setVisible(true);
jFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
jFrame.setLayout(null);
jPanel.setLayout(null);
jFrame.setBounds(100,100,500,800);
jPanel.setBounds(0,0,500,800);
textArea.setBounds(0,300,500,500);
textArea1.setBounds(0,100,500,300);
jButton.setBounds(175,50,100,30);
jTextField1.setBounds(50,50,100,30);
jTextField2.setBounds(300,50,100,30);
jFrame.add(jPanel);
jPanel.add(jTextField1);
jPanel.add(jButton);
jPanel.add(jTextField2);
jPanel.add(textArea);
jPanel.add(textArea1);
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String wenFa = jTextField1.getText();
StringBuffer stringBuffer1 = new StringBuffer(" $");
StringBuffer stringBuffer2 = new StringBuffer(wenFa);
MainMethod m= new MainMethod();
m.accept(stringBuffer1,stringBuffer2);
jTextField2.setText(m.jie);
textArea.setText(m.jieguo);
}
});
}
}
Test.java
/**
* Created by 吴为 on 2017/4/24.
*/
public class Test {//主方法
public static void main(String []args){
new WaiKe();
}
}