实验目的
1)理解LR(0)分析的原理;
2)掌握LR(0)分析识别符号串的方法;
3)掌握LR(0)分析表的运用;
4)能够编写程序实现LR(0)语法分析;
实验要求:
1)理解和掌握LR(0)文法的判断和分析过程。
2)本实验要求设计一个LR(0)语法分析程序。
3)本实验要求自己独立完成,不允许抄袭别人的实验结果。
4)用C#或JAVA语言实现;
实验报告以及实验程序的提交:
1)在实验任务截止时间以前将实验程序和实验报告的word文档打包上传超星网络教学平台。
2)每个同学的文件压缩包命名为:学号_姓名_5.rar
3)压缩包中应包含两个文件夹,一个存放程序,另一个存放实验报告的word文件。
实验内容:
1.设计LR(0)语法分析程序。
选择课本P136的文法和P136的LR(0)分析表
2.应用设计的分析程序对输入串bccd#进行一次LR(0)分析,并输出分析过程和结果(如P137的表6.4所示)
检验分析程序的正确性。
设计要求:
(1)为了方便文法的输入,将产生式中的“->”可以由“:”
(2)对于非终结符和终结符可以用一维数组VN[100]和VT[100]存储,对于文法G[S]可以由二维数组G[100][100]存储,对于LR(1)的动作表和转换表分别由ACTION和GOTO数组表示。
(3)LR(0)分析表为课本P136的表6.3。
主要分析流程如下:
置ip指向输入串w的第一个符号
令S为栈顶状态
a是ip指向的符号
重复 begin
if ACTION[S,a]=Sj
then
begin PUSH j,a(进栈)
ip 前进(指向下一输入符号)
end
else
if ACTION[S,a]=rj (用第j条产生式归约A->e)
then
begin
按产生式|e|的长度,
将对应的符号和状态出栈
令当前栈顶状态为S’
push GOTO[S’,A]和A(进栈)
end
else
if ACTION[s,a]=acc
then
return (成功)
else
error
end.
重复
public class Main {
//非终结符
private static final String[] vn = new String[]{"S\\'", "A", "B", "E"};
//终结符
private static final String[] vt = new String[]{"a", "b", "c", "d", "#"};
//状态栈
private static final Stack<String> state = new Stack();
//符号栈
private static final Stack<String> symbol = new Stack();
//输入栈
private static final Stack<Character> input = new Stack();
//文法
private static final List<String> grammar = new ArrayList<>();
private static final HashMap<String, String> grammarMap = new HashMap<>();
//分析表
private static final HashMap<String, HashMap<String, String>> analysisTable = new HashMap<>();
//初始化数据
public static void initData() {
grammar.add("S\\':E");
grammar.add("E:aA");
grammar.add("E:bB");
grammar.add("A:cA");
grammar.add("A:d");
grammar.add("B:cB");
grammar.add("B:d");
HashMap<String, String> zero = new HashMap<>() {
{
put("a", "S2");
put("b", "S3");
put("c", "null");
put("d", "null");
put("#", "null");
put("E", "1");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> one = new HashMap<>() {
{
put("a", "null");
put("b", "null");
put("c", "null");
put("d", "null");
put("#", "acc");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> two = new HashMap<>() {
{
put("a", "null");
put("b", "null");
put("c", "S4");
put("d", "S10");
put("#", "null");
put("E", "null");
put("A", "6");
put("B", "null");
}
};
HashMap<String, String> three = new HashMap<>() {
{
put("a", "null");
put("b", "null");
put("c", "S5");
put("d", "S11");
put("#", "null");
put("E", "null");
put("A", "null");
put("B", "7");
}
};
HashMap<String, String> four = new HashMap<>() {
{
put("a", "null");
put("b", "null");
put("c", "S4");
put("d", "S10");
put("#", "null");
put("E", "null");
put("A", "8");
put("B", "null");
}
};
HashMap<String, String> five = new HashMap<>() {
{
put("a", "null");
put("b", "null");
put("c", "S5");
put("d", "S11");
put("#", "null");
put("E", "null");
put("A", "null");
put("B", "9");
}
};
HashMap<String, String> six = new HashMap<>() {
{
put("a", "r1");
put("b", "r1");
put("c", "r1");
put("d", "r1");
put("#", "r1");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> seven = new HashMap<>() {
{
put("a", "r2");
put("b", "r2");
put("c", "r2");
put("d", "r2");
put("#", "r2");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> eight = new HashMap<>() {
{
put("a", "r3");
put("b", "r3");
put("c", "r3");
put("d", "r3");
put("#", "r3");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> nine = new HashMap<>() {
{
put("a", "r5");
put("b", "r5");
put("c", "r5");
put("d", "r5");
put("#", "r5");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> ten = new HashMap<>() {
{
put("a", "r4");
put("b", "r4");
put("c", "r4");
put("d", "r4");
put("#", "r4");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
HashMap<String, String> eleven = new HashMap<>() {
{
put("a", "r6");
put("b", "r6");
put("c", "r6");
put("d", "r6");
put("#", "r6");
put("E", "null");
put("A", "null");
put("B", "null");
}
};
analysisTable.put("0", zero);
analysisTable.put("1", one);
analysisTable.put("2", two);
analysisTable.put("3", three);
analysisTable.put("4", four);
analysisTable.put("5", five);
analysisTable.put("6", six);
analysisTable.put("7", seven);
analysisTable.put("8", eight);
analysisTable.put("9", nine);
analysisTable.put("10", ten);
analysisTable.put("11", eleven);
}
public static void main(String[] args) {
initData();
String content = "";
Scanner scanner = new Scanner(System.in);
ArrayList<Character> characters = new ArrayList<>();
while (true) {
symbol.clear();
state.clear();
symbol.push("#");
state.push("0");
System.out.println("请输入需要分析的字符串(请不要包含空格,请以#结尾):");
content = scanner.nextLine();
characters.clear();
for (int i = 0; i < content.length(); i++) {
characters.add(content.charAt(i));
}
input.clear();
for (int i = characters.size() - 1; i >= 0; i--) {
input.push(content.charAt(i));
}
if (inputIsLegal()) {
System.out.println(String.format("%-10s", "步骤") + String.format("%-10s", "状态栈") + String.format("%-10s", "符号栈") + String.format("%-10s", "输入串") + String.format("%-10s", "ACTION") + String.format("%-10s", "GOTO"));
analysisContent();
} else {
System.out.println("输入非法!!!!");
}
}
}
static public void analysisContent() {
Character temp = 'Q';
String temp3 = "";
String result = "";
String stateString = "";
int steps = 0;
while (true) {
//输入栈 栈顶元素
steps++;
temp = input.peek();
//输入串栈顶元素
temp3 = String.valueOf(temp);
//栈顶状态
stateString = state.peek();
result = analysisTable.get(stateString).get(temp3);
if (result.equals("null")) {
showResult(steps, "报错", "报错");
break;
}
//使用action 移进
else if (result.contains("S")) {
showResult(steps, result, "");
state.push(result.substring(1));
symbol.push(temp3);
input.pop();
continue;
}
//使用goto
else if (result.replaceAll("%d", "").length() == 0) {
continue;
} else if (result.equals("acc")) {
if (symbol.size() == 2 && input.size() == 1) {
showResult(steps, result, "");
break;
}
continue;
}
//规约
else if (result.contains("r")) {
String tempGrammar = grammar.get(Integer.parseInt(result.substring(1)));
String[] tempArray = tempGrammar.split(":");
Stack<String> tempState = new Stack<>();
Stack<String> tempSymbol = new Stack<>();
for (int i = 0; i < state.size(); i++) {
tempState.push(state.get(i));
}
for (int i = 0; i < symbol.size(); i++) {
tempSymbol.push(symbol.get(i));
}
for (int i = 0; i < tempArray[1].length(); i++) {
tempState.pop();
tempSymbol.pop();
}
stateString = tempState.peek();
String gotoResult = analysisTable.get(stateString).get(tempArray[0]);
showResult(steps, result, gotoResult);
tempSymbol.push(tempArray[0]);
tempState.push(gotoResult);
state.clear();
symbol.clear();
for (int i = 0; i < tempState.size(); i++) {
state.push(tempState.get(i));
}
for (int i = 0; i < tempSymbol.size(); i++) {
symbol.add(tempSymbol.get(i));
}
continue;
} else {
continue;
}
}
}
static public void showResult(int steps, String action, String goTo) {
System.out.println();
String id = steps + "";
id = String.format("%-10s", id);
System.out.print(id);
browseState();
browseAnalysis();
browseInput();
System.out.print(String.format("%-10s", action));
System.out.print(String.format("%-10s", goTo));
System.out.println();
}
static public void browseAnalysis() {
String analysisStr = "";
for (int i = 0; i < symbol.size(); i++) {
analysisStr = analysisStr + symbol.get(i) + "";
}
analysisStr = String.format("%-10s", analysisStr);
System.out.print(analysisStr);
System.out.print(" ");
}
static public void browseState() {
String stateStr = "";
for (int i = 0; i < state.size(); i++) {
stateStr = stateStr + state.get(i) + "";
}
stateStr = String.format("%-10s", stateStr);
System.out.print(stateStr);
System.out.print(" ");
}
static public void browseInput() {
String inputStr = "";
for (int i = 0; i < input.size(); i++) {
inputStr = inputStr + input.get(input.size() - i - 1) + "";
}
inputStr = String.format("%-10s", inputStr);
System.out.print(inputStr);
System.out.print(" ");
}
static public boolean inputIsLegal() {
boolean flag = false;
int num = 0;
for (Character character : input) {
num++;
for (String s : vt) {
if (String.valueOf(character).equals(s)) {
flag = true;
}
}
if (!flag) {
return flag;
}
if (num == input.size()) {
return flag;
} else {
flag = false;
}
}
return false;
}
}