LL1分析器

import java.util.ArrayList;
//lsh
import java.util.Scanner;

/**
 *题目:LL(1)分析过程模拟
 * time:4月22日
 * 功能:
 * 1、适应对满足LL(1)某一文法的输入串分析
 * 2、适应输入串中插入空格
 * 3、有简单的错误提示
 *假定文法如下:
 * E→TE’
 * E’→+TE’︱ε
 * T→FT’
 * T’→*FT’︱ε
 * F→(E)︱i
 */
public class LL1Analysis {
   public static void main(String a[])
   {
    int id=1;
    int index1=1;//记录栈最后一个非终结符的位置
    String topStack,topIn,operation;
    StringBuffer inString=null;
    ArrayList list = new ArrayList();
    System.out.println("请输入一个语句:");
    Scanner in = new Scanner(System.in);
    String ins=in.nextLine().trim();
    if(ins.indexOf("#")<0)//假如最后完了输入#号也没事
     ins+="#";
    else
     ins=ins.substring(0,ins.indexOf("#")+1);//截取#号在内的前部
    inString = new StringBuffer(ins);
    int kong=inString.indexOf(" ");
    while(kong>=0)//去掉输入串表达式中的空格
    {
     inString.delete(kong,kong+1);
     kong=inString.indexOf(" ");
    }
    StringBuffer stack=new StringBuffer("#E");//分析栈,初始放入E
    String ll[][]={{"","i","+","*","(",")","#"},
      {"E","E’T/P","","","E’T/P","",""},
      {"E’","","E’T/N","","","ε/P","ε/P"},
      {"T","T’F/P","","","T’F/P","",""},
      {"T’","","ε/P","T’F/N","","ε/P","ε/P"},
      {"F","ε/N","","",")E/N","",""},
      {")","","","","","ε/N",""},
      {"#","","","","","","acc"}
    };//ll(1)分析矩阵
    System.out.println("LL(1)分析过程如下:");
    System.out.println("/n序号/t分析栈"+getBlank(20)+" 输入数据"+getBlank(20)+"动作");
    StringBuffer liutemp = null;
    while(stack.length()>0)
    {
     int x=0,y=0;//记录在分析表中的的横纵坐标
     if(stack.toString().endsWith("/'")||stack.toString().endsWith("’"))//证明是带了一撇的非终结符
      index1 = stack.length()-2;//
     else
      index1=stack.length()-1;
     topStack=String.valueOf(stack.substring(index1,stack.length()));//栈顶元素
     if(inString.length()>0)
         topIn=String.valueOf(inString.charAt(0));//剩余输入串的第一个元素
     else
      topIn="";
     for(int i=1;i       if(topStack.equals(ll[i][0]))
      {
       x=i;
       break;
      }
     for(int i=1;i       if(topIn.equals(ll[0][i]))
      { 
       y=i;
       break;
      }
     operation=ll[x][y];//动作命令
     if(operation.length()>=3)
     {
      String first=operation.substring(0,operation.length()-2);//替换部分
      String last=operation.substring(operation.length()-2,operation.length());//是否换行部分
      if(first.equals("ε"))//如果是空字符,有不要加入栈
       first="";
      if(operation.equals("acc"))
      {
      if(stack.length()==1&&inString.length()==1)
      {
       System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+getBlank(11-operation.length())+operation);
          stack.delete(0,1);
          inString.delete(0,1);
       System.out.println("匹配成功!");
      }
      else
      {
       System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+getBlank(6)+"error");
       System.out.println("不能完整匹配!");
      }
      }
      else if(last.equals("/P"))
      {
       System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+getBlank(11-operation.length())+operation);
       stack.replace(index1,index1+topStack.length(),first);//把栈顶元素替换为分析表中值
       if(first.equals(""))
        list.add(ll[x][0]+"->ε");
       else{
        liutemp = new StringBuffer(first);
        list.add(ll[x][0]+"->"+reverse(liutemp));
       }
       id++;
      }else if(last.equals("/N"))
      {
       System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+getBlank(11-operation.length())+operation);
       stack.replace(index1,index1+topStack.length(),first);
       inString.delete(0,1);//相当于读下一个元素
       liutemp = new StringBuffer(first);
       list.add(ll[x][0]+"->"+topIn+reverse(liutemp));
       if(stack.toString().endsWith("/'")||stack.toString().endsWith("’"))
        index1 = stack.length()-2;//重新设置index1值
       else
        index1=stack.length()-1;
       id++;
      }else {
       System.out.println("分析表构造出错!");
       System.exit(0);
      }
     }else if(y==0){
      System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+getBlank(6)+"error");
      System.out.println("输入的符号不符合规定文法!");
      System.exit(0);
     }else if(x!=0&&y!=0&&operation.length()==0)
     {
      System.out.println(id+"/t"+stack+getBlank(21-stack.length()-inString.length())+inString+inString+getBlank(6)+"error");
      System.out.println("输入符号串不完整!");
      System.exit(0);
     }
    }
    System.out.println("/n该语句自顶向下构建语法树过程:");
    for(int i = 0;i      System.out.println(list.get(i));
   }
   public static StringBuffer reverse(StringBuffer buffer){//字母、运算符倒置
    StringBuffer buf = new StringBuffer();
    int ix=-1;
    int length=0;
    if(buffer.indexOf("'")<0&&buffer.indexOf("’")<0)
     buf.append(buffer.reverse());
    else{
     while(buffer.length()>0){
      length = buffer.length();
      if(buffer.charAt(length-1)=='/''||buffer.charAt(length-1)=='’')
      {
       buf.append(buffer.substring(length-2,length));
       buffer.delete(length-2,length);
      }else {
       buf.append(buffer.charAt(length-1));
       buffer.delete(length-1,length);
      }
     }
    }
    return buf;
   }
   public static String getBlank(int n){//得到n个连续空格
  String blank="";
  for(int i=0;i    blank+=" ";
  return blank;
 }
}
 

你可能感兴趣的:(LL1分析器)