一.实验目的
1.掌握LL(1)分析法的基本原理
2.掌握LL(1)分析表的构造方法
3.掌握LL(1)驱动程序的构造方法
4.加深对LL(1)分析法的理解
二.实验内容及要求
已知某LL(1)文法包含的产生式(其中E为开始符)及产生式相应的SELECT集如下表:
(这里直接给出了各产生式的SELECT集,相当于给出了预测分析表)
产生式 | 该产生式对应的SELECT集 |
---|---|
(1)E→ TM | {(, i} |
(2)M→ +TM | {+} |
(3)M→ ε | {), #} |
(4)T→ FN | { (, i} |
(5)N→ *FN | {*} |
(6)N→ ε | {+, ), #} |
(7)F→ (E) | {( } |
(8)F→ i | {i} |
本次实验要求根据该文法编制一个LL(1)分析程序,以便对任意输入的符号串进行分析。要求所编制的LL(1)分析程序输出的格式如下:
(1) LL(1)分析程序,编制人:姓名,学号,班级
(2) 输入一以#结束的符号串(可包括+*()i#等符号,如i+i#):在此位置输入符号串
(3) 对该输入串的LL(1)分析过程输出如下:0
步骤 | 栈 | 剩余输入串 | 所用产生式 |
---|---|---|---|
1 | E | i+i# | (1) |
2 | … | … | … |
(4) 判定结果:输入符号串为合法符号串(或者为非法符号串)。
注意:(1)在“所用产生式”一列中如果对应有推导则写出所用产生式编号;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“出错”;若成功结束则写为“成功”。
(2) 在此位置输入符号串为用户自行输入的符号串,其中允许使用运算符(+、*)、分割符(括号)、字符i,结束符#;如:i+i#。
(3) 如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。
三.实验过程
在这里粘贴出了最核心部分的代码,在此实验的过程中要知晓栈的基本概念,以及词法分析表的书写。其中也包括了输入非法的处理情况。
import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
import java.text.MessageFormat;
import java.util.Scanner;
import java.util.Stack;
public class Complier {
static String[] strings= new String[]{"E","T","M","F","N"};
static String[] strings1 = new String[]{"(","i","+",")","*","#"};
static String[][] table = new String[5][6];
static String input = null;
static Stack stack = null;
static Stack stacks = null;
public Complier()//对内容进行初始化
{
stacks = new Stack();//分析栈
stacks.push('#');//结束符
stacks.push('E');//开始符
table[0][0] = "TM";
table[0][1] = "TM";
table[1][0] = "FN";
table[1][1] = "FN";
table[2][2] = "+TM";
table[2][3] = "ε";
table[2][5] = "ε";
table[3][0] = "(E)";
table[3][1] = "i";
table[4][2] = "ε";
table[4][3] = "ε";
table[4][4] = "*FN";
table[4][5] = "ε";
}
public boolean input()//执行输入操作,判定输入是否合法
{
System.out.println("请输入以#结尾的字符串:");
Scanner scanner = new Scanner(System.in);
input = scanner.nextLine();
int length = input.length();
for(int i =0;i<length;i++)
{
if(input.charAt(i)!='('&&input.charAt(i)!='i'&&input.charAt(i)!='+'&&input.charAt(i)!=')'&&input.charAt(i)!='*'&&input.charAt(i)!='#')
{
return false;
}
}
return true;
}
public void setStack()//对栈进行操作
{
stack = new Stack();//剩余输出串的栈
for(int i=input.length()-1;i>=0;i--) {
stack.push(input.charAt(i));//将输入串压入栈
}
}
public void analyse()//分析的函数
{
System.out.format("%-8s%-8s%-8s%-8s\n","步骤","分析栈","剩余输入串","所用产生式");
int num = 0;
while (!stack.empty())//输入串的栈不为空
{
num++;
if(stack.peek()==stacks.peek())//匹配的情况下
{
System.out.format("%-8d %-9s %-9s \"%s\"匹配\n",num,printStack(stacks),printStacks(stack),stacks.peek());
stack.pop();
stacks.pop();
}
else
{
int row = selectRow(String.valueOf(stacks.peek()));
int column = selectColumn(String.valueOf(stack.peek()));
String temp = table[row][column];
// System.out.println(row+" "+column);
if(temp!=null)
{
if(temp=="ε")
{
System.out.format("%-8d %-9s %-9s %s->%s\n",num,printStack(stacks),printStacks(stack),stacks.peek(),temp);
stacks.pop();
}
else
{
System.out.format("%-8d %-9s %-9s %s->%s\n",num,printStack(stacks),printStacks(stack),stacks.peek(),temp);
stacks.pop();
for(int i=temp.length()-1;i>=0;i--)
{
stacks.push(temp.charAt(i));//将输入串压入栈
}
}
}
else
{
System.out.println("--------------------------------------------------");
System.out.println("在第"+num+"步遇到无法匹配的字符串,出错");
break;
}
}
}
if(!stacks.empty())
{
System.out.println("--------------------------------------------------");
System.out.println("发现异常错误,在第"+num+"步后检测到无结束符#");
}
else
{
System.out.println("-----------------------------------------------");
System.out.println("分析完成如上所示");
}
}
public int selectRow(String s1)//查找属于哪一行,stacks
{
for(int i =0;i<strings.length;i++)
{
if(s1.equals(strings[i]))
{
return i;
}
}
return 0;
}
public int selectColumn(String s1)//查找所属的哪一列
{
for(int i =0;i<strings1.length;i++)
{
if(s1.equals(strings1[i]))
{
return i;
}
}
return 0;
}
public String printStack(Stack stack)//输出栈中的内容
{
String something = "";
while(!stack.empty())
{
something+=stack.pop();
}
for(int i=something.length()-1;i>=0;i--)
{
stack.push(something.charAt(i));
}
StringBuffer stringBuffer = new StringBuffer(something);
something = stringBuffer.reverse().toString();
return something;
}
public String printStacks(Stack stack)//输出栈中的内容
{
String something = "";
while(!stack.empty())
{
something+=stack.pop();
}
for(int i=something.length()-1;i>=0;i--)
{
stack.push(something.charAt(i));
}
return something;
}
public static void main(String[] args) {
Complier complier = new Complier();
if(complier.input())
{
complier.setStack();//装填栈
complier.analyse();//分析函数
}
else
{
System.out.println("输入不合法");
}
}
}
运行结果截图:
ier();
if(complier.input())
{
complier.setStack();//装填栈
complier.analyse();//分析函数
}
else
{
System.out.println(“输入不合法”);
}
}
}
运行结果截图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/78557f439e0c41108666f2e569caae2c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zu25oia,size_18,color_FFFFFF,t_70,g_se,x_16#pic_center)