changeset 1:b149a5aa465a

Parser is written
author kono@ie.u-ryukyu.ac.jp
date Sat, 28 Aug 2010 17:39:34 +0900
parents b0dee5b76b12
children 151c7fe6c61a
files src/plparser/ArrayProperty.java src/plparser/BooleanProperty.java src/plparser/DictProperty.java src/plparser/NumberNode.java src/plparser/Property.java src/plparser/PropertyFactoryImpl.java src/plparser/PropertyListNodeFactory.java src/plparser/PropertyListParser.java src/plparser/PropertyListScope.java src/plparser/Test.java src/plparser/TestParser.java src/plparser/TestScanner.java src/plparser/Token.java src/plparser/TokenID.java
diffstat 14 files changed, 477 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/ArrayProperty.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,15 @@
+package plparser;
+
+import java.util.LinkedList;
+
+public class ArrayProperty extends Property {
+	LinkedList<Property> list;
+	
+	public ArrayProperty(LinkedList<Property> list1) {
+		list = list1;
+	}
+	
+	public String toString() {
+		return "Array ("+list+")";
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/BooleanProperty.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,15 @@
+package plparser;
+
+public class BooleanProperty extends Property {
+	boolean b;
+	
+	public BooleanProperty(TokenID id) {
+		b = id==TokenID.True;
+	}
+
+	public String toString() {
+		return b?"True":"Fasel";
+	}
+	
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/DictProperty.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,30 @@
+package plparser;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+public class DictProperty extends Property {
+	HashMap<Property, Property> map;
+	
+	public DictProperty(LinkedList<Property> list) {
+		map = new HashMap<Property, Property>();
+		while(!list.isEmpty()) {
+			Property key = list.poll();
+			Property value = list.poll();
+			map.put(key, value);
+		}
+	}
+	
+	public String toString() {
+		String s = "Dictionary{" ;
+		for(Property p:map.keySet()) {
+			s += p;
+			s += "->";
+			s += map.get(p);
+			s += ",";
+		}
+		s += "}";
+		return s;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/NumberNode.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,14 @@
+package plparser;
+
+public class NumberNode extends Property {
+	int value;
+	
+	public NumberNode(int i) {
+		value = i;
+	}
+	
+	public String toString() {
+		return "Number "+value;
+	}
+	
+}
--- a/src/plparser/Property.java	Sat Aug 28 16:07:00 2010 +0900
+++ b/src/plparser/Property.java	Sat Aug 28 17:39:34 2010 +0900
@@ -2,5 +2,17 @@
 
 public class Property {
 	String name;
-	Object value;
+	
+	public Property() {
+		
+	}
+	
+	public Property(String name2) {
+		name = name2;
+	}
+
+	public String toString() {
+		return name;
+	}
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/PropertyFactoryImpl.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,39 @@
+package plparser;
+
+import java.util.LinkedList;
+
+public class PropertyFactoryImpl implements PropertyListNodeFactory<Property> {
+
+	@Override
+	public Property variableNode(String name, boolean b) {
+		return new Property(name);
+	}
+
+	@Override
+	public Property numberNode(int i) {
+		return new NumberNode(i);
+	}
+
+	@Override
+	public Property booleanNode(TokenID id) {
+		return new BooleanProperty(id);
+	}
+	
+	@Override
+	public Property trueNode() {
+		// TODO Auto-generated method stub
+		return booleanNode(TokenID.True);
+	}
+
+	@Override
+	public Property arrayNode(LinkedList<Property> list1) {
+		return new ArrayProperty(list1);
+	}
+
+	@Override
+	public Property dictionaryNode(LinkedList<Property> list) {
+		return new DictProperty(list);
+	}
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/PropertyListNodeFactory.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,17 @@
+package plparser;
+
+import java.util.LinkedList;
+
+public interface PropertyListNodeFactory<Node> {
+
+	Node variableNode(String name, boolean b);
+
+	Node numberNode(int parseInt);
+
+	Node trueNode();
+
+	Node arrayNode(LinkedList<Node>list1);
+	Node dictionaryNode(LinkedList<Node>list);
+	Node booleanNode(TokenID id);
+
+}
--- /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);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/PropertyListScope.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,50 @@
+package plparser;
+
+import java.util.TreeMap;
+
+/*
+ * Scope mechanism for local variable
+ *    define("<>(x)","~(true& ~x)");
+ *    previous x token is stored in an association list
+ *    pop() remove local x token and restore previous x.
+ *    previous x may be null. We cannot use this scope
+ *    for quantifiers since our macro evaluator already
+ *    convert everything in symbols.
+ */
+public class PropertyListScope<Node> {
+	public TreeMap<String,Token<Node>> scope;
+	public Dictionary<Node> dict;
+	public PropertyListScope<Node> prev;
+	
+
+	public PropertyListScope(PropertyListScope<Node>prev, Dictionary<Node> dict) {
+		this.dict = dict;
+		this.prev = prev;
+		this.scope = new TreeMap<String,Token<Node>>();
+	}
+	
+
+	// enter the scope
+	public PropertyListScope<Node> push() {
+		return new PropertyListScope<Node>(this,dict);
+	}
+	
+	// exit the scope
+	public PropertyListScope<Node> pop() {
+		// restore local variable name
+		for(String name: scope.keySet()) {
+			Token<Node> t = scope.get(name);
+			dict.put(name, t); // overwrite
+		}
+		return prev;
+	}
+	
+	// make new local name in this scope
+	public Token<Node> getLocalName(String name) {
+		Token<Node> n = new Token<Node>(name);
+		Token<Node> t=dict.get(name);
+		scope.put(name, t); // remember original
+		dict.put(name,n);   // overwrite entry with new one
+		return n;
+	}
+}
\ No newline at end of file
--- a/src/plparser/Test.java	Sat Aug 28 16:07:00 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-package plparser;
-
-
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-
-public class Test {
-	
-	public static PropertyListScanner<Property> scan;
-
-	public static void main(String arg[]) {
-		initScanner();
-		if (arg.length==0) {
-			arg = new String[1];
-			arg[0] = "data/alias_article.plist";
-		}
-		for(String file: arg) {
-			try {
-				scan(new FileReader(file));
-			} catch (FileNotFoundException e) {
-				scan(file);
-			}
-		}
-	}
-	
-	public static void initScanner() {
-		Dictionary<Property> dict = new Dictionary<Property>();
-		scan = new PropertyListScanner<Property>(dict);
-	}
-
-
-	public static void scan(String exp) {
-		for(Token<Property> t : scan.scanToken(exp)) {
-			System.out.print(t+" ");
-		}
-		System.out.println();
-	}
-	
-	public static void scan(FileReader file) {
-		for(Token<Property> t : scan.scanToken(file)) {
-			System.out.print(t+" ");
-			System.out.println();
-		}
-	}
-	
-
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/TestParser.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,13 @@
+package plparser;
+
+
+public class TestParser {
+
+	public static void main(String arg[]) {
+		PropertyListParser<Property> p;
+		PropertyListNodeFactory<Property> lf = new PropertyFactoryImpl(); 
+		p = new PropertyListParser<Property>("{ a=b;}",lf);
+		Property n = p.parse();
+		if (n!=null) System.out.print(n); System.out.println(".");
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plparser/TestScanner.java	Sat Aug 28 17:39:34 2010 +0900
@@ -0,0 +1,47 @@
+package plparser;
+
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+
+public class TestScanner {
+	
+	public static PropertyListScanner<Property> scan;
+
+	public static void main(String arg[]) {
+		initScanner();
+		if (arg.length==0) {
+			arg = new String[1];
+			arg[0] = "data/alias_article.plist";
+		}
+		for(String file: arg) {
+			try {
+				scan(new FileReader(file));
+			} catch (FileNotFoundException e) {
+				scan(file);
+			}
+		}
+	}
+	
+	public static void initScanner() {
+		Dictionary<Property> dict = new Dictionary<Property>();
+		scan = new PropertyListScanner<Property>(dict);
+	}
+
+
+	public static void scan(String exp) {
+		for(Token<Property> t : scan.scanToken(exp)) {
+			System.out.print(t+" ");
+		}
+		System.out.println();
+	}
+	
+	public static void scan(FileReader file) {
+		for(Token<Property> t : scan.scanToken(file)) {
+			System.out.print(t+" ");
+			System.out.println();
+		}
+	}
+	
+
+}
\ No newline at end of file
--- a/src/plparser/Token.java	Sat Aug 28 16:07:00 2010 +0900
+++ b/src/plparser/Token.java	Sat Aug 28 17:39:34 2010 +0900
@@ -2,16 +2,50 @@
 
 
 public class Token<Node> {
-	String name;
-	TokenID type;
 	
 	
-
-	public Token(String name, TokenID type) {
-		this.name = name; this.type = type;
+	public String name;
+	public TokenID type;
+	public Node value;
+	public TokenID syntax;
+	public  int order;
+	public static int count = 0;
+	
+	public Token(String str) {
+		this(str,TokenID.UNKNOWN);
+	}
+	
+	public Token(String s, TokenID b) {
+		this.name=s;
+		this.type = b;
 	}
 
 
+	public String name() {
+		return name;
+	}
+
+	public boolean isVariable() {
+		return type==TokenID.VARIABLE;
+	}
+	
+	public void setVariable(boolean b) {
+		type = TokenID.VARIABLE;
+	}
+	
+	public boolean isVariableType() {
+		return type.isVariable();
+	}
+	
+	public Node value() {
+		return value;
+	}
+	
+	public void setValue(Node v) {
+		value = v;
+	}
+	
+	
 	public String toString() {
 		return "Token("+name+","+type+")";
 	}
--- a/src/plparser/TokenID.java	Sat Aug 28 16:07:00 2010 +0900
+++ b/src/plparser/TokenID.java	Sat Aug 28 17:39:34 2010 +0900
@@ -1,6 +1,10 @@
 package plparser;
 
 public enum TokenID {
-	NULL, Any, VARIABLE, NUMBER, STRING
+	NULL, Any, VARIABLE, NUMBER, STRING, UNKNOWN, Paren, CloseParen, CurParen, CloseCurParen, Comma, Semicolon, Assign, True, False;
+
+	public boolean isVariable() {
+		return this==VARIABLE;
+	}
 
 }