/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hit.core; import java.io.*; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author songmingye */ public class Syntax {//句法分析核心类 public void Syntax_Analysis(ArrayList<Token> token_list){//句法分析核心函数 if(derived_strings.empty()){ explaination = "结束"; }else{ String top_ofinput;//输入缓冲区首字符 if(token_list.isEmpty()){ top_ofinput = "$"; }else{ Token t = token_list.get(0); top_ofinput = Token_Code[t.code]; } String top_ofstack = derived_strings.peek(); if(isTerminal(top_ofstack)){ //推导符号串栈顶为终结符 if(top_ofinput.equals(top_ofstack)){//匹配相约 token_list.remove(0); derived_strings.pop(); explaination = "终结符归约"; }else{ derived_strings.pop();//不匹配弹出栈顶的终结符 explaination = "错误:栈顶终结符与输入符号不匹配"; } }else if(isUnterminal(top_ofstack)){ //栈顶为非终结符 //System.out.println(top_ofstack); if(!(predict_map.get(top_ofstack).containsKey(top_ofinput))){//(栈顶非终结符——输入元素)项为空 if(!token_list.isEmpty()){ token_list.remove(0); explaination = "错误:忽略输入符号"+top_ofinput; }else{ derived_strings.pop(); explaination = "错误:弹出栈顶元素"; } }else{ Production production = predict_map.get(top_ofstack).get(top_ofinput); if(production.num==-1){//同步记号 derived_strings.pop(); explaination = "错误:同步记号,弹出栈顶非终结符"; }else{ derived_strings.pop(); for(int i=production.right.size()-1;i>=0;i--){ String sp = production.right.get(i); //System.out.println(sp); if(!"<NULL>".equals(sp)){ derived_strings.push(sp); } } explaination = production.left+"->"; for(String s : production.right){ explaination += s; } } } } } } public void create_list(){try { //构造基础表 FileReader fr=new FileReader("/Users/songmingye/Documents/compiler/Syntax/Song_Syntax/Syntax_rule.txt");//文法文件地址请根据自己的系统更换 BufferedReader br=new BufferedReader(fr); String s; while((s = br.readLine())!=null){ String b1[] = s.split("->"); Production p = new Production(production_list.size()); p.left = b1[0]; String b2[] = b1[1].split("@"); for(String sp : b2){ p.right.add(sp); if(Character.isLowerCase(sp.charAt(1))){//非终结符小写 if(!isUnterminal(sp)){ Unterminal_Symbol new_unterminal = new Unterminal_Symbol(sp); unterminal_list.add(new_unterminal); } }else{ if(!"<NULL>".equals(sp)){ if(!isTerminal(sp)){ Terminal_Symbol new_terminal = new Terminal_Symbol(sp); terminal_list.add(new_terminal); } } } } production_list.add(p); if(!isUnterminal(b1[0])){ Unterminal_Symbol new_unterminal = new Unterminal_Symbol(b1[0]); unterminal_list.add(new_unterminal); } } } catch (IOException ex) { Logger.getLogger(Syntax.class.getName()).log(Level.SEVERE, null, ex); } } public void create_predict_map(){//构造预测分析表 for(Production production : production_list){ if(predict_map.containsKey(production.left)){ HashMap temp = predict_map.get(production.left); for(String s : production.select){ temp.put(s, production); } predict_map.remove(production.left); predict_map.put(production.left, temp); }else{ HashMap<String,Production> temp = new HashMap<>(); for(String s : production.select){ temp.put(s, production); } predict_map.put(production.left, temp); } } create_synch(); } public void create_synch(){//构造同步记号 for(Unterminal_Symbol temp : unterminal_list){ HashMap map = predict_map.get(temp.value); for(String s : temp.follow_Set){ if(!map.containsKey(s)){ Production p = new Production(-1);//synch同步记号 map.put(s,p); } } predict_map.remove(temp.value); predict_map.put(temp.value, map); } } public void create_select(){//构造select集 for(int i=0;i<production_list.size();i++){ Production temp = production_list.get(i); if("<NULL>".equals(temp.right.get(0))){ for(Unterminal_Symbol A : unterminal_list){ if(A.value.equals(temp.left)){ temp.select = (ArrayList<String>) A.follow_Set.clone(); } } }else{ ArrayList<String> first_alpha = get_first_ofsequence(temp.right); if(can_beNullsequence(temp.right)){ for(Unterminal_Symbol A : unterminal_list){ if(A.value.equals(temp.left)){ temp.select = union_List(first_alpha,A.follow_Set); } } }else{ temp.select = (ArrayList<String>) first_alpha.clone(); } } production_list.set(i, temp); } for(int i=0;i<production_list.size();i++){//人工矫正 Production temp = production_list.get(i); if("<stmts'>".equals(temp.left) && "<NULL>".equals(temp.right.get(0))){ temp.select.clear(); temp.select.add("<}>"); } production_list.set(i, temp); } } public void create_first(){//构造first集 set_terminal_first(); set_unterminal_first(); } public void set_terminal_first(){//初始化first集 for(int i=0;i<terminal_list.size();i++){ Terminal_Symbol temp = terminal_list.get(i); temp.first_Set.add(temp.value); //终结符FIRST(X)={X} terminal_list.set(i, temp); } } public void set_unterminal_first(){ //构造非终止符first集 boolean havechanged; do{ havechanged = false; for(int i=0;i<unterminal_list.size();i++){ Unterminal_Symbol temp = unterminal_list.get(i); int cur_num = temp.first_Set.size(); for(Production p : production_list){ if(temp.value.equals(p.left)){ for (String current_symbol : p.right) { if(can_beNull(current_symbol)){ for(Unterminal_Symbol u : unterminal_list){ if(u.value.equals(current_symbol)){ temp.first_Set = union_List(temp.first_Set,u.first_Set); } } }else{ if(isTerminal(current_symbol)){ if(!temp.first_Set.contains(current_symbol)){ temp.first_Set.add(current_symbol); } }else{ for(Unterminal_Symbol u : unterminal_list){ if(u.value.equals(current_symbol)){ temp.first_Set = union_List(temp.first_Set,u.first_Set); } } } break; } } } } int next_num = temp.first_Set.size(); if(next_num>cur_num){ havechanged = true; unterminal_list.set(i, temp); } } }while(havechanged); } public void create_follow(){//构造follow集 init_follow(); boolean havechanged; do{ havechanged = false; for(Production production : production_list){ String currentLeft = production.left; ArrayList<String> currentRight = production.right; int length = currentRight.size(); for(int i=0;i<length;i++){ String currentString = currentRight.get(i); if(!isUnterminal(currentString)){//直到非终结符才计算follow集 continue; } if(i < length-1){ ArrayList<String> rest = new ArrayList<>(currentRight.subList(i+1, length)); ArrayList<String> firstSetofRest = get_first_ofsequence(rest); for(int j=0;j<unterminal_list.size();j++){ if(unterminal_list.get(j).value.equals(currentString)){ Unterminal_Symbol unterminal = unterminal_list.get(j); int len1 = unterminal.follow_Set.size(); unterminal.follow_Set = union_List(unterminal.follow_Set,firstSetofRest); int len2 = unterminal.follow_Set.size(); if(len2>len1){ havechanged = true; unterminal_list.set(j, unterminal); } } } if(can_beNullsequence(rest)){ for(int j=0;j<unterminal_list.size();j++){ if(unterminal_list.get(j).value.equals(currentString)){ Unterminal_Symbol unterminal = unterminal_list.get(j); int len1 = unterminal.follow_Set.size(); for(Unterminal_Symbol A : unterminal_list){ if(A.value.equals(currentLeft)){ unterminal.follow_Set = union_List(unterminal.follow_Set,A.follow_Set); } } int len2 = unterminal.follow_Set.size(); if(len2>len1){ havechanged = true; unterminal_list.set(j, unterminal); } } } } }else{ for(int j=0;j<unterminal_list.size();j++){ if(unterminal_list.get(j).value.equals(currentString)){ Unterminal_Symbol unterminal = unterminal_list.get(j); int len1 = unterminal.follow_Set.size(); for(Unterminal_Symbol A : unterminal_list){ if(A.value.equals(currentLeft)){ unterminal.follow_Set = union_List(unterminal.follow_Set,A.follow_Set); } } int len2 = unterminal.follow_Set.size(); if(len2>len1){ havechanged = true; unterminal_list.set(j, unterminal); } } } } } } }while(havechanged); } public void init_follow(){//follow集的初始化 for(int i=0;i<unterminal_list.size();i++){ Unterminal_Symbol temp = unterminal_list.get(i); if("<s>".equals(temp.value)){ temp.follow_Set.add("$"); unterminal_list.set(i, temp); } } } public boolean can_beNullsequence(ArrayList<String> alpha){//文法串能否为空 for(String s : alpha){ if(!can_beNull(s)){ return false; } } return true; } public ArrayList<String> get_first_ofsequence(ArrayList<String> alpha){//求语法串的first集 ArrayList<String> first_set = new ArrayList<String>(); for(String s : alpha){ if(can_beNull(s)){ for(Unterminal_Symbol temp : unterminal_list){ if(s.equals(temp.value)){ first_set = union_List(first_set,temp.first_Set); } } }else{ if(isTerminal(s)){ if(!first_set.contains(s)){ first_set.add(s); } }else{ for(Unterminal_Symbol temp : unterminal_list){ if(s.equals(temp.value)){ first_set = union_List(first_set,temp.first_Set); } } } break; } } return first_set; } public ArrayList union_List(ArrayList a,ArrayList b){//集合并运算 ArrayList c; c = (ArrayList) a.clone(); for (Object temp : b) { if(!(c.contains(temp))){ c.add(temp); } } return c; } public boolean isTerminal(String X){ //判断是否为终结符 for (Terminal_Symbol temp : terminal_list) { if(temp.value.equals(X)){ return true; } } return false; } public boolean isUnterminal(String X){ for(Unterminal_Symbol temp : unterminal_list){ if(temp.value.equals(X)){ return true; } } return false; } public boolean can_beNull(String X){ //判断X可否推出空串 if(isTerminal(X)){//X是终结符,则X不可能推出空串 return false; }else{//X是非终结符 if(canbeNull_list.contains(X) || X.equals("<NULL>")){ return true; } for(Production p : production_list){ if(X.equals(p.left)){ if("<NULL>".equals(p.right)){ canbeNull_list.add(X); return true; }else{ boolean flag = true; for(int i=0;i<p.right.size();i++){ if(!can_beNull(p.right.get(i))){ flag = false; break; } } if(flag){ canbeNull_list.add(X); return true; } } } } return false; } } public Syntax(){ this.Token_Code_List = Arrays.asList(Token_Code); this.predict_map = new HashMap<>(); this.terminal_list = new ArrayList<>(); this.unterminal_list = new ArrayList<>(); this.production_list = new ArrayList<>(); this.canbeNull_list = new ArrayList<>(); this.derived_strings = new Stack<>(); this.explaination = null; //derived_strings.push("<s>"); } public ArrayList<Terminal_Symbol> terminal_list; //终结符表 public ArrayList<Unterminal_Symbol> unterminal_list; //非终结符表 public ArrayList<Production> production_list; //表达式 public ArrayList<String> canbeNull_list; //可推导为空符号表 public HashMap<String,HashMap<String,Production>> predict_map;//预测分析表 public Stack<String> derived_strings;//推导符号串 public String explaination; //句法分析说明 /*******词法种别码表******终结符表********/ public static String[] Token_Code = {"<IF>","<ELSE>","<FOR>","<DO>","<WHILE>","<RETURN>", "<INT>","<FLOAT>","<CHAR>","<DOUBLE>","<BOOLEAN>","<VOID>","<TRUE>","<FALSE>","<INCLUDE>","<STRING>","<<>","<>>","<=>","<<=>","<>=>","<<>>","<==>", "<*>","<\\>","<+>","< - >","</>","<;>","<!>","<CHARACTER>","<TEXT>","<ID>","<CONST_INT>", "<CONST_REAL>","<(>","<)>","<{>","<}>","<&>","<|>","<~>","<.>","<#>","<++>","< -- >","<%>","<,>"};//token种别码表 public static List<String> Token_Code_List; }