2015-05-24 06:27:42 +00:00
|
|
|
use scanner::*;
|
2015-05-28 18:26:37 +00:00
|
|
|
use std::collections::HashMap;
|
2015-05-26 18:50:51 +00:00
|
|
|
// use yaml::*;
|
2015-05-24 06:27:42 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug, Eq)]
|
2015-05-31 09:59:43 +00:00
|
|
|
enum State {
|
2015-05-24 06:27:42 +00:00
|
|
|
StreamStart,
|
|
|
|
ImplicitDocumentStart,
|
|
|
|
DocumentStart,
|
|
|
|
DocumentContent,
|
|
|
|
DocumentEnd,
|
|
|
|
BlockNode,
|
|
|
|
BlockNodeOrIndentlessSequence,
|
|
|
|
FlowNode,
|
|
|
|
BlockSequenceFirstEntry,
|
|
|
|
BlockSequenceEntry,
|
|
|
|
IndentlessSequenceEntry,
|
|
|
|
BlockMappingFirstKey,
|
|
|
|
BlockMappingKey,
|
|
|
|
BlockMappingValue,
|
|
|
|
FlowSequenceFirstEntry,
|
|
|
|
FlowSequenceEntry,
|
|
|
|
FlowSequenceEntryMappingKey,
|
|
|
|
FlowSequenceEntryMappingValue,
|
|
|
|
FlowSequenceEntryMappingEnd,
|
|
|
|
FlowMappingFirstKey,
|
|
|
|
FlowMappingKey,
|
|
|
|
FlowMappingValue,
|
|
|
|
FlowMappingEmptyValue,
|
|
|
|
End
|
|
|
|
}
|
|
|
|
|
2015-05-31 09:59:43 +00:00
|
|
|
/// `Event` is used with the low-level event base parsing API,
|
|
|
|
/// see `EventReceiver` trait.
|
2015-05-24 06:27:42 +00:00
|
|
|
#[derive(Clone, PartialEq, Debug, Eq)]
|
|
|
|
pub enum Event {
|
2015-05-31 09:59:43 +00:00
|
|
|
/// Reserved for internal use
|
2015-05-24 06:27:42 +00:00
|
|
|
NoEvent,
|
|
|
|
StreamStart,
|
|
|
|
StreamEnd,
|
|
|
|
DocumentStart,
|
|
|
|
DocumentEnd,
|
2015-05-31 09:59:43 +00:00
|
|
|
/// Refer to an anchor ID
|
2015-05-28 17:56:03 +00:00
|
|
|
Alias(usize),
|
2015-05-31 09:59:43 +00:00
|
|
|
/// Value, style, anchor_id, tag
|
2015-05-30 14:39:50 +00:00
|
|
|
Scalar(String, TScalarStyle, usize, Option<TokenType>),
|
2015-05-31 09:59:43 +00:00
|
|
|
/// Anchor ID
|
2015-05-28 17:56:03 +00:00
|
|
|
SequenceStart(usize),
|
2015-05-24 06:27:42 +00:00
|
|
|
SequenceEnd,
|
2015-05-31 09:59:43 +00:00
|
|
|
/// Anchor ID
|
2015-05-28 17:56:03 +00:00
|
|
|
MappingStart(usize),
|
2015-05-24 06:27:42 +00:00
|
|
|
MappingEnd
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:29:10 +00:00
|
|
|
impl Event {
|
|
|
|
fn empty_scalar() -> Event {
|
2015-05-27 13:57:42 +00:00
|
|
|
// a null scalar
|
2016-02-28 00:30:13 +00:00
|
|
|
Event::Scalar("~".to_owned(), TScalarStyle::Plain, 0, None)
|
2015-05-30 14:39:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn empty_scalar_with_anchor(anchor: usize, tag: TokenType) -> Event {
|
2016-02-28 00:30:13 +00:00
|
|
|
Event::Scalar("".to_owned(), TScalarStyle::Plain, anchor, Some(tag))
|
2015-05-24 06:29:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Parser<T> {
|
|
|
|
scanner: Scanner<T>,
|
|
|
|
states: Vec<State>,
|
|
|
|
state: State,
|
|
|
|
marks: Vec<Marker>,
|
|
|
|
token: Option<Token>,
|
2015-05-28 18:26:37 +00:00
|
|
|
anchors: HashMap<String, usize>,
|
|
|
|
anchor_id: usize,
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 16:29:40 +00:00
|
|
|
pub trait EventReceiver {
|
|
|
|
fn on_event(&mut self, ev: &Event);
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
pub type ParseResult = Result<Event, ScanError>;
|
|
|
|
|
|
|
|
impl<T: Iterator<Item=char>> Parser<T> {
|
|
|
|
pub fn new(src: T) -> Parser<T> {
|
|
|
|
Parser {
|
|
|
|
scanner: Scanner::new(src),
|
|
|
|
states: Vec::new(),
|
|
|
|
state: State::StreamStart,
|
|
|
|
marks: Vec::new(),
|
2015-05-24 17:34:18 +00:00
|
|
|
token: None,
|
2015-05-28 18:26:37 +00:00
|
|
|
|
|
|
|
anchors: HashMap::new(),
|
|
|
|
// valid anchor_id starts from 1
|
|
|
|
anchor_id: 1,
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peek(&mut self) -> Result<Token, ScanError> {
|
|
|
|
if self.token.is_none() {
|
|
|
|
self.token = self.scanner.next();
|
|
|
|
}
|
|
|
|
if self.token.is_none() {
|
2015-05-28 14:07:59 +00:00
|
|
|
match self.scanner.get_error() {
|
|
|
|
None =>
|
2015-06-29 16:31:22 +00:00
|
|
|
return Err(ScanError::new(self.scanner.mark(),
|
2015-05-28 14:07:59 +00:00
|
|
|
"unexpected eof")),
|
|
|
|
Some(e) => return Err(e),
|
|
|
|
}
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
// XXX better?
|
|
|
|
Ok(self.token.clone().unwrap())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn skip(&mut self) {
|
|
|
|
self.token = None;
|
2015-05-24 06:37:36 +00:00
|
|
|
//self.peek();
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
fn pop_state(&mut self) {
|
|
|
|
self.state = self.states.pop().unwrap()
|
|
|
|
}
|
|
|
|
fn push_state(&mut self, state: State) {
|
|
|
|
self.states.push(state);
|
|
|
|
}
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
fn parse<R: EventReceiver>(&mut self, recv: &mut R)
|
|
|
|
-> ParseResult {
|
2015-05-24 06:27:42 +00:00
|
|
|
if self.scanner.stream_ended()
|
|
|
|
|| self.state == State::End {
|
2015-05-26 08:41:35 +00:00
|
|
|
return Ok(Event::StreamEnd);
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
2015-05-26 18:50:51 +00:00
|
|
|
let ev = try!(self.state_machine());
|
2015-05-30 14:39:50 +00:00
|
|
|
// println!("EV {:?}", ev);
|
2015-05-26 18:50:51 +00:00
|
|
|
recv.on_event(&ev);
|
|
|
|
Ok(ev)
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
pub fn load<R: EventReceiver>(&mut self, recv: &mut R, multi: bool)
|
|
|
|
-> Result<(), ScanError> {
|
2015-05-24 06:27:42 +00:00
|
|
|
if !self.scanner.stream_started() {
|
2015-05-26 18:50:51 +00:00
|
|
|
let ev = try!(self.parse(recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
assert_eq!(ev, Event::StreamStart);
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.scanner.stream_ended() {
|
2015-05-26 08:41:35 +00:00
|
|
|
// XXX has parsed?
|
2015-05-26 18:50:51 +00:00
|
|
|
recv.on_event(&Event::StreamEnd);
|
|
|
|
return Ok(());
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
2015-05-26 08:41:35 +00:00
|
|
|
loop {
|
2015-05-26 18:50:51 +00:00
|
|
|
let ev = try!(self.parse(recv));
|
2015-05-26 08:41:35 +00:00
|
|
|
if ev == Event::StreamEnd {
|
2015-05-26 18:50:51 +00:00
|
|
|
recv.on_event(&Event::StreamEnd);
|
|
|
|
return Ok(());
|
|
|
|
}
|
2015-05-28 18:26:37 +00:00
|
|
|
// clear anchors before a new document
|
|
|
|
self.anchors.clear();
|
2015-05-26 18:50:51 +00:00
|
|
|
try!(self.load_document(&ev, recv));
|
|
|
|
if !multi {
|
|
|
|
break;
|
2015-05-26 08:41:35 +00:00
|
|
|
}
|
|
|
|
}
|
2015-05-26 18:50:51 +00:00
|
|
|
Ok(())
|
2015-05-26 08:41:35 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
fn load_document<R: EventReceiver>(&mut self, first_ev: &Event, recv: &mut R)
|
|
|
|
-> Result<(), ScanError> {
|
2015-05-24 06:27:42 +00:00
|
|
|
assert_eq!(first_ev, &Event::DocumentStart);
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
let ev = try!(self.parse(recv));
|
|
|
|
try!(self.load_node(&ev, recv));
|
|
|
|
|
2015-05-26 08:41:35 +00:00
|
|
|
// DOCUMENT-END is expected.
|
2015-05-26 18:50:51 +00:00
|
|
|
let ev = try!(self.parse(recv));
|
2015-05-26 08:41:35 +00:00
|
|
|
assert_eq!(ev, Event::DocumentEnd);
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
Ok(())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 18:50:51 +00:00
|
|
|
fn load_node<R: EventReceiver>(&mut self, first_ev: &Event, recv: &mut R)
|
|
|
|
-> Result<(), ScanError> {
|
2015-05-24 06:27:42 +00:00
|
|
|
match *first_ev {
|
2016-02-28 00:30:13 +00:00
|
|
|
Event::Alias(..) | Event::Scalar(..) => {
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
Event::SequenceStart(_) => {
|
2015-05-26 18:50:51 +00:00
|
|
|
self.load_sequence(first_ev, recv)
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2015-05-28 17:56:03 +00:00
|
|
|
Event::MappingStart(_) => {
|
2015-05-26 18:50:51 +00:00
|
|
|
self.load_mapping(first_ev, recv)
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2015-05-27 15:04:03 +00:00
|
|
|
_ => { println!("UNREACHABLE EVENT: {:?}", first_ev);
|
|
|
|
unreachable!(); }
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-28 09:18:20 +00:00
|
|
|
fn load_mapping<R: EventReceiver>(&mut self, _first_ev: &Event, recv: &mut R)
|
2015-05-26 18:50:51 +00:00
|
|
|
-> Result<(), ScanError> {
|
|
|
|
let mut ev = try!(self.parse(recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
while ev != Event::MappingEnd {
|
|
|
|
// key
|
2015-05-26 18:50:51 +00:00
|
|
|
try!(self.load_node(&ev, recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
|
|
|
|
// value
|
2015-05-26 18:50:51 +00:00
|
|
|
ev = try!(self.parse(recv));
|
|
|
|
try!(self.load_node(&ev, recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
|
|
|
|
// next event
|
2015-05-26 18:50:51 +00:00
|
|
|
ev = try!(self.parse(recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
2015-05-26 18:50:51 +00:00
|
|
|
Ok(())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
|
2015-05-28 09:18:20 +00:00
|
|
|
fn load_sequence<R: EventReceiver>(&mut self, _first_ev: &Event, recv: &mut R)
|
2015-05-26 18:50:51 +00:00
|
|
|
-> Result<(), ScanError> {
|
|
|
|
let mut ev = try!(self.parse(recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
while ev != Event::SequenceEnd {
|
2015-05-28 09:18:20 +00:00
|
|
|
try!(self.load_node(&ev, recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
|
|
|
|
// next event
|
2015-05-26 18:50:51 +00:00
|
|
|
ev = try!(self.parse(recv));
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
2015-05-26 18:50:51 +00:00
|
|
|
Ok(())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn state_machine(&mut self) -> ParseResult {
|
2015-05-30 14:39:50 +00:00
|
|
|
// let next_tok = try!(self.peek());
|
|
|
|
// println!("cur_state {:?}, next tok: {:?}", self.state, next_tok);
|
2015-05-24 06:27:42 +00:00
|
|
|
match self.state {
|
|
|
|
State::StreamStart => self.stream_start(),
|
2015-05-26 08:41:35 +00:00
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
State::ImplicitDocumentStart => self.document_start(true),
|
|
|
|
State::DocumentStart => self.document_start(false),
|
|
|
|
State::DocumentContent => self.document_content(),
|
2015-05-26 08:41:35 +00:00
|
|
|
State::DocumentEnd => self.document_end(),
|
2015-05-24 06:27:42 +00:00
|
|
|
|
2015-05-24 17:34:18 +00:00
|
|
|
State::BlockNode => self.parse_node(true, false),
|
|
|
|
State::BlockNodeOrIndentlessSequence => self.parse_node(true, true),
|
|
|
|
State::FlowNode => self.parse_node(false, false),
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
State::BlockMappingFirstKey => self.block_mapping_key(true),
|
|
|
|
State::BlockMappingKey => self.block_mapping_key(false),
|
|
|
|
State::BlockMappingValue => self.block_mapping_value(),
|
|
|
|
|
|
|
|
State::BlockSequenceFirstEntry => self.block_sequence_entry(true),
|
|
|
|
State::BlockSequenceEntry => self.block_sequence_entry(false),
|
|
|
|
|
|
|
|
State::FlowSequenceFirstEntry => self.flow_sequence_entry(true),
|
|
|
|
State::FlowSequenceEntry => self.flow_sequence_entry(false),
|
|
|
|
|
2015-05-27 13:34:52 +00:00
|
|
|
State::FlowMappingFirstKey => self.flow_mapping_key(true),
|
|
|
|
State::FlowMappingKey => self.flow_mapping_key(false),
|
|
|
|
State::FlowMappingValue => self.flow_mapping_value(false),
|
|
|
|
|
2015-05-27 08:35:13 +00:00
|
|
|
State::IndentlessSequenceEntry => self.indentless_sequence_entry(),
|
|
|
|
|
2015-05-27 15:18:38 +00:00
|
|
|
State::FlowSequenceEntryMappingKey => self.flow_sequence_entry_mapping_key(),
|
|
|
|
State::FlowSequenceEntryMappingValue => self.flow_sequence_entry_mapping_value(),
|
|
|
|
State::FlowSequenceEntryMappingEnd => self.flow_sequence_entry_mapping_end(),
|
2015-06-04 08:10:43 +00:00
|
|
|
State::FlowMappingEmptyValue => self.flow_mapping_value(true),
|
2015-05-27 15:18:38 +00:00
|
|
|
|
2015-06-04 08:10:43 +00:00
|
|
|
/* impossible */
|
|
|
|
State::End => unreachable!(),
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stream_start(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::StreamStart(_) => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::ImplicitDocumentStart;
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::StreamStart)
|
|
|
|
},
|
2016-02-28 00:30:13 +00:00
|
|
|
_ => Err(ScanError::new(tok.0,
|
2015-05-24 06:27:42 +00:00
|
|
|
"did not find expected <stream-start>")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn document_start(&mut self, implicit: bool) -> ParseResult {
|
|
|
|
let mut tok = try!(self.peek());
|
|
|
|
if !implicit {
|
2016-02-28 00:30:13 +00:00
|
|
|
while let TokenType::DocumentEnd = tok.1 {
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::StreamEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::End;
|
|
|
|
self.skip();
|
2016-02-28 00:30:13 +00:00
|
|
|
Ok(Event::StreamEnd)
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::VersionDirective(..)
|
|
|
|
| TokenType::TagDirective(..)
|
|
|
|
| TokenType::DocumentStart => {
|
2015-05-24 06:27:42 +00:00
|
|
|
// explicit document
|
|
|
|
self._explict_document_start()
|
|
|
|
},
|
|
|
|
_ if implicit => {
|
2015-05-28 14:07:59 +00:00
|
|
|
try!(self.parser_process_directives());
|
2015-05-24 06:27:42 +00:00
|
|
|
self.push_state(State::DocumentEnd);
|
|
|
|
self.state = State::BlockNode;
|
|
|
|
Ok(Event::DocumentStart)
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
// explicit document
|
|
|
|
self._explict_document_start()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-28 14:07:59 +00:00
|
|
|
fn parser_process_directives(&mut self) -> Result<(), ScanError> {
|
|
|
|
loop {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::VersionDirective(_, _) => {
|
2015-05-28 14:07:59 +00:00
|
|
|
// XXX parsing with warning according to spec
|
|
|
|
//if major != 1 || minor > 2 {
|
|
|
|
// return Err(ScanError::new(tok.0,
|
|
|
|
// "found incompatible YAML document"));
|
|
|
|
//}
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::TagDirective(..) => {
|
2015-05-28 18:57:41 +00:00
|
|
|
// TODO add tag directive
|
2015-05-28 14:07:59 +00:00
|
|
|
},
|
|
|
|
_ => break
|
|
|
|
}
|
|
|
|
self.skip();
|
|
|
|
}
|
|
|
|
// TODO tag directive
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
fn _explict_document_start(&mut self) -> ParseResult {
|
2015-05-28 14:07:59 +00:00
|
|
|
try!(self.parser_process_directives());
|
2015-05-24 06:37:36 +00:00
|
|
|
let tok = try!(self.peek());
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 != TokenType::DocumentStart {
|
2015-05-24 06:27:42 +00:00
|
|
|
return Err(ScanError::new(tok.0, "did not find expected <document start>"));
|
|
|
|
}
|
|
|
|
self.push_state(State::DocumentEnd);
|
|
|
|
self.state = State::DocumentContent;
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::DocumentStart)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn document_content(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::VersionDirective(..)
|
|
|
|
|TokenType::TagDirective(..)
|
|
|
|
|TokenType::DocumentStart
|
|
|
|
|TokenType::DocumentEnd
|
|
|
|
|TokenType::StreamEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
// empty scalar
|
2015-05-24 06:29:10 +00:00
|
|
|
Ok(Event::empty_scalar())
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.parse_node(true, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-26 08:41:35 +00:00
|
|
|
fn document_end(&mut self) -> ParseResult {
|
|
|
|
let mut _implicit = true;
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
let _start_mark = tok.0;
|
|
|
|
|
2016-02-28 00:30:13 +00:00
|
|
|
if let TokenType::DocumentEnd = tok.1 {
|
|
|
|
self.skip();
|
|
|
|
_implicit = false;
|
2015-05-26 08:41:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO tag handling
|
|
|
|
self.state = State::DocumentStart;
|
|
|
|
Ok(Event::DocumentEnd)
|
|
|
|
}
|
|
|
|
|
2016-02-28 00:30:13 +00:00
|
|
|
fn register_anchor(&mut self, name: &str, _: &Marker) -> Result<usize, ScanError> {
|
2015-05-28 18:26:37 +00:00
|
|
|
// anchors can be overrided/reused
|
|
|
|
// if self.anchors.contains_key(name) {
|
|
|
|
// return Err(ScanError::new(*mark,
|
|
|
|
// "while parsing anchor, found duplicated anchor"));
|
|
|
|
// }
|
|
|
|
let new_id = self.anchor_id;
|
|
|
|
self.anchor_id += 1;
|
2016-02-28 00:30:13 +00:00
|
|
|
self.anchors.insert(name.to_owned(), new_id);
|
2015-05-28 18:26:37 +00:00
|
|
|
Ok(new_id)
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> ParseResult {
|
2015-05-28 17:56:03 +00:00
|
|
|
let mut tok = try!(self.peek());
|
2015-05-28 18:26:37 +00:00
|
|
|
let mut anchor_id = 0;
|
2015-05-30 14:39:50 +00:00
|
|
|
let mut tag = None;
|
2015-05-28 17:56:03 +00:00
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Alias(name) => {
|
2015-05-28 17:56:03 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
2015-05-28 18:26:37 +00:00
|
|
|
match self.anchors.get(&name) {
|
|
|
|
None => return Err(ScanError::new(tok.0, "while parsing node, found unknown anchor")),
|
|
|
|
Some(id) => return Ok(Event::Alias(*id))
|
|
|
|
}
|
2015-05-28 17:56:03 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Anchor(name) => {
|
2015-05-28 18:26:37 +00:00
|
|
|
anchor_id = try!(self.register_anchor(&name, &tok.0));
|
2015-05-28 17:56:03 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
2016-02-27 23:29:34 +00:00
|
|
|
if let TokenType::Tag(_, _) = tok.1 {
|
2015-05-30 14:39:50 +00:00
|
|
|
tag = Some(tok.1);
|
2015-05-28 17:56:03 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
}
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Tag(..) => {
|
2015-05-30 14:39:50 +00:00
|
|
|
tag = Some(tok.1);
|
2015-05-28 17:56:03 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
2016-02-27 23:29:34 +00:00
|
|
|
if let TokenType::Anchor(name) = tok.1 {
|
2015-05-28 18:26:37 +00:00
|
|
|
anchor_id = try!(self.register_anchor(&name, &tok.0));
|
2015-05-28 17:56:03 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {}
|
|
|
|
}
|
2015-05-24 06:27:42 +00:00
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEntry if indentless_sequence => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::IndentlessSequenceEntry;
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::SequenceStart(anchor_id))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Scalar(style, v) => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
2015-05-30 14:39:50 +00:00
|
|
|
Ok(Event::Scalar(v, style, anchor_id, tag))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowSequenceStart => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::FlowSequenceFirstEntry;
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::SequenceStart(anchor_id))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowMappingStart => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::FlowMappingFirstKey;
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::MappingStart(anchor_id))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockSequenceStart if block => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::BlockSequenceFirstEntry;
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::SequenceStart(anchor_id))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockMappingStart if block => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::BlockMappingFirstKey;
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::MappingStart(anchor_id))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
2015-05-30 14:39:50 +00:00
|
|
|
// ex 7.2, an empty scalar can follow a secondary tag
|
|
|
|
_ if tag.is_some() || anchor_id > 0 => {
|
|
|
|
self.pop_state();
|
|
|
|
Ok(Event::empty_scalar_with_anchor(anchor_id, tag.unwrap()))
|
|
|
|
},
|
2015-05-28 09:18:20 +00:00
|
|
|
_ => { Err(ScanError::new(tok.0, "while parsing a node, did not find expected node content")) }
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn block_mapping_key(&mut self, first: bool) -> ParseResult {
|
2016-02-27 23:29:34 +00:00
|
|
|
// skip BlockMappingStart
|
2015-05-24 06:27:42 +00:00
|
|
|
if first {
|
2015-05-24 06:37:36 +00:00
|
|
|
let _ = try!(self.peek());
|
2015-05-24 06:27:42 +00:00
|
|
|
//self.marks.push(tok.0);
|
|
|
|
self.skip();
|
|
|
|
}
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Key => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Key
|
|
|
|
| TokenType::Value
|
|
|
|
| TokenType::BlockEnd
|
2015-05-24 06:27:42 +00:00
|
|
|
=> {
|
|
|
|
self.state = State::BlockMappingValue;
|
|
|
|
// empty scalar
|
2015-05-24 06:29:10 +00:00
|
|
|
Ok(Event::empty_scalar())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::BlockMappingValue);
|
|
|
|
self.parse_node(true, true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2015-05-27 15:04:03 +00:00
|
|
|
// XXX(chenyh): libyaml failed to parse spec 1.2, ex8.18
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Value => {
|
2015-05-27 15:04:03 +00:00
|
|
|
self.state = State::BlockMappingValue;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::MappingEnd)
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
Err(ScanError::new(tok.0, "while parsing a block mapping, did not find expected key"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn block_mapping_value(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Value => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Key | TokenType::Value | TokenType::BlockEnd
|
2015-05-24 06:27:42 +00:00
|
|
|
=> {
|
2015-05-27 15:04:03 +00:00
|
|
|
self.state = State::BlockMappingKey;
|
2015-05-24 06:27:42 +00:00
|
|
|
// empty scalar
|
2015-05-24 06:29:10 +00:00
|
|
|
Ok(Event::empty_scalar())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::BlockMappingKey);
|
|
|
|
self.parse_node(true, true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.state = State::BlockMappingKey;
|
|
|
|
// empty scalar
|
2015-05-24 06:29:10 +00:00
|
|
|
Ok(Event::empty_scalar())
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-27 13:34:52 +00:00
|
|
|
fn flow_mapping_key(&mut self, first: bool) -> ParseResult {
|
|
|
|
if first {
|
|
|
|
let _ = try!(self.peek());
|
|
|
|
self.skip();
|
|
|
|
}
|
|
|
|
let mut tok = try!(self.peek());
|
|
|
|
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 != TokenType::FlowMappingEnd {
|
2015-05-27 13:34:52 +00:00
|
|
|
if !first {
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 == TokenType::FlowEntry {
|
2015-05-27 13:34:52 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
} else {
|
|
|
|
return Err(ScanError::new(tok.0,
|
|
|
|
"while parsing a flow mapping, did not find expected ',' or '}'"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 == TokenType::Key {
|
2015-05-27 13:34:52 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Value
|
|
|
|
| TokenType::FlowEntry
|
|
|
|
| TokenType::FlowMappingEnd => {
|
2015-05-27 13:34:52 +00:00
|
|
|
self.state = State::FlowMappingValue;
|
|
|
|
return Ok(Event::empty_scalar());
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::FlowMappingValue);
|
|
|
|
return self.parse_node(false, false);
|
|
|
|
}
|
|
|
|
}
|
2015-05-28 09:18:20 +00:00
|
|
|
// XXX libyaml fail ex 7.3, empty key
|
2016-02-27 23:29:34 +00:00
|
|
|
} else if tok.1 == TokenType::Value {
|
2015-05-28 09:18:20 +00:00
|
|
|
self.state = State::FlowMappingValue;
|
|
|
|
return Ok(Event::empty_scalar());
|
2016-02-27 23:29:34 +00:00
|
|
|
} else if tok.1 != TokenType::FlowMappingEnd {
|
2015-05-27 13:34:52 +00:00
|
|
|
self.push_state(State::FlowMappingEmptyValue);
|
|
|
|
return self.parse_node(false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::MappingEnd)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flow_mapping_value(&mut self, empty: bool) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
if empty {
|
|
|
|
self.state = State::FlowMappingKey;
|
|
|
|
return Ok(Event::empty_scalar());
|
|
|
|
}
|
|
|
|
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 == TokenType::Value {
|
2015-05-27 13:34:52 +00:00
|
|
|
self.skip();
|
2015-05-28 09:18:20 +00:00
|
|
|
let tok = try!(self.peek());
|
2015-05-27 13:34:52 +00:00
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowEntry
|
|
|
|
| TokenType::FlowMappingEnd => { },
|
2015-05-27 13:34:52 +00:00
|
|
|
_ => {
|
|
|
|
self.push_state(State::FlowMappingKey);
|
|
|
|
return self.parse_node(false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.state = State::FlowMappingKey;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
fn flow_sequence_entry(&mut self, first: bool) -> ParseResult {
|
2016-02-27 23:29:34 +00:00
|
|
|
// skip FlowMappingStart
|
2015-05-24 06:27:42 +00:00
|
|
|
if first {
|
2015-05-24 06:37:36 +00:00
|
|
|
let _ = try!(self.peek());
|
2015-05-24 06:27:42 +00:00
|
|
|
//self.marks.push(tok.0);
|
|
|
|
self.skip();
|
|
|
|
}
|
|
|
|
let mut tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowSequenceEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
return Ok(Event::SequenceEnd);
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowEntry if !first => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
},
|
|
|
|
_ if !first => {
|
|
|
|
return Err(ScanError::new(tok.0,
|
|
|
|
"while parsing a flow sequence, expectd ',' or ']'"));
|
|
|
|
}
|
|
|
|
_ => { /* next */ }
|
|
|
|
}
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowSequenceEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::SequenceEnd)
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Key => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::FlowSequenceEntryMappingKey;
|
|
|
|
self.skip();
|
2015-05-28 17:56:03 +00:00
|
|
|
Ok(Event::MappingStart(0))
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::FlowSequenceEntry);
|
|
|
|
self.parse_node(false, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-27 08:35:13 +00:00
|
|
|
fn indentless_sequence_entry(&mut self) -> ParseResult {
|
|
|
|
let mut tok = try!(self.peek());
|
2016-02-27 23:29:34 +00:00
|
|
|
if tok.1 != TokenType::BlockEntry {
|
2015-05-27 08:35:13 +00:00
|
|
|
self.pop_state();
|
|
|
|
return Ok(Event::SequenceEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEntry
|
|
|
|
| TokenType::Key
|
|
|
|
| TokenType::Value
|
|
|
|
| TokenType::BlockEnd => {
|
2015-05-27 08:35:13 +00:00
|
|
|
self.state = State::IndentlessSequenceEntry;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::IndentlessSequenceEntry);
|
|
|
|
self.parse_node(true, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
fn block_sequence_entry(&mut self, first: bool) -> ParseResult {
|
|
|
|
// BLOCK-SEQUENCE-START
|
|
|
|
if first {
|
2015-05-24 06:37:36 +00:00
|
|
|
let _ = try!(self.peek());
|
2015-05-24 06:27:42 +00:00
|
|
|
//self.marks.push(tok.0);
|
|
|
|
self.skip();
|
|
|
|
}
|
|
|
|
let mut tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::SequenceEnd)
|
|
|
|
},
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEntry => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::BlockEntry
|
|
|
|
| TokenType::BlockEnd => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.state = State::BlockSequenceEntry;
|
2015-05-24 06:29:10 +00:00
|
|
|
Ok(Event::empty_scalar())
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::BlockSequenceEntry);
|
|
|
|
self.parse_node(true, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
Err(ScanError::new(tok.0,
|
|
|
|
"while parsing a block collection, did not find expected '-' indicator"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-27 15:18:38 +00:00
|
|
|
fn flow_sequence_entry_mapping_key(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Value
|
|
|
|
| TokenType::FlowEntry
|
|
|
|
| TokenType::FlowSequenceEnd => {
|
2015-05-27 15:18:38 +00:00
|
|
|
self.skip();
|
|
|
|
self.state = State::FlowSequenceEntryMappingValue;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::FlowSequenceEntryMappingValue);
|
|
|
|
self.parse_node(false, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flow_sequence_entry_mapping_value(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::Value => {
|
2015-05-27 15:18:38 +00:00
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
self.state = State::FlowSequenceEntryMappingValue;
|
|
|
|
match tok.1 {
|
2016-02-27 23:29:34 +00:00
|
|
|
TokenType::FlowEntry
|
|
|
|
| TokenType::FlowSequenceEnd => {
|
2015-05-27 15:18:38 +00:00
|
|
|
self.state = State::FlowSequenceEntryMappingEnd;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.push_state(State::FlowSequenceEntryMappingEnd);
|
|
|
|
self.parse_node(false, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
self.state = State::FlowSequenceEntryMappingEnd;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flow_sequence_entry_mapping_end(&mut self) -> ParseResult {
|
|
|
|
self.state = State::FlowSequenceEntry;
|
|
|
|
Ok(Event::MappingEnd)
|
|
|
|
}
|
2015-05-24 06:27:42 +00:00
|
|
|
}
|