diff src/plparser/PropertyListParser.java @ 1:b149a5aa465a

Parser is written
author kono@ie.u-ryukyu.ac.jp
date Sat, 28 Aug 2010 17:39:34 +0900
parents
children 151c7fe6c61a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/PropertyListParser.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,180 @@
+package plparser;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.LinkedList;
+
+
+public class PropertyListParser<Node extends Property> {
+	PropertyListNodeFactory<Node> lf;
+	Token<Node> nextToken;
+	public PropertyListScanner<Node> scanner;
+	private Dictionary<Node> dict;
+	// private PropertyListScope<Node> scope;
+	
+	public PropertyListParser(String string,
+			PropertyListNodeFactory<Node> lf) {
+		this.lf = lf;
+	}
+
+	public void initReservedWord() {
+		dict.reserve("=",TokenID.Assign);
+		dict.reserve(",",TokenID.Comma);
+		dict.reserve(";",TokenID.Semicolon);
+		dict.reserve("(",TokenID.Paren);
+		dict.reserve(")",TokenID.CloseParen);
+		dict.reserve("{",TokenID.CurParen);
+		dict.reserve("}",TokenID.CloseCurParen);
+		dict.reserve("true",TokenID.True);
+		dict.reserve("false",TokenID.False);
+	}
+
+	public void initialize() {
+		dict = new Dictionary<Node>();
+		// scope = new PropertyListScope<Node>(null,dict);
+		initReservedWord();
+		scanner = new PropertyListScanner<Node>(dict);
+	}
+
+	public Node parse() {
+		if (scanner==null) return null;
+		nextToken();
+		return term();
+	}
+
+	public Node parse(String exp) {
+		Node n;
+		scanner = scanner.pushScanner(exp);
+		n = parse();
+		scanner = scanner.popScanner();
+		nextToken = scanner.nextToken;
+		return n;
+		
+	}
+
+	public void parseFile(String file) {
+		try {
+			scanner = scanner.pushScannerFile(file);
+		} catch (FileNotFoundException e) {
+			error("Can't open "+file);
+			return;
+		}
+		doParse();
+	}
+	
+	public void parse(InputStream file) {
+		scanner = scanner.pushScannerFile(file,null);
+		doParse();
+	}
+
+	public void parse(InputStream in, String prompt) {
+		scanner = scanner.pushScannerFile(in,prompt);
+		doParse();
+	}
+	
+	public Node doParse() {
+		Node n;
+		do {
+			n=parse();
+		} while(scanner.hasRemaining());
+		scanner = scanner.popScanner();
+		nextToken = scanner.nextToken;
+		return n;
+	}
+
+	public LinkedList<Node> expr1() {
+		LinkedList<Node> list = new LinkedList<Node>();
+	    expr2(list);
+		while(nextToken.type == TokenID.Semicolon) {
+			nextToken();
+			expr2(list);
+		}
+		return list;
+	}
+
+
+	public void expr2(LinkedList<Node>list) {
+		Node n1 = term();
+		if (nextToken.type!=TokenID.Assign) {
+			error("needs assignment");
+			return;
+		}
+		Node n2 = term();
+		list.add(n1); list.add(n2);
+		return;
+	}
+
+	public LinkedList<Node> expr3() {
+		LinkedList<Node>list = new LinkedList<Node>();
+		Node n1 = term();
+		list.add(n1); 
+		while (nextToken.type==TokenID.Comma) {
+			Node n2 = term();
+			list.add(n2);
+		}
+		return list;
+	}
+	
+	protected Node makeVariable(Token<Node> t) {
+		Node n;
+		if ((n=t.value())==null) {
+			n =  lf.variableNode(t.name(),true);
+			t.setValue(n);
+		}
+		// n.token = t;
+		return n;
+	}
+
+	protected Node term() {
+		Node n = null;
+		switch (nextToken.type) {
+		case Paren: // Array
+			nextToken();
+			LinkedList<Node>list1 = expr3();
+			if (nextToken.type==TokenID.CloseParen) {
+			} else { // syntax error;
+				scanner.error(") expected but got "+nextToken);
+				return lf.trueNode();
+			}
+			return lf.arrayNode(list1);
+		case CurParen: // Dictionary
+			nextToken();
+			LinkedList<Node> list = expr1();
+			if (nextToken.type==TokenID.CloseCurParen) {
+			} else { // syntax error;
+				scanner.error("} expected");
+			}
+			return lf.dictionaryNode(list);
+		case NUMBER:
+			n = lf.numberNode(Integer.parseInt(nextToken.name));
+			break;
+		case NULL: 
+			break;
+		default:
+			if (nextToken.type.isVariable()) 
+				n = makeVariable(nextToken);
+			else {
+				// error("Internal ununderstandable term '"+nextToken+"' type: "+nextToken.type+".");
+				n = makeVariable(nextToken); // skip any
+			}
+		}
+		nextToken();
+		return n;
+	}
+
+
+	/*
+	 * Syntactical Short cut for scanner.textToken()
+	 * 
+	 * It never returns null, to check EOF, 
+	 *     nextToken.type==TokenID.NULL
+	 */
+	public Token<Node> nextToken() {
+		return nextToken = scanner.nextToken();
+	}
+	
+
+	public void error(String err) {
+		scanner.error(err);
+	}
+}