View Javadoc

    1   /**
    2    * Copyright (c) 2008-2011, 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
    17  package org.pyyaml;
    18
    19  import java.util.ArrayList;
    20
    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
    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
    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
    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, new Integer[] { 1, 1 }, null));
    73          parseNode();
    74          events.add(new DocumentEndEvent(null, null, true));
    75      }
    76
    77      // node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping)
    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
    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
    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
    143     private void parseMapEntry() {
    144         scanner.getToken(Token.ID.Key);
    145         parseNode();
    146         scanner.getToken(Token.ID.Value);
    147         parseNode();
    148     }
    149
    150     public void parse() {
    151         parseStream();
    152         parsed = true;
    153     }
    154
    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      */
    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      */
    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 }