KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jvyamlb > ParserImpl


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2007 Ola Bini <ola@ologix.com>
15  *
16  * Alternatively, the contents of this file may be used under the terms of
17  * either of the GNU General Public License Version 2 or later (the "GPL"),
18  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19  * in which case the provisions of the GPL or the LGPL are applicable instead
20  * of those above. If you wish to allow use of your version of this file only
21  * under the terms of either the GPL or the LGPL, and not to allow others to
22  * use your version of this file under the terms of the CPL, indicate your
23  * decision by deleting the provisions above and replace them with the notice
24  * and other provisions required by the GPL or the LGPL. If you do not delete
25  * the provisions above, a recipient may use your version of this file under
26  * the terms of any one of the CPL, the GPL or the LGPL.
27  ***** END LICENSE BLOCK *****/

28 package org.jvyamlb;
29
30 import java.io.InputStream JavaDoc;
31 import java.io.FileInputStream JavaDoc;
32
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38
39 import org.jvyamlb.events.*;
40 import org.jvyamlb.tokens.*;
41
42 import org.jruby.util.ByteList;
43
44 /**
45  * @author <a HREF="mailto:ola.bini@ki.se">Ola Bini</a>
46  */

47 public class ParserImpl implements Parser {
48     // Memnonics for the production table
49
private final static int P_STREAM = 0;
50     private final static int P_STREAM_START = 1; // TERMINAL
51
private final static int P_STREAM_END = 2; // TERMINAL
52
private final static int P_IMPLICIT_DOCUMENT = 3;
53     private final static int P_EXPLICIT_DOCUMENT = 4;
54     private final static int P_DOCUMENT_START = 5;
55     private final static int P_DOCUMENT_START_IMPLICIT = 6;
56     private final static int P_DOCUMENT_END = 7;
57     private final static int P_BLOCK_NODE = 8;
58     private final static int P_BLOCK_CONTENT = 9;
59     private final static int P_PROPERTIES = 10;
60     private final static int P_PROPERTIES_END = 11;
61     private final static int P_FLOW_CONTENT = 12;
62     private final static int P_BLOCK_SEQUENCE = 13;
63     private final static int P_BLOCK_MAPPING = 14;
64     private final static int P_FLOW_SEQUENCE = 15;
65     private final static int P_FLOW_MAPPING = 16;
66     private final static int P_SCALAR = 17;
67     private final static int P_BLOCK_SEQUENCE_ENTRY = 18;
68     private final static int P_BLOCK_MAPPING_ENTRY = 19;
69     private final static int P_BLOCK_MAPPING_ENTRY_VALUE = 20;
70     private final static int P_BLOCK_NODE_OR_INDENTLESS_SEQUENCE = 21;
71     private final static int P_BLOCK_SEQUENCE_START = 22;
72     private final static int P_BLOCK_SEQUENCE_END = 23;
73     private final static int P_BLOCK_MAPPING_START = 24;
74     private final static int P_BLOCK_MAPPING_END = 25;
75     private final static int P_INDENTLESS_BLOCK_SEQUENCE = 26;
76     private final static int P_BLOCK_INDENTLESS_SEQUENCE_START = 27;
77     private final static int P_INDENTLESS_BLOCK_SEQUENCE_ENTRY = 28;
78     private final static int P_BLOCK_INDENTLESS_SEQUENCE_END = 29;
79     private final static int P_FLOW_SEQUENCE_START = 30;
80     private final static int P_FLOW_SEQUENCE_ENTRY = 31;
81     private final static int P_FLOW_SEQUENCE_END = 32;
82     private final static int P_FLOW_MAPPING_START = 33;
83     private final static int P_FLOW_MAPPING_ENTRY = 34;
84     private final static int P_FLOW_MAPPING_END = 35;
85     private final static int P_FLOW_INTERNAL_MAPPING_START = 36;
86     private final static int P_FLOW_INTERNAL_CONTENT = 37;
87     private final static int P_FLOW_INTERNAL_VALUE = 38;
88     private final static int P_FLOW_INTERNAL_MAPPING_END = 39;
89     private final static int P_FLOW_ENTRY_MARKER = 40;
90     private final static int P_FLOW_NODE = 41;
91     private final static int P_FLOW_MAPPING_INTERNAL_CONTENT = 42;
92     private final static int P_FLOW_MAPPING_INTERNAL_VALUE = 43;
93     private final static int P_ALIAS = 44;
94     private final static int P_EMPTY_SCALAR = 45;
95
96     private final static Event DOCUMENT_END_TRUE = new DocumentEndEvent(true);
97     private final static Event DOCUMENT_END_FALSE = new DocumentEndEvent(false);
98     private final static Event MAPPING_END = new MappingEndEvent();
99     private final static Event SEQUENCE_END = new SequenceEndEvent();
100     private final static Event STREAM_END = new StreamEndEvent();
101     private final static Event STREAM_START = new StreamStartEvent();
102
103     private static class ProductionEnvironment {
104         private List JavaDoc tags;
105         private List JavaDoc anchors;
106         private Map JavaDoc tagHandles;
107         private int[] yamlVersion;
108         private int[] defaultYamlVersion;
109
110         public ProductionEnvironment(final YAMLConfig cfg) {
111             this.tags = new LinkedList JavaDoc();
112             this.anchors = new LinkedList JavaDoc();
113             this.tagHandles = new HashMap JavaDoc();
114             this.yamlVersion = null;
115             this.defaultYamlVersion = new int[2];
116             this.defaultYamlVersion[0] = Integer.parseInt(cfg.version().substring(0,cfg.version().indexOf('.')));
117             this.defaultYamlVersion[1] = Integer.parseInt(cfg.version().substring(cfg.version().indexOf('.')+1));
118         }
119
120         public List JavaDoc getTags() {
121             return this.tags;
122         }
123
124         public List JavaDoc getAnchors() {
125             return this.anchors;
126         }
127
128         public Map JavaDoc getTagHandles() {
129             return this.tagHandles;
130         }
131
132         public int[] getYamlVersion() {
133             return this.yamlVersion;
134         }
135
136         public int[] getFinalYamlVersion() {
137             if(null == this.yamlVersion) {
138                 return this.defaultYamlVersion;
139             }
140             return this.yamlVersion;
141         }
142
143         public void setYamlVersion(final int[] yamlVersion) {
144             this.yamlVersion = yamlVersion;
145         }
146     }
147
148     private static interface Production {
149         Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner);
150     }
151
152     private final static Production[] P_TABLE = new Production[46];
153
154     private final static Map JavaDoc DEFAULT_TAGS_1_0 = new HashMap JavaDoc();
155     private final static Map JavaDoc DEFAULT_TAGS_1_1 = new HashMap JavaDoc();
156     static {
157         DEFAULT_TAGS_1_0.put("!","tag:yaml.org,2002:");
158
159         DEFAULT_TAGS_1_1.put("!","!");
160         DEFAULT_TAGS_1_1.put("!!","tag:yaml.org,2002:");
161     }
162
163     static {
164         P_TABLE[P_STREAM] = new Production() {
165                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
166                     parseStack.add(0,P_TABLE[P_STREAM_END]);
167                     parseStack.add(0,P_TABLE[P_EXPLICIT_DOCUMENT]);
168                     parseStack.add(0,P_TABLE[P_IMPLICIT_DOCUMENT]);
169                     parseStack.add(0,P_TABLE[P_STREAM_START]);
170                     return null;
171                 }
172             };
173         P_TABLE[P_STREAM_START] = new Production() {
174                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
175                     scanner.getToken();
176                     return STREAM_START;
177                 }
178             };
179         P_TABLE[P_STREAM_END] = new Production() {
180                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
181                     scanner.getToken();
182                     return STREAM_END;
183                 }
184             };
185         P_TABLE[P_IMPLICIT_DOCUMENT] = new Production() {
186                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
187                     final Token curr = scanner.peekToken();
188                     if(!(curr instanceof DirectiveToken || curr instanceof DocumentStartToken || curr instanceof StreamEndToken)) {
189                         parseStack.add(0,P_TABLE[P_DOCUMENT_END]);
190                         parseStack.add(0,P_TABLE[P_BLOCK_NODE]);
191                         parseStack.add(0,P_TABLE[P_DOCUMENT_START_IMPLICIT]);
192                     }
193                     return null;
194                 }
195             };
196         P_TABLE[P_EXPLICIT_DOCUMENT] = new Production() {
197                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
198                     if(!(scanner.peekToken() instanceof StreamEndToken)) {
199                         parseStack.add(0,P_TABLE[P_EXPLICIT_DOCUMENT]);
200                         parseStack.add(0,P_TABLE[P_DOCUMENT_END]);
201                         parseStack.add(0,P_TABLE[P_BLOCK_NODE]);
202                         parseStack.add(0,P_TABLE[P_DOCUMENT_START]);
203                     }
204                     return null;
205                 }
206             };
207         P_TABLE[P_DOCUMENT_START] = new Production() {
208                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
209                     Token tok = scanner.peekToken();
210                     final Object JavaDoc[] directives = processDirectives(env,scanner);
211                     if(!(scanner.peekToken() instanceof DocumentStartToken)) {
212                         throw new ParserException(null,"expected '<document start>', but found " + tok.getClass().getName(),null);
213                     }
214                     scanner.getToken();
215                     return new DocumentStartEvent(true,(int[])directives[0],(Map JavaDoc)directives[1]);
216                 }
217             };
218         P_TABLE[P_DOCUMENT_START_IMPLICIT] = new Production() {
219                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
220                     final Object JavaDoc[] directives = processDirectives(env,scanner);
221                     return new DocumentStartEvent(false,(int[])directives[0],(Map JavaDoc)directives[1]);
222                 }
223             };
224         P_TABLE[P_DOCUMENT_END] = new Production() {
225                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
226                     Token tok = scanner.peekToken();
227                     boolean explicit = false;
228                     while(scanner.peekToken() instanceof DocumentEndToken) {
229                         scanner.getToken();
230                         explicit = true;
231                     }
232                     return explicit ? DOCUMENT_END_TRUE : DOCUMENT_END_FALSE;
233                 }
234             };
235         P_TABLE[P_BLOCK_NODE] = new Production() {
236                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
237                     final Token curr = scanner.peekToken();
238                     if(curr instanceof DirectiveToken || curr instanceof DocumentStartToken || curr instanceof DocumentEndToken || curr instanceof StreamEndToken) {
239                         parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
240                     } else {
241                         if(curr instanceof AliasToken) {
242                             parseStack.add(0,P_TABLE[P_ALIAS]);
243                         } else {
244                             parseStack.add(0,P_TABLE[P_PROPERTIES_END]);
245                             parseStack.add(0,P_TABLE[P_BLOCK_CONTENT]);
246                             parseStack.add(0,P_TABLE[P_PROPERTIES]);
247                         }
248                     }
249                     return null;
250                 }
251             };
252         P_TABLE[P_BLOCK_CONTENT] = new Production() {
253                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
254                     final Token tok = scanner.peekToken();
255                     if(tok instanceof BlockSequenceStartToken) {
256                         parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE]);
257                     } else if(tok instanceof BlockMappingStartToken) {
258                         parseStack.add(0,P_TABLE[P_BLOCK_MAPPING]);
259                     } else if(tok instanceof FlowSequenceStartToken) {
260                         parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE]);
261                     } else if(tok instanceof FlowMappingStartToken) {
262                         parseStack.add(0,P_TABLE[P_FLOW_MAPPING]);
263                     } else if(tok instanceof ScalarToken) {
264                         parseStack.add(0,P_TABLE[P_SCALAR]);
265                     } else {
266                         throw new ParserException("while scanning a node","expected the node content, but found " + tok.getClass().getName(),null);
267                     }
268                     return null;
269                 }
270             };
271         P_TABLE[P_PROPERTIES] = new Production() {
272                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
273                     String JavaDoc anchor = null;
274                     Object JavaDoc tag = null;
275                     if(scanner.peekToken() instanceof AnchorToken) {
276                         anchor = ((AnchorToken)scanner.getToken()).getValue();
277                         if(scanner.peekToken() instanceof TagToken) {
278                             scanner.getToken();
279                         }
280                     } else if(scanner.peekToken() instanceof TagToken) {
281                         tag = ((TagToken)scanner.getToken()).getValue();
282                         if(scanner.peekToken() instanceof AnchorToken) {
283                             anchor = ((AnchorToken)scanner.getToken()).getValue();
284                         }
285                     }
286                     if(tag != null && !tag.equals("!")) {
287                         final String JavaDoc handle = ScannerImpl.into(((ByteList[])tag)[0]);
288                         final String JavaDoc suffix = ScannerImpl.into(((ByteList[])tag)[1]);
289                         if(handle != null) {
290                             if(!env.getTagHandles().containsKey(handle)) {
291                                 throw new ParserException("while parsing a node","found undefined tag handle " + handle,null);
292                             }
293                             tag = ((String JavaDoc)env.getTagHandles().get(handle)) + suffix;
294                         } else {
295                             tag = suffix;
296                         }
297                     }
298                     env.getAnchors().add(0,anchor);
299                     env.getTags().add(0,tag);
300                     return null;
301                 }
302             };
303         P_TABLE[P_PROPERTIES_END] = new Production() {
304                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
305                     env.getAnchors().remove(0);
306                     env.getTags().remove(0);
307                     return null;
308                 }
309             };
310         P_TABLE[P_FLOW_CONTENT] = new Production() {
311                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
312                     final Token tok = scanner.peekToken();
313                     if(tok instanceof FlowSequenceStartToken) {
314                         parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE]);
315                     } else if(tok instanceof FlowMappingStartToken) {
316                         parseStack.add(0,P_TABLE[P_FLOW_MAPPING]);
317                     } else if(tok instanceof ScalarToken) {
318                         parseStack.add(0,P_TABLE[P_SCALAR]);
319                     } else {
320                         throw new ParserException("while scanning a flow node","expected the node content, but found " + tok.getClass().getName(),null);
321                     }
322                     return null;
323                 }
324             };
325         P_TABLE[P_BLOCK_SEQUENCE] = new Production() {
326                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
327                     parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE_END]);
328                     parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE_ENTRY]);
329                     parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE_START]);
330                     return null;
331                 }
332             };
333         P_TABLE[P_BLOCK_MAPPING] = new Production() {
334                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
335                     parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_END]);
336                     parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY]);
337                     parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_START]);
338                     return null;
339                 }
340             };
341         P_TABLE[P_FLOW_SEQUENCE] = new Production() {
342                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
343                     parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE_END]);
344                     parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE_ENTRY]);
345                     parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE_START]);
346                     return null;
347                 }
348             };
349         P_TABLE[P_FLOW_MAPPING] = new Production() {
350                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
351                     parseStack.add(0,P_TABLE[P_FLOW_MAPPING_END]);
352                     parseStack.add(0,P_TABLE[P_FLOW_MAPPING_ENTRY]);
353                     parseStack.add(0,P_TABLE[P_FLOW_MAPPING_START]);
354                     return null;
355                 }
356             };
357         P_TABLE[P_SCALAR] = new Production() {
358                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
359                     final ScalarToken tok = (ScalarToken)scanner.getToken();
360                     boolean[] implicit = null;
361                     if((tok.getPlain() && env.getTags().get(0) == null) || "!".equals(env.getTags().get(0))) {
362                         implicit = new boolean[]{true,false};
363                     } else if(env.getTags().get(0) == null) {
364                         implicit = new boolean[]{false,true};
365                     } else {
366                         implicit = new boolean[]{false,false};
367                     }
368                     return new ScalarEvent((String JavaDoc)env.getAnchors().get(0),(String JavaDoc)env.getTags().get(0),implicit,tok.getValue(),tok.getStyle());
369                 }
370             };
371         P_TABLE[P_BLOCK_SEQUENCE_ENTRY] = new Production() {
372                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
373                     if(scanner.peekToken() instanceof BlockEntryToken) {
374                         scanner.getToken();
375                         if(!(scanner.peekToken() instanceof BlockEntryToken || scanner.peekToken() instanceof BlockEndToken)) {
376                             parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE_ENTRY]);
377                             parseStack.add(0,P_TABLE[P_BLOCK_NODE]);
378                         } else {
379                             parseStack.add(0,P_TABLE[P_BLOCK_SEQUENCE_ENTRY]);
380                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
381                         }
382                     }
383                     return null;
384                 }
385             };
386         P_TABLE[P_BLOCK_MAPPING_ENTRY] = new Production() {
387                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
388                     if(scanner.peekToken() instanceof KeyToken || scanner.peekToken() instanceof ValueToken) {
389                         if(scanner.peekToken() instanceof KeyToken) {
390                             scanner.getToken();
391                             final Token curr = scanner.peekToken();
392                             if(!(curr instanceof KeyToken || curr instanceof ValueToken || curr instanceof BlockEndToken)) {
393                                 parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY]);
394                                 parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY_VALUE]);
395                                 parseStack.add(0,P_TABLE[P_BLOCK_NODE_OR_INDENTLESS_SEQUENCE]);
396                             } else {
397                                 parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY]);
398                                 parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY_VALUE]);
399                                 parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
400                             }
401                         } else {
402                             parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY]);
403                             parseStack.add(0,P_TABLE[P_BLOCK_MAPPING_ENTRY_VALUE]);
404                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
405                         }
406                     }
407                     return null;
408                 }
409             };
410         P_TABLE[P_BLOCK_MAPPING_ENTRY_VALUE] = new Production() {
411                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
412                     if(scanner.peekToken() instanceof KeyToken || scanner.peekToken() instanceof ValueToken) {
413                         if(scanner.peekToken() instanceof ValueToken) {
414                             scanner.getToken();
415                             final Token curr = scanner.peekToken();
416                             if(!(curr instanceof KeyToken || curr instanceof ValueToken || curr instanceof BlockEndToken)) {
417                                 parseStack.add(0,P_TABLE[P_BLOCK_NODE_OR_INDENTLESS_SEQUENCE]);
418                             } else {
419                                 parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
420                             }
421                         } else {
422                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
423                         }
424                     }
425                     return null;
426                 }
427             };
428         P_TABLE[P_BLOCK_NODE_OR_INDENTLESS_SEQUENCE] = new Production() {
429                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
430                     if(scanner.peekToken() instanceof AliasToken) {
431                         parseStack.add(0,P_TABLE[P_ALIAS]);
432                     } else {
433                         if(scanner.peekToken() instanceof BlockEntryToken) {
434                             parseStack.add(0,P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE]);
435                             parseStack.add(0,P_TABLE[P_PROPERTIES]);
436                         } else {
437                             parseStack.add(0,P_TABLE[P_BLOCK_CONTENT]);
438                             parseStack.add(0,P_TABLE[P_PROPERTIES]);
439                         }
440                     }
441                     return null;
442                 }
443             };
444         P_TABLE[P_BLOCK_SEQUENCE_START] = new Production() {
445                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
446                     final boolean implicit = env.getTags().get(0) == null || env.getTags().get(0).equals("!");
447                     scanner.getToken();
448                     return new SequenceStartEvent((String JavaDoc)env.getAnchors().get(0), (String JavaDoc)env.getTags().get(0), implicit,false);
449                 }
450             };
451         P_TABLE[P_BLOCK_SEQUENCE_END] = new Production() {
452                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
453                     Token tok = null;
454                     if(!(scanner.peekToken() instanceof BlockEndToken)) {
455                         tok = scanner.peekToken();
456                         throw new ParserException("while scanning a block collection","expected <block end>, but found " + tok.getClass().getName(),null);
457                     }
458                     scanner.getToken();
459                     return SEQUENCE_END;
460                 }
461             };
462         P_TABLE[P_BLOCK_MAPPING_START] = new Production() {
463                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
464                     final boolean implicit = env.getTags().get(0) == null || env.getTags().get(0).equals("!");
465                     scanner.getToken();
466                     return new MappingStartEvent((String JavaDoc)env.getAnchors().get(0), (String JavaDoc)env.getTags().get(0), implicit,false);
467                 }
468             };
469         P_TABLE[P_BLOCK_MAPPING_END] = new Production() {
470                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
471                     Token tok = null;
472                     if(!(scanner.peekToken() instanceof BlockEndToken)) {
473                         tok = scanner.peekToken();
474                         throw new ParserException("while scanning a block mapping","expected <block end>, but found " + tok.getClass().getName(),null);
475                     }
476                     scanner.getToken();
477                     return MAPPING_END;
478                 }
479             };
480         P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE] = new Production() {
481                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
482                     parseStack.add(0,P_TABLE[P_BLOCK_INDENTLESS_SEQUENCE_END]);
483                     parseStack.add(0,P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE_ENTRY]);
484                     parseStack.add(0,P_TABLE[P_BLOCK_INDENTLESS_SEQUENCE_START]);
485                     return null;
486                 }
487             };
488         P_TABLE[P_BLOCK_INDENTLESS_SEQUENCE_START] = new Production() {
489                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
490                     final boolean implicit = env.getTags().get(0) == null || env.getTags().get(0).equals("!");
491                     return new SequenceStartEvent((String JavaDoc)env.getAnchors().get(0), (String JavaDoc)env.getTags().get(0), implicit, false);
492                 }
493             };
494         P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE_ENTRY] = new Production() {
495                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
496                     if(scanner.peekToken() instanceof BlockEntryToken) {
497                         scanner.getToken();
498                         final Token curr = scanner.peekToken();
499                         if(!(curr instanceof BlockEntryToken || curr instanceof KeyToken || curr instanceof ValueToken || curr instanceof BlockEndToken)) {
500                             parseStack.add(0,P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE_ENTRY]);
501                             parseStack.add(0,P_TABLE[P_BLOCK_NODE]);
502                         } else {
503                             parseStack.add(0,P_TABLE[P_INDENTLESS_BLOCK_SEQUENCE_ENTRY]);
504                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
505                         }
506                     }
507                     return null;
508                 }
509             };
510         P_TABLE[P_BLOCK_INDENTLESS_SEQUENCE_END] = new Production() {
511                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
512                     return SEQUENCE_END;
513                 }
514             };
515         P_TABLE[P_FLOW_SEQUENCE_START] = new Production() {
516                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
517                     final boolean implicit = env.getTags().get(0) == null || env.getTags().get(0).equals("!");
518                     scanner.getToken();
519                     return new SequenceStartEvent((String JavaDoc)env.getAnchors().get(0), (String JavaDoc)env.getTags().get(0), implicit,true);
520                 }
521             };
522         P_TABLE[P_FLOW_SEQUENCE_ENTRY] = new Production() {
523                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
524                     if(!(scanner.peekToken() instanceof FlowSequenceEndToken)) {
525                         if(scanner.peekToken() instanceof KeyToken) {
526                             parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE_ENTRY]);
527                             parseStack.add(0,P_TABLE[P_FLOW_ENTRY_MARKER]);
528                             parseStack.add(0,P_TABLE[P_FLOW_INTERNAL_MAPPING_END]);
529                             parseStack.add(0,P_TABLE[P_FLOW_INTERNAL_VALUE]);
530                             parseStack.add(0,P_TABLE[P_FLOW_INTERNAL_CONTENT]);
531                             parseStack.add(0,P_TABLE[P_FLOW_INTERNAL_MAPPING_START]);
532                         } else {
533                             parseStack.add(0,P_TABLE[P_FLOW_SEQUENCE_ENTRY]);
534                             parseStack.add(0,P_TABLE[P_FLOW_NODE]);
535                             parseStack.add(0,P_TABLE[P_FLOW_ENTRY_MARKER]);
536                         }
537                     }
538                     return null;
539                 }
540             };
541         P_TABLE[P_FLOW_SEQUENCE_END] = new Production() {
542                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
543                     scanner.getToken();
544                     return SEQUENCE_END;
545                 }
546             };
547         P_TABLE[P_FLOW_MAPPING_START] = new Production() {
548                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
549                     final boolean implicit = env.getTags().get(0) == null || env.getTags().get(0).equals("!");
550                     scanner.getToken();
551                     return new MappingStartEvent((String JavaDoc)env.getAnchors().get(0), (String JavaDoc)env.getTags().get(0), implicit,true);
552                 }
553             };
554         P_TABLE[P_FLOW_MAPPING_ENTRY] = new Production() {
555                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
556                     if(!(scanner.peekToken() instanceof FlowMappingEndToken)) {
557                         if(scanner.peekToken() instanceof KeyToken) {
558                             parseStack.add(0,P_TABLE[P_FLOW_MAPPING_ENTRY]);
559                             parseStack.add(0,P_TABLE[P_FLOW_ENTRY_MARKER]);
560                             parseStack.add(0,P_TABLE[P_FLOW_MAPPING_INTERNAL_VALUE]);
561                             parseStack.add(0,P_TABLE[P_FLOW_MAPPING_INTERNAL_CONTENT]);
562                         } else {
563                             parseStack.add(0,P_TABLE[P_FLOW_MAPPING_ENTRY]);
564                             parseStack.add(0,P_TABLE[P_FLOW_NODE]);
565                             parseStack.add(0,P_TABLE[P_FLOW_ENTRY_MARKER]);
566                         }
567                     }
568                     return null;
569                 }
570             };
571         P_TABLE[P_FLOW_MAPPING_END] = new Production() {
572                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
573                     scanner.getToken();
574                     return MAPPING_END;
575                 }
576             };
577         P_TABLE[P_FLOW_INTERNAL_MAPPING_START] = new Production() {
578                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
579                     scanner.getToken();
580                     return new MappingStartEvent(null,null,true,true);
581                 }
582             };
583         P_TABLE[P_FLOW_INTERNAL_CONTENT] = new Production() {
584                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
585                     final Token curr = scanner.peekToken();
586                     if(!(curr instanceof ValueToken || curr instanceof FlowEntryToken || curr instanceof FlowSequenceEndToken)) {
587                         parseStack.add(0,P_TABLE[P_FLOW_NODE]);
588                     } else {
589                         parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
590                     }
591                     return null;
592                 }
593             };
594         P_TABLE[P_FLOW_INTERNAL_VALUE] = new Production() {
595                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
596                     if(scanner.peekToken() instanceof ValueToken) {
597                         scanner.getToken();
598                         if(!((scanner.peekToken() instanceof FlowEntryToken) || (scanner.peekToken() instanceof FlowSequenceEndToken))) {
599                             parseStack.add(0,P_TABLE[P_FLOW_NODE]);
600                         } else {
601                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
602                         }
603                     } else {
604                         parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
605                     }
606                     return null;
607                 }
608             };
609         P_TABLE[P_FLOW_INTERNAL_MAPPING_END] = new Production() {
610                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
611                     return MAPPING_END;
612                 }
613             };
614         P_TABLE[P_FLOW_ENTRY_MARKER] = new Production() {
615                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
616                     if(scanner.peekToken() instanceof FlowEntryToken) {
617                         scanner.getToken();
618                     }
619                     return null;
620                 }
621             };
622         P_TABLE[P_FLOW_NODE] = new Production() {
623                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
624                     if(scanner.peekToken() instanceof AliasToken) {
625                         parseStack.add(0,P_TABLE[P_ALIAS]);
626                     } else {
627                         parseStack.add(0,P_TABLE[P_PROPERTIES_END]);
628                         parseStack.add(0,P_TABLE[P_FLOW_CONTENT]);
629                         parseStack.add(0,P_TABLE[P_PROPERTIES]);
630                     }
631                     return null;
632                 }
633             };
634         P_TABLE[P_FLOW_MAPPING_INTERNAL_CONTENT] = new Production() {
635                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
636                     final Token curr = scanner.peekToken();
637                     if(!(curr instanceof ValueToken || curr instanceof FlowEntryToken || curr instanceof FlowMappingEndToken)) {
638                         scanner.getToken();
639                         parseStack.add(0,P_TABLE[P_FLOW_NODE]);
640                     } else {
641                         parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
642                     }
643                     return null;
644                 }
645             };
646         P_TABLE[P_FLOW_MAPPING_INTERNAL_VALUE] = new Production() {
647                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
648                     if(scanner.peekToken() instanceof ValueToken) {
649                         scanner.getToken();
650                         if(!(scanner.peekToken() instanceof FlowEntryToken || scanner.peekToken() instanceof FlowMappingEndToken)) {
651                             parseStack.add(0,P_TABLE[P_FLOW_NODE]);
652                         } else {
653                             parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
654                         }
655                     } else {
656                         parseStack.add(0,P_TABLE[P_EMPTY_SCALAR]);
657                     }
658                     return null;
659                 }
660             };
661         P_TABLE[P_ALIAS] = new Production() {
662                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
663                     final AliasToken tok = (AliasToken)scanner.getToken();
664                     return new AliasEvent(tok.getValue());
665                 }
666             };
667         P_TABLE[P_EMPTY_SCALAR] = new Production() {
668                 public Event produce(final List JavaDoc parseStack, final ProductionEnvironment env, final Scanner scanner) {
669                     return processEmptyScalar();
670                 }
671             };
672     }
673
674     private static Event processEmptyScalar() {
675         return new ScalarEvent(null,null,new boolean[]{true,false},new ByteList(ByteList.NULL_ARRAY),(char)0);
676     }
677
678     private static Object JavaDoc[] processDirectives(final ProductionEnvironment env, final Scanner scanner) {
679         while(scanner.peekToken() instanceof DirectiveToken) {
680             final DirectiveToken tok = (DirectiveToken)scanner.getToken();
681             if(tok.getName().equals("YAML")) {
682                 if(env.getYamlVersion() != null) {
683                     throw new ParserException(null,"found duplicate YAML directive",null);
684                 }
685                 final int major = Integer.parseInt(tok.getValue()[0]);
686                 final int minor = Integer.parseInt(tok.getValue()[1]);
687                 if(major != 1) {
688                     throw new ParserException(null,"found incompatible YAML document (version 1.* is required)",null);
689                 }
690                 env.setYamlVersion(new int[]{major,minor});
691             } else if(tok.getName().equals("TAG")) {
692                 final String JavaDoc handle = tok.getValue()[0];
693                 final String JavaDoc prefix = tok.getValue()[1];
694                 if(env.getTagHandles().containsKey(handle)) {
695                     throw new ParserException(null,"duplicate tag handle " + handle,null);
696                 }
697                 env.getTagHandles().put(handle,prefix);
698             }
699         }
700         Object JavaDoc[] value = new Object JavaDoc[2];
701         value[0] = env.getFinalYamlVersion();
702
703         if(!env.getTagHandles().isEmpty()) {
704             value[1] = new HashMap JavaDoc(env.getTagHandles());
705         }
706
707         final Map JavaDoc baseTags = ((int[])value[0])[1] == 0 ? DEFAULT_TAGS_1_0 : DEFAULT_TAGS_1_1;
708         for(final Iterator JavaDoc iter = baseTags.keySet().iterator();iter.hasNext();) {
709             final Object JavaDoc key = iter.next();
710             if(!env.getTagHandles().containsKey(key)) {
711                 env.getTagHandles().put(key,baseTags.get(key));
712             }
713         }
714         return value;
715     }
716
717     private Scanner scanner = null;
718     private YAMLConfig cfg = null;
719
720     public ParserImpl(final Scanner scanner) {
721         this(scanner, YAML.config());
722     }
723
724     public ParserImpl(final Scanner scanner, final YAMLConfig cfg) {
725         this.scanner = scanner;
726         this.cfg = cfg;
727     }
728
729     private Event currentEvent = null;
730
731     public boolean checkEvent(final Class JavaDoc[] choices) {
732         parseStream();
733         if(this.currentEvent == null) {
734             this.currentEvent = parseStreamNext();
735         }
736         if(this.currentEvent != null) {
737             if(choices.length == 0) {
738                 return true;
739             }
740             for(int i=0,j=choices.length;i<j;i++) {
741                 if(choices[i].isInstance(this.currentEvent)) {
742                     return true;
743                 }
744             }
745         }
746         return false;
747     }
748
749     public Event peekEvent() {
750         parseStream();
751         if(this.currentEvent == null) {
752             this.currentEvent = parseStreamNext();
753         }
754         return this.currentEvent;
755     }
756
757     public Event getEvent() {
758         parseStream();
759         if(this.currentEvent == null) {
760             this.currentEvent = parseStreamNext();
761         }
762         final Event value = this.currentEvent;
763         this.currentEvent = null;
764         return value;
765     }
766
767     private class EventIterator implements Iterator JavaDoc {
768         public boolean hasNext() {
769             return null != peekEvent();
770         }
771
772         public Object JavaDoc next() {
773             return getEvent();
774         }
775
776         public void remove() {
777         }
778     }
779
780     public Iterator JavaDoc eachEvent() {
781         return new EventIterator();
782     }
783
784     public Iterator JavaDoc iterator() {
785         return eachEvent();
786     }
787
788     private List JavaDoc parseStack = null;
789     private ProductionEnvironment pEnv = null;
790
791     public void parseStream() {
792         if(null == parseStack) {
793             this.parseStack = new LinkedList JavaDoc();
794             this.parseStack.add(0,P_TABLE[P_STREAM]);
795             this.pEnv = new ProductionEnvironment(cfg);
796         }
797     }
798
799     public Event parseStreamNext() {
800         while(!parseStack.isEmpty()) {
801             final Event value = ((Production)(this.parseStack.remove(0))).produce(this.parseStack,this.pEnv,this.scanner);
802             if(null != value) {
803                 return value;
804             }
805         }
806         this.pEnv = null;
807         return null;
808     }
809
810     public static void main(final String JavaDoc[] args) throws Exception JavaDoc {
811         final String JavaDoc filename = args[0];
812         System.out.println("Reading of file: \"" + filename + "\"");
813
814         final ByteList input = new ByteList(1024);
815         final InputStream JavaDoc reader = new FileInputStream JavaDoc(filename);
816         byte[] buff = new byte[1024];
817         int read = 0;
818         while(true) {
819             read = reader.read(buff);
820             input.append(buff,0,read);
821             if(read < 1024) {
822                 break;
823             }
824         }
825         reader.close();
826         final long before = System.currentTimeMillis();
827         for(int i=0;i<1;i++) {
828             final Parser pars = new ParserImpl(new ScannerImpl(input));
829             for(final Iterator JavaDoc iter = pars.eachEvent();iter.hasNext();iter.next()) {
830             }
831         }
832         final long after = System.currentTimeMillis();
833         final long time = after-before;
834         final double timeS = (after-before)/1000.0;
835         System.out.println("Walking through the events for the file: " + filename + " took " + time + "ms, or " + timeS + " seconds");
836     }
837
838     public static void tmain(final String JavaDoc[] args) throws Exception JavaDoc {
839         final String JavaDoc filename = args[0];
840         System.out.println("Reading of file: \"" + filename + "\"");
841
842         final InputStream JavaDoc reader = new FileInputStream JavaDoc(filename);
843         final long before = System.currentTimeMillis();
844         for(int i=0;i<1;i++) {
845             final Parser pars = new ParserImpl(new ScannerImpl(reader));
846             for(final Iterator JavaDoc iter = pars.eachEvent();iter.hasNext();iter.next()) {
847             }
848         }
849         reader.close();
850         final long after = System.currentTimeMillis();
851         final long time = after-before;
852         final double timeS = (after-before)/1000.0;
853         System.out.println("Walking through the events for the file: " + filename + " took " + time + "ms, or " + timeS + " seconds");
854     }
855
856     public static void tmain2(final String JavaDoc[] args) throws Exception JavaDoc {
857         final String JavaDoc filename = args[0];
858         final Parser pars = new ParserImpl(new ScannerImpl(new FileInputStream JavaDoc(filename)));
859         for(final Iterator JavaDoc iter = pars.eachEvent();iter.hasNext();) {
860             System.out.println(iter.next().getClass().getName());
861         }
862     }
863 }// ParserImpl
864
Popular Tags