编译原理实验LL(1)文法

一.实验目的

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

步骤剩余输入串所用产生式
1Ei+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)

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值