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