Mercurial > hg > Members > kono > PLparser
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; + } }