comparison 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
comparison
equal deleted inserted replaced
0:b0dee5b76b12 1:b149a5aa465a
1 package plparser;
2
3 import java.io.FileNotFoundException;
4 import java.io.InputStream;
5 import java.util.LinkedList;
6
7
8 public class PropertyListParser<Node extends Property> {
9 PropertyListNodeFactory<Node> lf;
10 Token<Node> nextToken;
11 public PropertyListScanner<Node> scanner;
12 private Dictionary<Node> dict;
13 // private PropertyListScope<Node> scope;
14
15 public PropertyListParser(String string,
16 PropertyListNodeFactory<Node> lf) {
17 this.lf = lf;
18 }
19
20 public void initReservedWord() {
21 dict.reserve("=",TokenID.Assign);
22 dict.reserve(",",TokenID.Comma);
23 dict.reserve(";",TokenID.Semicolon);
24 dict.reserve("(",TokenID.Paren);
25 dict.reserve(")",TokenID.CloseParen);
26 dict.reserve("{",TokenID.CurParen);
27 dict.reserve("}",TokenID.CloseCurParen);
28 dict.reserve("true",TokenID.True);
29 dict.reserve("false",TokenID.False);
30 }
31
32 public void initialize() {
33 dict = new Dictionary<Node>();
34 // scope = new PropertyListScope<Node>(null,dict);
35 initReservedWord();
36 scanner = new PropertyListScanner<Node>(dict);
37 }
38
39 public Node parse() {
40 if (scanner==null) return null;
41 nextToken();
42 return term();
43 }
44
45 public Node parse(String exp) {
46 Node n;
47 scanner = scanner.pushScanner(exp);
48 n = parse();
49 scanner = scanner.popScanner();
50 nextToken = scanner.nextToken;
51 return n;
52
53 }
54
55 public void parseFile(String file) {
56 try {
57 scanner = scanner.pushScannerFile(file);
58 } catch (FileNotFoundException e) {
59 error("Can't open "+file);
60 return;
61 }
62 doParse();
63 }
64
65 public void parse(InputStream file) {
66 scanner = scanner.pushScannerFile(file,null);
67 doParse();
68 }
69
70 public void parse(InputStream in, String prompt) {
71 scanner = scanner.pushScannerFile(in,prompt);
72 doParse();
73 }
74
75 public Node doParse() {
76 Node n;
77 do {
78 n=parse();
79 } while(scanner.hasRemaining());
80 scanner = scanner.popScanner();
81 nextToken = scanner.nextToken;
82 return n;
83 }
84
85 public LinkedList<Node> expr1() {
86 LinkedList<Node> list = new LinkedList<Node>();
87 expr2(list);
88 while(nextToken.type == TokenID.Semicolon) {
89 nextToken();
90 expr2(list);
91 }
92 return list;
93 }
94
95
96 public void expr2(LinkedList<Node>list) {
97 Node n1 = term();
98 if (nextToken.type!=TokenID.Assign) {
99 error("needs assignment");
100 return;
101 }
102 Node n2 = term();
103 list.add(n1); list.add(n2);
104 return;
105 }
106
107 public LinkedList<Node> expr3() {
108 LinkedList<Node>list = new LinkedList<Node>();
109 Node n1 = term();
110 list.add(n1);
111 while (nextToken.type==TokenID.Comma) {
112 Node n2 = term();
113 list.add(n2);
114 }
115 return list;
116 }
117
118 protected Node makeVariable(Token<Node> t) {
119 Node n;
120 if ((n=t.value())==null) {
121 n = lf.variableNode(t.name(),true);
122 t.setValue(n);
123 }
124 // n.token = t;
125 return n;
126 }
127
128 protected Node term() {
129 Node n = null;
130 switch (nextToken.type) {
131 case Paren: // Array
132 nextToken();
133 LinkedList<Node>list1 = expr3();
134 if (nextToken.type==TokenID.CloseParen) {
135 } else { // syntax error;
136 scanner.error(") expected but got "+nextToken);
137 return lf.trueNode();
138 }
139 return lf.arrayNode(list1);
140 case CurParen: // Dictionary
141 nextToken();
142 LinkedList<Node> list = expr1();
143 if (nextToken.type==TokenID.CloseCurParen) {
144 } else { // syntax error;
145 scanner.error("} expected");
146 }
147 return lf.dictionaryNode(list);
148 case NUMBER:
149 n = lf.numberNode(Integer.parseInt(nextToken.name));
150 break;
151 case NULL:
152 break;
153 default:
154 if (nextToken.type.isVariable())
155 n = makeVariable(nextToken);
156 else {
157 // error("Internal ununderstandable term '"+nextToken+"' type: "+nextToken.type+".");
158 n = makeVariable(nextToken); // skip any
159 }
160 }
161 nextToken();
162 return n;
163 }
164
165
166 /*
167 * Syntactical Short cut for scanner.textToken()
168 *
169 * It never returns null, to check EOF,
170 * nextToken.type==TokenID.NULL
171 */
172 public Token<Node> nextToken() {
173 return nextToken = scanner.nextToken();
174 }
175
176
177 public void error(String err) {
178 scanner.error(err);
179 }
180 }