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