不知不觉,写了一个编译器(二)

当我们完成了词法分析之后,就可以进行语法分析了。(词法分析链接:不知不觉,写了一个编译器(一)

语法分析的主要内容是,对于我们自己规定的语法,判断哪些token可以在一起,哪些token不行。我们在这里,主要使用建立first,follow,predict_table的方法。(针对LL文法)

对于LL文法的讲解,这里就不再赘述了。下面阐述一下,first集合,follow集合,以及predict_table的建立方法:

first 集合

对形如U->a…的产生式(a是终结符),把a收入到First(U)中
对形入U->P…的产生式(P是非终结符),应把First(P)中的全部内容包含到First(U)中

Follow 集合:

对每一个形如“…Ua…”的组合,把a直接包含到Follow(U)中。

对形如“…UP…”(P是非终结符)的组合,把First(P)直接收入到Follow(U)中。

若S->…U,即以U结尾,则#∈Follow(U)

对形如U->…P的产生式(P是非终结符),把Follow(U)包含到Follow(P)中。

 

Predict_table:

Predict(U→a) =
First(a) 当First(a)不包含空
或者
First(a)-空∪Follow(U) 当First(a)包含空

 

下面是我们的语法:

然后是我们首先要将语法转换为LL文法,然后再构建first,follow以及predict集合:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import Scanner.Kind;
import Scanner.LexicalException;
import Scanner.Token;
import Parser.SyntaxException;


import static Scanner.Kind.*;

public class Parser {

	@SuppressWarnings("serial")
	public class SyntaxException extends Exception {
		Token t;

		public SyntaxException(Token t, String message) {
			super(message);
			this.t = t;
		}

	}
	
	public class ThreeTuple {
	    public String first;
	    public String second;
	    public ThreeTuple(String a, String b) {
	        this.first = a;
	        this.second = b;
	    }
	    public void put(String a, String b) {
	        this.first = a;
	        this.second = b;
	    }
	    public String toString() {
	        return this.first+" "+this.second;
	    }
	    public String GetFirst() {
	        return this.first;
	    }
	    public String GetSecond() {
	        return this.second;
	    }
	    @Override
	    public boolean equals(Object obj) {
	        return obj instanceof ThreeTuple &&
	                this.first.equals(((ThreeTuple)obj).first) &&
	                this.second.equals(((ThreeTuple)obj).second);
	    }
	    @Override
	    public int hashCode() {  
	        return (first!=null?first.hashCode():1)*31+(second!=null?second.hashCode():1)*31;  
	    }  
	}


	Scanner scanner;
	Token t;
    ArrayList<String> grammar;
    HashSet<String> terminator;//终结符
    HashMap<String, HashSet<String>> F;//建立first集合
    HashMap<String, HashSet<String>> FO;//建立follow集合
    String tsts;
    ArrayList<Token> toks;
	Parser(Scanner scanner) {
		this.scanner = scanner;
		t = scanner.nextToken();
		tsts="";
		toks=new ArrayList<Token> ();//添加已经转换为LL文法的新语法
		grammar=new ArrayList<String>();
		grammar.add("Program ::= IDENTIFIER Pro");
		grammar.add("Pro ::= Declaration Zec | Statement Zec | ε");
		grammar.add("Zec ::= SEMI Pro");
		grammar.add("Declaration ::= VariableDeclaration | ImageDeclaration | SourceSinkDeclaration");
		grammar.add("VariableDeclaration ::= VarType IDENTIFIER Va");
		grammar.add("Va ::= OP_ASSIGN Expression | ε");
		grammar.add("VarType ::= KW_int | KW_boolean");
		grammar.add("SourceSinkDeclaration ::= SourceSinkType IDENTIFIER OP_ASSIGN Source");
		grammar.add("Source ::= STRING_LITERAL | OP_AT Expression | IDENTIFIER");
		grammar.add("SourceSinkType ::= KW_url | KW_file");
		grammar.add("ImageDeclaration ::= KW_image Im IDENTIFIER Ma");
		grammar.add("Im ::= LSQUARE Expression COMMA Expression RSQUARE | ε");
		grammar.add("Ma ::= OP_LARROW Source | ε");
		grammar.add("Statement ::= IDENTIFIER St");
		grammar.add("St ::= AssignmentStatement | ImageOutStatement | ImageInStatement");
		grammar.add("ImageOutStatement ::= OP_RARROW Sink");
		grammar.add("Sink ::= IDENTIFIER | KW_SCREEN");
		grammar.add("ImageInStatement ::= OP_LARROW Source");
		grammar.add("AssignmentStatement ::= Lhs OP_ASSIGN Expression");
		grammar.add("Expression ::= OrExpression E");
		grammar.add("E ::= OP_Q Expression OP_COLON Expression | ε");
		grammar.add("OrExpression ::= AndExpression An");
		grammar.add("An ::= OP_OR AndExpression An | ε");
		grammar.add("AndExpression ::= EqExpression Eq");
		grammar.add("Eq ::= OP_AND EqExpression Eq | ε");
		grammar.add("EqExpression ::= RelExpression Rel");
		grammar.add("Rel ::= OP_EQ RelExpression Rel | OP_NEQ RelExpression Rel | ε");
		grammar.add("RelExpression ::= AddExpression Add");
		grammar.add("Add ::= OP_LT AddExpression Add | OP_GT AddExpression Add | OP_LE AddExpression Add | OP_GE AddExpression Add | ε");
		grammar.add("AddExpression ::= MultExpression Mul");
		grammar.add("Mul ::= OP_PLUS MultExpression Mul | OP_MINUS MultExpression Mul | ε");
		grammar.add("MultExpression ::= UnaryExpression Unary");
		grammar.add("Unary ::= OP_TIMES UnaryExpression Unary | OP_DIV UnaryExpression Unary | OP_MOD UnaryExpression Unary | ε");
		grammar.add("UnaryExpression ::= OP_PLUS UnaryExpression | OP_MINUS UnaryExpression | UnaryExpressionNotPlusMinus");
		grammar.add("UnaryExpressionNotPlusMinus ::= OP_EXCL UnaryExpression | Primary | IdentOrPixelSelectorExpression | KW_x | KW_y | KW_r | KW_a | KW_X | KW_Y | KW_Z | KW_A | KW_R | KW_DEF_X | KW_DEF_Y");
		grammar.add("Primary ::= INTEGER_LITERAL | LPAREN Expression RPAREN | FunctionApplication | BOOLEAN_LITERAL");
		grammar.add("IdentOrPixelSelectorExpression ::= IDENTIFIER Id");
		grammar.add("Id ::= LSQUARE Selector RSQUARE  | ε");
		grammar.add("Lhs ::= LSQUARE LhsSelector RSQUARE | ε");
		grammar.add("FunctionApplication ::= FunctionName Fc");
		grammar.add("Fc ::= LPAREN Expression RPAREN | LSQUARE Selector RSQUARE ");
		grammar.add("FunctionName ::= KW_sin | KW_cos | KW_atan | KW_abs | KW_cart_x | KW_cart_y | KW_polar_a | KW_polar_r");
		grammar.add("LhsSelector ::= LSQUARE Se RSQUARE");
		grammar.add("Se ::= XySelector | RaSelector");
		grammar.add("XySelector ::= KW_x COMMA KW_y");
		grammar.add("RaSelector ::= KW_r COMMA KW_a");
		grammar.add("Selector ::= Expression COMMA Expression");
		terminator=new HashSet<String> ();//添加终结符
		terminator.add("IDENTIFIER"); terminator.add("INTEGER_LITERAL"); terminator.add("BOOLEAN_LITERAL"); 
		terminator.add("STRING_LITERAL"); terminator.add("KW_x"); terminator.add("KW_X");
		terminator.add("KW_y"); terminator.add("KW_Y"); terminator.add("KW_r"); 
		terminator.add("KW_R"); terminator.add("KW_a"); terminator.add("KW_A"); 
		terminator.add("KW_Z"); terminator.add("KW_DEF_X"); terminator.add("KW_DEF_Y"); 
		terminator.add("KW_SCREEN"); terminator.add("KW_cart_x"); terminator.add("KW_cart_y"); 
		terminator.add("KW_polar_a"); terminator.add("KW_polar_r"); terminator.add("KW_abs"); 
		terminator.add("KW_sin"); terminator.add("KW_cos"); terminator.add("KW_atan"); 
		terminator.add("KW_log"); terminator.add("KW_image"); terminator.add("KW_int"); 
		terminator.add("KW_boolean"); terminator.add("KW_url"); terminator.add("KW_file"); 
		terminator.add("OP_ASSIGN"); terminator.add("OP_GT"); terminator.add("OP_LT"); 
		terminator.add("OP_EXCL"); terminator.add("OP_Q"); terminator.add("OP_COLON"); 
		terminator.add("OP_EQ"); terminator.add("OP_NEQ"); terminator.add("OP_GE"); 
		terminator.add("OP_LE"); terminator.add("OP_AND"); terminator.add("OP_OR"); 
		terminator.add("OP_PLUS"); terminator.add("OP_MINUS"); terminator.add("OP_TIMES"); 
		terminator.add("OP_DIV"); terminator.add("OP_MOD"); terminator.add("OP_POWER"); 
		terminator.add("OP_AT"); terminator.add("OP_RARROW"); terminator.add("OP_LARROW"); 
		terminator.add("LPAREN"); terminator.add("RPAREN"); terminator.add("LSQUARE"); 
		terminator.add("RSQUARE"); terminator.add("SEMI"); terminator.add("COMMA");
		terminator.add("ε");terminator.add("EOF");
		F=new HashMap<String, HashSet<String>> ();
		FO=new HashMap<String, HashSet<String>> ();
		for(Token sc: scanner.tokens){
			if(!sc.kind.toString().equals("EOF")) tsts=tsts+sc.kind.toString()+" ";
			toks.add(sc);
		}
		tsts=tsts.trim();
		//System.out.println("This is Parser");
	}

	//字符串处理,去空格等
	 public HashMap<String, String> Analysis(ArrayList<String> k){
		 HashMap<String, String> m=new HashMap<String, String>();
		 for(int i=0;i<k.size();i++){
			 String s=k.get(i);
			 String a[]=s.split("::=");
			 m.put(a[0].trim(), a[1].trim());
		 }
		 return m;
		 
	 }//建立First集合
	 public HashSet<String> getFirst(String s,HashMap<String, String> c,HashSet<String> t){	
			HashSet<String> l=new HashSet<String>();
			if(s.contains("|")){
				String k[]=s.split("\\|");
				for(int i=0;i<k.length;i++){
					l.addAll(getFirst(k[i].trim(),c,t));
				}
			}
			else{
				String k[]=s.split(" ");
				if(t.contains(k[0])){
					l.add(k[0]);
				}
				else if(c.containsKey(k[0])){
					//System.out.println(s+" "+k[0]);
					l.addAll(getFirst(c.get(k[0]).trim(),c,t));
				}
				for(int i=0;i<k.length-1;i++){
					//System.out.println(s);
					if(c.containsKey(k[i])&&getFirst(c.get(k[i]).trim(),c,t).contains("ε")) {
						if(c.containsKey(k[i+1])) l.addAll(getFirst(c.get(k[i+1]).trim(),c,t));
						else if(t.contains(k[i+1])) l.add(k[i+1]);
					}
					else break;
				}
			}
			return l;
			
		}
	public HashMap<String, HashSet<String>> First(HashMap<String, String> c,HashSet<String> t){
		HashMap<String, HashSet<String>> First= new HashMap<String, HashSet<String>>();
		for (Map.Entry<String, String> entry : c.entrySet()) {  
			String s=entry.getValue().trim();
			//System.out.println(s);
			HashSet<String> temp=getFirst(s,c,t);
		    First.put(entry.getKey(), temp);
		    //System.out.println("hello");
		}  
		return First;	
	}//建立follow集合
    public  HashMap<String, HashSet<String>> FollowLoop(HashMap<String, String> c,HashSet<String> t,HashMap<String, HashSet<String>> F,HashMap<String, HashSet<String>> Follow){
    	for (Map.Entry<String, String> entry : c.entrySet()) {  
			String key=entry.getKey();
			String value=entry.getValue();
			if(key.equals("Program")){
				Follow.get(key).add("EOF");
			}
			if(value.contains("|")){
				Follow=FollowLoopForOr(c,t,F,Follow,value,key);
				continue;
			}
			String k[]=value.split(" ");
			int i=0;
			for(i=0;i<k.length-1;i++){
				if(c.containsKey(k[i])&&t.contains(k[i+1])){
					Follow.get(k[i]).add(k[i+1]);
				}
				else if(c.containsKey(k[i])&&c.containsKey(k[i+1])){
					Follow.get(k[i]).addAll(F.get(k[i+1]));
					if(F.get(k[i+1]).contains("ε")) {
						Follow.get(k[i]).remove("ε");
					}
				}
			}
			if(c.containsKey(k[i])) Follow.get(k[i]).addAll(Follow.get(key));
		    if(c.containsKey(k[i])&&F.get(k[i]).contains("ε")&&c.containsKey(k[i-1])) Follow.get(k[i-1]).addAll(Follow.get(key));
    	}
    	return Follow;
    }
    public HashMap<String, HashSet<String>> FollowLoopForOr(HashMap<String, String> c,HashSet<String> t,HashMap<String, HashSet<String>> F,HashMap<String, HashSet<String>> Follow,String value,String key){
			if(value.contains("|")){
				String x[]=value.split("\\|");
				for(int j=0;j<x.length;j++){
					x[j]=x[j].trim();
					if(c.containsKey(x[j])){
						Follow.get(x[j]).addAll(Follow.get(key));
					}
					else{
				    String kk[]=x[j].split(" ");int i=0;
				    for(i=0;i<kk.length-1;i++){
				    if(c.containsKey(kk[i])&&t.contains(kk[i+1]))
						Follow.get(kk[i]).add(kk[i+1]);
					else if(c.containsKey(kk[i])&&c.containsKey(kk[i+1])){
						Follow.get(kk[i]).addAll(F.get(kk[i+1]));
						if(F.get(kk[i+1]).contains("ε")) {
							Follow.get(kk[i]).remove("ε");
						}
					}
				    }
				    if(c.containsKey(kk[i])) Follow.get(kk[i]).addAll(Follow.get(key));
				    if(c.containsKey(kk[i])&&F.get(kk[i]).contains("ε")&&c.containsKey(kk[i-1])) Follow.get(kk[i-1]).addAll(Follow.get(key));
				    }
			}
		}
		
    	return Follow;
    }
	public HashMap<String, HashSet<String>> Follow(HashMap<String, String> c,HashSet<String> t,HashMap<String, HashSet<String>> F){
    	HashMap<String, HashSet<String>> Follow=new HashMap<String, HashSet<String>>();
    	for (Map.Entry<String, String> entry : c.entrySet()) { 
    		HashSet<String> temp=new HashSet<String>();
			Follow.put(entry.getKey(),temp);
		}  
    	Follow=FollowLoop(c,t,F,Follow);
    	Follow=FollowLoop(c,t,F,Follow);
    	Follow=FollowLoop(c,t,F,Follow);
    	Follow=FollowLoop(c,t,F,Follow);
    	Follow=FollowLoop(c,t,F,Follow);
			return Follow;}//建立predict集合
	public HashMap<ThreeTuple, String> Prediction(HashSet<String> t,HashMap<String, String> c,HashMap<String, HashSet<String>> F,HashMap<String, HashSet<String>> Follow){
		HashMap<ThreeTuple, String> k=new HashMap<ThreeTuple, String>();
		for (Map.Entry<String, String> entry : c.entrySet()) {  
			String key=entry.getKey().trim();	
			for(String str:t){
				str=str.trim();
				if(str.equals("ε")) continue;
				//System.out.println(key+" "+str);
				if(F.get(key).contains(str)){
					//System.out.println("");
					ThreeTuple temp = new ThreeTuple(key,str);
					String con= c.get(key).trim();
					if(!con.contains("|")) {
						k.put(temp, con);			
					}
					else{
						String kk[]=con.split("\\|");
						for(int i=0;i<kk.length;i++){
							kk[i]=kk[i].trim();
							if(c.containsKey(kk[i])&&F.get(kk[i]).contains(str))
								k.put(temp,kk[i]);
							else if(kk[i].contains(" ")){
								String z[]=kk[i].split(" ");
								if(z[0].equals(str)) k.put(temp, kk[i]);
								else if(c.containsKey(z[0])&&F.get(z[0]).contains(str)) k.put(temp, kk[i]);
							}
							else if(kk[i].equals(str)) k.put(temp, kk[i]);
						}
					}
				}
				else if(Follow.get(key).contains(str)){
					ThreeTuple temp = new ThreeTuple(key,str);
					String con= c.get(key).trim();
					if(!con.contains("|")) {
						String s[]=con.split(" ");
						boolean flag=true;
						for(int i=0;i<s.length;i++){
							if((c.containsKey(s[i])&&!F.get(key).contains("ε"))||(t.contains(s[i])))
								flag=false;
						}
						if(flag) k.put(temp, con);
					}
					else{
						String kk[]=con.split("\\|");
						for(int i=0;i<kk.length;i++){					
							kk[i]=kk[i].trim();
							if(kk[i].contains(" ")){
								String z[]=kk[i].split(" ");
								boolean flag=true;
								for(int j=0;j<z.length;j++){
									//System.out.println("Following");
									if((c.containsKey(z[j])&&!F.get(key).contains("ε"))||(t.contains(z[j])))
										flag=false;
								}
								if(flag) k.put(temp, kk[i]);
							}
							else if((c.containsKey(kk[i])&&F.get(kk[i]).contains("ε"))||kk[i].equals("ε"))
								k.put(temp, kk[i]);
						}
					}
				}
				else continue;
				}
			
			}
		return k;
		
		
	}
	public int Judgement(HashMap<ThreeTuple, String> predict,String tokens,HashMap<String, HashSet<String>> F){
		Stack<String> st=new Stack<String>();
		ThreeTuple a=new ThreeTuple("Program","IDENTIFIER");
		String s=predict.get(a);
		int w=0;
		//System.out.println(s);
		s=Reverse(s);
		String t[]=s.split(" ");
		for(int i=0;i<t.length;i++) st.push(t[i]);
		tokens+=" EOF";
		String token[]=tokens.split(" ");
		int i=0;
		for(i=0;i<token.length;i++){
			if(token[i].equals(st.peek())){
				st.pop();w++;this.t=scanner.nextToken();continue;
			}
			else{
				String key=st.peek();
				ThreeTuple temp=new ThreeTuple(key,token[i]);
				if(predict.containsKey(temp)){
					String z=st.pop();
					if(!predict.get(temp).equals("ε")){
					String k=Reverse(predict.get(temp));
					String v[]=k.split(" ");
					for(int j=0;j<v.length;j++) st.push(v[j]);
					i--;}
					else{
						if(token[i].equals("EOF")&&z.equals("Pro")&&st.isEmpty()) break;
						else i--;
					}
				}
				else return w+st.size();;
			}
		}
		return w;
	}
	public String Reverse(String s){
		String z[]=s.split(" ");
		String k="";
		for(int i=z.length-1;i>=0;i--){
			k+=z[i];
			k+=" ";
		}
		return k;
	}
	public int JudgementforExpression(HashMap<ThreeTuple, String> predict,String tokens,HashMap<String, HashSet<String>> F){
		Stack<String> st=new Stack<String>();
		String x[]=tokens.split(" ");
		int w=0;
		ThreeTuple a=new ThreeTuple("Expression",x[0]);
		if(!predict.containsKey(a)){w++;return w;}
		String s=predict.get(a);
		//System.out.println(s);
		s=Reverse(s);
		String t[]=s.split(" ");
		for(int i=0;i<t.length;i++) st.push(t[i]);
		tokens+=" EOF";
		String token[]=tokens.split(" ");
		int i=0;
		for(i=0;i<token.length;i++){
			if(token[i].equals(st.peek())){
				st.pop();w++;this.t=scanner.nextToken();continue;
			}
			else{
				String key=st.peek();
				ThreeTuple temp=new ThreeTuple(key,token[i]);
				if(predict.containsKey(temp)){
					String z=st.pop();
					if(!predict.get(temp).equals("ε")){
					String k=Reverse(predict.get(temp));
					String v[]=k.split(" ");
					for(int j=0;j<v.length;j++) st.push(v[j]);
					i--;}
					else{
						if(token[i].equals("EOF")&&st.isEmpty()) break;
						else if(st.isEmpty()&&!token[i].equals("EOF")) return w+token.length-i-1;
						else i--;
					}
				}
				else return w;
			}
		}
		return w;
	}

	/**
	 * Main method called by compiler to parser input.
	 * Checks for EOF
	 * 
	 * @throws SyntaxException
	 */
	public static Program Pro(ArrayList<Token> list){
		Token firstToken=list.get(0); 
		list.remove(0);
		ArrayList<ASTNode> decsAndStatements=new ArrayList<ASTNode>();
		ArrayList<Token> onepart=new ArrayList<Token>();
		for(Token a:list){
			if(!a.kind.equals(SEMI)) onepart.add(a);
			else{
				if(a.kind.equals(SEMI)){
					ASTNode dos;
					if(onepart.get(0).kind.equals(IDENTIFIER))
						dos=Stm(onepart);
					else
						dos=Dec(onepart);
					decsAndStatements.add(dos);
					onepart=new ArrayList<Token>();
				}
			}
		}
		Program a=new Program(firstToken, firstToken,decsAndStatements);
		return a;
	}
	public static Declaration Dec(ArrayList<Token> list){
		Token firstToken=list.get(0); 
		 if(list.get(0).kind.equals(KW_int)||list.get(0).kind.equals(KW_boolean))
			 return DV(list);
		 else if(list.get(0).kind.equals(KW_url)||list.get(0).kind.equals(KW_file))
			 return DS(list);
		 else 
			 return DI(list);
	 }
	public static Declaration_Variable DV(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Token name=list.get(0);
		list.remove(0);
		if(!list.isEmpty()&&list.get(0).kind.equals(OP_ASSIGN)) {
			list.remove(0);
			Declaration_Variable a=new Declaration_Variable(firstToken,  firstToken, name, Exp(list));
			return a;
		}
		else {
			Declaration_Variable a=new Declaration_Variable(firstToken,  firstToken, name, null);
			return a;
		}
		
	}
	public static Declaration_SourceSink DS(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Token name=list.get(0);
		list.remove(0);
		list.remove(0);
		Declaration_SourceSink a=new Declaration_SourceSink(firstToken, firstToken, name, sou(list));
		return a;
	}
	public static Declaration_Image DI(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		if(list.get(0).kind.equals(LSQUARE)){
			list.remove(0);
			Expression x=Exp(list);
			list.remove(0);
			Expression y=Exp(list);
			list.remove(0);
			Token name=list.get(0);
			list.remove(0);
			if(!list.isEmpty()&&list.get(0).kind.equals(OP_LARROW)){
				list.remove(0);
				Declaration_Image a=new Declaration_Image(firstToken, x, y, name,sou(list));
				return a;
			}
			else {
				Declaration_Image a=new Declaration_Image(firstToken, x, y, name,null);
				return a;
			}
		}
		else{
			Token name=list.get(0);
			list.remove(0);
			if(!list.isEmpty()&&list.get(0).kind.equals(OP_LARROW)){
				list.remove(0);
				Declaration_Image a=new Declaration_Image(firstToken, null, null, name,sou(list));
				return a;
			}
			else {
				Declaration_Image a=new Declaration_Image(firstToken, null, null, name, null);
				return a;
			}
		}
	}
	public static Source sou(ArrayList<Token> list){
		Token firstToken=list.get(0); 
		 if(list.get(0).kind.equals(STRING_LITERAL))
			 return SouS(list);
		 else if(list.get(0).kind.equals(OP_AT))
			 return SouCo(list);
		 else 
			 return SouId(list);
	 }
	public static Source_StringLiteral SouS(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Source_StringLiteral a=new Source_StringLiteral(firstToken, firstToken.getText());
		return a;
	}
	
	public static Source_CommandLineParam SouCo(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Source_CommandLineParam a=new Source_CommandLineParam(firstToken, Exp(list));
		return a;
	}
	
	public static Source_Ident SouId(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Source_Ident a=new Source_Ident(firstToken, firstToken);
		return a;
	}
	
	public static Statement Stm(ArrayList<Token> list){
		Token firstToken=list.get(0); 
		 if(list.get(1).kind.equals(OP_LARROW))
			 return StaIn(list);
		 else if(list.get(1).kind.equals(OP_RARROW))
			 return StaOut(list);
		 else 
			 return StaAs(list);
	 }
	
	public static Statement_In StaIn(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);list.remove(0);
		Statement_In a=new Statement_In(firstToken, firstToken, sou(list));
		return a;
	}
	
	public static Statement_Out StaOut(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);list.remove(0);
		Statement_Out a=new Statement_Out(firstToken, firstToken, sin(list));
		return a;
	}
	
	public static Statement_Assign StaAs(ArrayList<Token> list){
		Token firstToken=list.get(0);
		LHS lhs=LHS(list);
		list.remove(0);
		Expression e=Exp(list);
		Statement_Assign a=new Statement_Assign(firstToken, lhs, e);
		return a;
	}
	
	public static Sink sin(ArrayList<Token> list){
		Token firstToken=list.get(0); 
		 if(list.get(0).kind.equals(IDENTIFIER))
			 return SinId(list);
		 else 
			 return SinSc(list);
	 }
	
	public static Sink_Ident SinId(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Sink_Ident a=new Sink_Ident(firstToken, firstToken);
		return a;
	}
	
	public static Sink_SCREEN SinSc(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		Sink_SCREEN a=new Sink_SCREEN(firstToken);
		return a;
	}
	
	public static LHS LHS(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);
		if(!list.isEmpty()&&list.get(0).kind.equals(LSQUARE)){
			list.remove(0);list.remove(0);
			Index Ind=Ind(list);
			list.remove(0);list.remove(0);
			LHS a=new LHS(firstToken, firstToken, Ind);
			return a;
		}
		else{
			LHS a=new LHS(firstToken, firstToken, null);
			return a;
		}
	}
	
	public static Index Ind(ArrayList<Token> list){
		Token firstToken=list.get(0);
		/*if((list.get(0).kind.equals(KW_x)||list.get(0).kind.equals(KW_r))&&list.get(1).kind.equals(COMMA)){
			Expression e0=EPre(list);
			list.remove(0);
			Expression e1=EPre(list);
			Index a=new Index(firstToken, e0, e1);
			return a;
		}
		else{*/
			Expression e0=Exp(list);
			list.remove(0);
			Expression e1=Exp(list);
			Index a=new Index(firstToken, e0, e1);
			return a;
		//}
		
	}
	
	public static Expression Exp(ArrayList<Token> list){
		ArrayList<Token> newList=new ArrayList<Token>();
		for(Token a:list) newList.add(a);
		Expression EB=EB(newList);
		if(!newList.isEmpty()&&newList.get(0).kind.equals(OP_Q)){
			return EC(list);
		}
		else return EB(list);
	}
	
	public static Expression_Conditional EC(ArrayList<Token> list){
		Token firstToken=list.get(0);
		Expression condition=EB(list);
		list.remove(0);
		Expression trueExpression=Exp(list);
		list.remove(0);
		Expression falseExpression=Exp(list);
		Expression_Conditional a=new Expression_Conditional(firstToken, condition, trueExpression,falseExpression);
		return a;
	}
	
	public static Expression EB(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> OrList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EB_AND(list);
			if(!list.isEmpty()&&list.get(0).kind.equals(OP_OR)){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				OrList.add(e0);
			}
			else{
				OrList.add(e0);
				break;
			}
		}
		while(OrList.size()>1){
			Expression ek=OrList.get(0);
			OrList.remove(0);
			Expression es=OrList.get(0);
			OrList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			OrList.add(0, a);
		}
		return OrList.get(0);
	}
	public static Expression EB_AND(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> AndList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EB_EQ(list);
			if(!list.isEmpty()&&list.get(0).kind.equals(OP_AND)){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				AndList.add(e0);
			}
			else{
				AndList.add(e0);
				break;
			}
		}
		while(AndList.size()>1){
			Expression ek=AndList.get(0);
			AndList.remove(0);
			Expression es=AndList.get(0);
			AndList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			AndList.add(0, a);
		}
		return AndList.get(0);
	}
	public static Expression EB_EQ(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> EqList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EB_REL(list);
			if(!list.isEmpty()&&(list.get(0).kind.equals(OP_EQ)||list.get(0).kind.equals(OP_NEQ))){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				EqList.add(e0);
			}
			else{
				EqList.add(e0);
				break;
			}
		}
		while(EqList.size()>1){
			Expression ek=EqList.get(0);
			EqList.remove(0);
			Expression es=EqList.get(0);
			EqList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			EqList.add(0, a);
		}
		return EqList.get(0);
	}
	public static Expression EB_REL(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> RelList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EB_ADD(list);
			if(!list.isEmpty()&&(list.get(0).kind.equals(OP_LT)||list.get(0).kind.equals(OP_GT)||list.get(0).kind.equals(OP_LE)||list.get(0).kind.equals(OP_GE))){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				RelList.add(e0);
			}
			else{
				RelList.add(e0);
				break;
			}
		}
		while(RelList.size()>1){
			Expression ek=RelList.get(0);
			RelList.remove(0);
			Expression es=RelList.get(0);
			RelList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			RelList.add(0, a);
		}
		return RelList.get(0);
		
	}
	public static Expression EB_ADD(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> AddList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EB_MUL(list);
			if(!list.isEmpty()&&(list.get(0).kind.equals(OP_PLUS)||list.get(0).kind.equals(OP_MINUS))){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				AddList.add(e0);
			}
			else{
				AddList.add(e0);
				break;
			}
		}
		while(AddList.size()>1){
			Expression ek=AddList.get(0);
			AddList.remove(0);
			Expression es=AddList.get(0);
			AddList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			AddList.add(0, a);
		}
		return AddList.get(0);
	}
		
	public static Expression EB_MUL(ArrayList<Token> list){
		Token firstToken=list.get(0);
		ArrayList<Expression> MulList=new ArrayList<Expression> ();
		ArrayList<Token> OpList=new ArrayList<Token> ();
		while(true){
			Expression e0=EU(list);
			if(!list.isEmpty()&&(list.get(0).kind.equals(OP_TIMES)||list.get(0).kind.equals(OP_DIV)||list.get(0).kind.equals(OP_MOD))){
				Token op=list.get(0);
				OpList.add(op);
				list.remove(0);
				MulList.add(e0);
			}
			else{
				MulList.add(e0);
				break;
			}
		}
		while(MulList.size()>1){
			Expression ek=MulList.get(0);
			MulList.remove(0);
			Expression es=MulList.get(0);
			MulList.remove(0);
			Token op=OpList.get(0);
			OpList.remove(0);
			Expression_Binary a=new Expression_Binary(firstToken, ek, op, es);
			MulList.add(0, a);
		}
		return MulList.get(0);
	}
	public static Expression EU(ArrayList<Token> list){
		Token firstToken=list.get(0);
		if(firstToken.kind.equals(OP_PLUS)||firstToken.kind.equals(OP_MINUS)||firstToken.kind.equals(OP_EXCL)){
			list.remove(0);
			Expression e=EU(list);
			Expression_Unary a=new Expression_Unary(firstToken, firstToken, e);
			return a;
		}
		else {
			HashSet<Kind> kinds=new HashSet<Kind> ();
			kinds.add(KW_x);kinds.add(KW_y);kinds.add(KW_r);kinds.add(KW_a);kinds.add(KW_X);
			kinds.add(KW_Y);kinds.add(KW_Z);kinds.add(KW_A);kinds.add(KW_R);kinds.add(KW_DEF_X);
			kinds.add(KW_DEF_Y);
			if(kinds.contains(list.get(0).kind)){
				return EPre(list);
			}
			else if(list.get(0).kind.equals(IDENTIFIER)){
				if(list.size()>1&&list.get(1).kind.equals(LSQUARE)){
					return EPix(list);
				}
				else return EId(list);
			}
			else if(list.get(0).kind.equals(INTEGER_LITERAL)){
				return EIn(list);
			}
			else if(list.get(0).kind.equals(BOOLEAN_LITERAL)){
				return EBo(list);
			}
			else if(list.get(0).kind.equals(LPAREN)){
				list.remove(0);
				Expression a=Exp(list);
				list.remove(0);
				return a;
			}
			else{
				HashSet<Kind> kindfuncs=new HashSet<Kind> ();
				kindfuncs.add(KW_sin); kindfuncs.add(KW_cos); kindfuncs.add(KW_atan); 
				kindfuncs.add(KW_abs); kindfuncs.add(KW_cart_x); kindfuncs.add(KW_cart_y); 
				kindfuncs.add(KW_polar_a); kindfuncs.add(KW_polar_r);
				if(kindfuncs.contains(list.get(0).kind)&&list.get(1).kind.equals(LPAREN)){
					return EFe(list);
				}
				else return EFi(list);
			}
		}
	}
	
	public static Expression_PredefinedName EPre(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);
		Expression_PredefinedName a=new Expression_PredefinedName(firstToken, firstToken.kind);
		return a;
	}
	
	public static Expression_PixelSelector EPix(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);list.remove(0);
		Index index=Ind(list);
		list.remove(0);
		Expression_PixelSelector a=new Expression_PixelSelector(firstToken, firstToken, index);
		return a;
	}
	
	public static Expression_Ident EId(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);	
		Expression_Ident a=new Expression_Ident(firstToken, firstToken);
		return a;
	}
	
	public static Expression_IntLit EIn(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);	
		Expression_IntLit a=new Expression_IntLit(firstToken, Integer.parseInt(firstToken.getText()));
		return a;
	}
	
	public static Expression_BooleanLit EBo(ArrayList<Token> list){
		Token firstToken=list.get(0);list.remove(0);	
		Expression_BooleanLit a=new Expression_BooleanLit(firstToken, Boolean.parseBoolean(firstToken.getText()));
		return a;
	}

	public static Expression_FunctionAppWithExprArg EFe(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);	
		list.remove(0);
		Expression arg=Exp(list);
		list.remove(0);
		Expression_FunctionAppWithExprArg a=new Expression_FunctionAppWithExprArg(firstToken, firstToken.kind, arg);
		return a;
	}

	public static Expression_FunctionAppWithIndexArg EFi(ArrayList<Token> list){
		Token firstToken=list.get(0);
		list.remove(0);	
		list.remove(0);
		//System.out.println("HELLO");
		Index arg=Ind(list);
		list.remove(0);
		Expression_FunctionAppWithIndexArg a=new Expression_FunctionAppWithIndexArg(firstToken, firstToken.kind, arg);
		return a;
	}
	public Program parse() throws SyntaxException {
		//System.out.println("This is Parser");
		//System.out.println(tsts);
		Program a= program();
		
		matchEOF();
		return a;
	}
	

	/**
	 * Program ::=  IDENTIFIER   ( Declaration SEMI | Statement SEMI )*   
	 * 
	 * Program is start symbol of our grammar.
	 * 
	 * @throws SyntaxException
	 */
	 public Program program() throws SyntaxException {
	    	HashMap<String, String> d=Analysis(grammar);
			F= First(d,terminator);
			FO= Follow(d,terminator,F);
			HashMap<ThreeTuple, String> P=Prediction(terminator,d,F,FO);
			//String test="IDENTIFIER KW_int IDENTIFIER OP_ASSIGN KW_y OP_PLUS KW_x OP_PLUS OP_MINUS KW_y OP_MOD KW_r OP_EQ KW_A OP_LE KW_DEF_Y OP_AND KW_Z OP_NEQ KW_r OP_OR INTEGER_LITERAL OP_Q IDENTIFIER LSQUARE LPAREN IDENTIFIER RPAREN COMMA KW_cos LPAREN KW_Z RPAREN RSQUARE OP_COLON BOOLEAN_LITERAL SEMI IDENTIFIER LSQUARE LSQUARE KW_r COMMA KW_A RSQUARE RSQUARE OP_ASSIGN KW_X SEMI KW_image LSQUARE KW_Y COMMA KW_Z RSQUARE IDENTIFIER SEMI IDENTIFIER OP_RARROW KW_SCREEN SEMI IDENTIFIER OP_LARROW STRING_LITERAL SEMI KW_file IDENTIFIER OP_ASSIGN OP_AT IDENTIFIER SEMI";
			String sp[]=tsts.split(" ");
			if(Judgement(P,tsts,F)!=sp.length) throw new SyntaxException(this.t, "Token not allowed in grammar"); 
			else return Pro(toks);
			//System.out.println(this.t.toString());
		   // throw new UnsupportedOperationException();
	}

	

	/**
	 * Expression ::=  OrExpression  OP_Q  Expression OP_COLON Expression    | OrExpression
	 * 
	 * Our test cases may invoke this routine directly to support incremental development.
	 * 
	 * @throws SyntaxException
	 */
	Expression expression() throws SyntaxException {
		HashMap<String, String> d=Analysis(grammar);
		F= First(d,terminator);
		FO= Follow(d,terminator,F);
		HashMap<ThreeTuple, String> P=Prediction(terminator,d,F,FO);
		//String test="IDENTIFIER KW_int IDENTIFIER OP_ASSIGN KW_y OP_PLUS KW_x OP_PLUS OP_MINUS KW_y OP_MOD KW_r OP_EQ KW_A OP_LE KW_DEF_Y OP_AND KW_Z OP_NEQ KW_r OP_OR INTEGER_LITERAL OP_Q IDENTIFIER LSQUARE LPAREN IDENTIFIER RPAREN COMMA KW_cos LPAREN KW_Z RPAREN RSQUARE OP_COLON BOOLEAN_LITERAL SEMI IDENTIFIER LSQUARE LSQUARE KW_r COMMA KW_A RSQUARE RSQUARE OP_ASSIGN KW_X SEMI KW_image LSQUARE KW_Y COMMA KW_Z RSQUARE IDENTIFIER SEMI IDENTIFIER OP_RARROW KW_SCREEN SEMI IDENTIFIER OP_LARROW STRING_LITERAL SEMI KW_file IDENTIFIER OP_ASSIGN OP_AT IDENTIFIER SEMI";
		String sp[]=tsts.split(" ");
		if(JudgementforExpression(P,tsts,F)!=sp.length) throw new SyntaxException(this.t, "Token not allowed in Expression grammar"); 
		else return Exp(toks);
		//System.out.println(this.t.toString());
		//throw new UnsupportedOperationException();
	}



	/**
	 * Only for check at end of program. Does not "consume" EOF so no attempt to get
	 * nonexistent next Token.
	 * 
	 * @return
	 * @throws SyntaxException
	 */
	private Token matchEOF() throws SyntaxException {
		if (t.kind == EOF) {
			return t;
		}
		String message =  "Expected EOL at " + t.line + ":" + t.pos_in_line;
		throw new SyntaxException(t, message);
	}
}

 

posted @ 2017-12-29 23:17  chris1030  阅读(143)  评论(0编辑  收藏  举报