• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2008, http://www.snakeyaml.org
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.pyyaml;
17 
18 import java.util.ArrayList;
19 
20 import org.yaml.snakeyaml.DumperOptions.Version;
21 import org.yaml.snakeyaml.events.AliasEvent;
22 import org.yaml.snakeyaml.events.DocumentEndEvent;
23 import org.yaml.snakeyaml.events.DocumentStartEvent;
24 import org.yaml.snakeyaml.events.Event;
25 import org.yaml.snakeyaml.events.ImplicitTuple;
26 import org.yaml.snakeyaml.events.MappingEndEvent;
27 import org.yaml.snakeyaml.events.MappingStartEvent;
28 import org.yaml.snakeyaml.events.ScalarEvent;
29 import org.yaml.snakeyaml.events.SequenceEndEvent;
30 import org.yaml.snakeyaml.events.SequenceStartEvent;
31 import org.yaml.snakeyaml.events.StreamEndEvent;
32 import org.yaml.snakeyaml.events.StreamStartEvent;
33 import org.yaml.snakeyaml.parser.Parser;
34 import org.yaml.snakeyaml.tokens.AliasToken;
35 import org.yaml.snakeyaml.tokens.AnchorToken;
36 import org.yaml.snakeyaml.tokens.ScalarToken;
37 import org.yaml.snakeyaml.tokens.TagToken;
38 import org.yaml.snakeyaml.tokens.Token;
39 
40 public class CanonicalParser implements Parser {
41     private ArrayList<Event> events;
42     private boolean parsed;
43     private CanonicalScanner scanner;
44 
CanonicalParser(String data)45     public CanonicalParser(String data) {
46         events = new ArrayList<Event>();
47         parsed = false;
48         scanner = new CanonicalScanner(data);
49     }
50 
51     // stream: STREAM-START document* STREAM-END
parseStream()52     private void parseStream() {
53         scanner.getToken(Token.ID.StreamStart);
54         events.add(new StreamStartEvent(null, null));
55         while (!scanner.checkToken(Token.ID.StreamEnd)) {
56             if (scanner.checkToken(Token.ID.Directive, Token.ID.DocumentStart)) {
57                 parseDocument();
58             } else {
59                 throw new CanonicalException("document is expected, got " + scanner.tokens.get(0));
60             }
61         }
62         scanner.getToken(Token.ID.StreamEnd);
63         events.add(new StreamEndEvent(null, null));
64     }
65 
66     // document: DIRECTIVE? DOCUMENT-START node
parseDocument()67     private void parseDocument() {
68         if (scanner.checkToken(Token.ID.Directive)) {
69             scanner.getToken(Token.ID.Directive);
70         }
71         scanner.getToken(Token.ID.DocumentStart);
72         events.add(new DocumentStartEvent(null, null, true, Version.V1_1, null));
73         parseNode();
74         events.add(new DocumentEndEvent(null, null, true));
75     }
76 
77     // node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping)
parseNode()78     private void parseNode() {
79         if (scanner.checkToken(Token.ID.Alias)) {
80             AliasToken token = (AliasToken) scanner.getToken();
81             events.add(new AliasEvent(token.getValue(), null, null));
82         } else {
83             String anchor = null;
84             if (scanner.checkToken(Token.ID.Anchor)) {
85                 AnchorToken token = (AnchorToken) scanner.getToken();
86                 anchor = token.getValue();
87             }
88             String tag = null;
89             if (scanner.checkToken(Token.ID.Tag)) {
90                 TagToken token = (TagToken) scanner.getToken();
91                 tag = token.getValue().getHandle() + token.getValue().getSuffix();
92             }
93             if (scanner.checkToken(Token.ID.Scalar)) {
94                 ScalarToken token = (ScalarToken) scanner.getToken();
95                 events.add(new ScalarEvent(anchor, tag, new ImplicitTuple(false, false), token
96                         .getValue(), null, null, null));
97             } else if (scanner.checkToken(Token.ID.FlowSequenceStart)) {
98                 events.add(new SequenceStartEvent(anchor, tag, false, null, null, null));
99                 parseSequence();
100             } else if (scanner.checkToken(Token.ID.FlowMappingStart)) {
101                 events.add(new MappingStartEvent(anchor, tag, false, null, null, null));
102                 parseMapping();
103             } else {
104                 throw new CanonicalException("SCALAR, '[', or '{' is expected, got "
105                         + scanner.tokens.get(0));
106             }
107         }
108     }
109 
110     // sequence: SEQUENCE-START (node (ENTRY node)*)? ENTRY? SEQUENCE-END
parseSequence()111     private void parseSequence() {
112         scanner.getToken(Token.ID.FlowSequenceStart);
113         if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) {
114             parseNode();
115             while (!scanner.checkToken(Token.ID.FlowSequenceEnd)) {
116                 scanner.getToken(Token.ID.FlowEntry);
117                 if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) {
118                     parseNode();
119                 }
120             }
121         }
122         scanner.getToken(Token.ID.FlowSequenceEnd);
123         events.add(new SequenceEndEvent(null, null));
124     }
125 
126     // mapping: MAPPING-START (map_entry (ENTRY map_entry)*)? ENTRY? MAPPING-END
parseMapping()127     private void parseMapping() {
128         scanner.getToken(Token.ID.FlowMappingStart);
129         if (!scanner.checkToken(Token.ID.FlowMappingEnd)) {
130             parseMapEntry();
131             while (!scanner.checkToken(Token.ID.FlowMappingEnd)) {
132                 scanner.getToken(Token.ID.FlowEntry);
133                 if (!scanner.checkToken(Token.ID.FlowMappingEnd)) {
134                     parseMapEntry();
135                 }
136             }
137         }
138         scanner.getToken(Token.ID.FlowMappingEnd);
139         events.add(new MappingEndEvent(null, null));
140     }
141 
142     // map_entry: KEY node VALUE node
parseMapEntry()143     private void parseMapEntry() {
144         scanner.getToken(Token.ID.Key);
145         parseNode();
146         scanner.getToken(Token.ID.Value);
147         parseNode();
148     }
149 
parse()150     public void parse() {
151         parseStream();
152         parsed = true;
153     }
154 
getEvent()155     public Event getEvent() {
156         if (!parsed) {
157             parse();
158         }
159         return events.remove(0);
160     }
161 
162     /**
163      * Check the type of the next event.
164      */
checkEvent(Event.ID choice)165     public boolean checkEvent(Event.ID choice) {
166         if (!parsed) {
167             parse();
168         }
169         if (!events.isEmpty()) {
170             if (events.get(0).is(choice)) {
171                 return true;
172             }
173         }
174         return false;
175     }
176 
177     /**
178      * Get the next event.
179      */
peekEvent()180     public Event peekEvent() {
181         if (!parsed) {
182             parse();
183         }
184         if (events.isEmpty()) {
185             return null;
186         } else {
187             return events.get(0);
188         }
189     }
190 }
191