2015-05-24 06:27:42 +00:00
|
|
|
use scanner::*;
|
2015-05-26 18:50:51 +00:00
|
|
|
// use yaml::*;
|
2015-05-24 06:27:42 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug, Eq)]
|
|
|
|
pub enum State {
|
|
|
|
StreamStart,
|
|
|
|
ImplicitDocumentStart,
|
|
|
|
DocumentStart,
|
|
|
|
DocumentContent,
|
|
|
|
DocumentEnd,
|
|
|
|
BlockNode,
|
|
|
|
BlockNodeOrIndentlessSequence,
|
|
|
|
FlowNode,
|
|
|
|
BlockSequenceFirstEntry,
|
|
|
|
BlockSequenceEntry,
|
|
|
|
IndentlessSequenceEntry,
|
|
|
|
BlockMappingFirstKey,
|
|
|
|
BlockMappingKey,
|
|
|
|
BlockMappingValue,
|
|
|
|
FlowSequenceFirstEntry,
|
|
|
|
FlowSequenceEntry,
|
|
|
|
FlowSequenceEntryMappingKey,
|
|
|
|
FlowSequenceEntryMappingValue,
|
|
|
|
FlowSequenceEntryMappingEnd,
|
|
|
|
FlowMappingFirstKey,
|
|
|
|
FlowMappingKey,
|
|
|
|
FlowMappingValue,
|
|
|
|
FlowMappingEmptyValue,
|
|
|
|
End
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, PartialEq, Debug, Eq)]
|
|
|
|
pub enum Event {
|
|
|
|
NoEvent,
|
|
|
|
StreamStart,
|
|
|
|
StreamEnd,
|
|
|
|
DocumentStart,
|
|
|
|
DocumentEnd,
|
|
|
|
Alias,
|
2015-05-24 19:21:53 +00:00
|
|
|
Scalar(String, TScalarStyle),
|
2015-05-24 06:27:42 +00:00
|
|
|
SequenceStart,
|
|
|
|
SequenceEnd,
|
|
|
|
MappingStart,
|
|
|
|
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
|
|
|
|
Event::Scalar("~".to_string(), TScalarStyle::Plain)
|
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-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-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 =>
|
|
|
|
return Err(ScanError::new(self.scanner.mark(),
|
|
|
|
"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());
|
|
|
|
// println!("EV {:?}", ev);
|
|
|
|
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(());
|
|
|
|
}
|
|
|
|
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 {
|
2015-05-27 15:04:03 +00:00
|
|
|
Event::Alias => { unimplemented!() },
|
2015-05-28 09:18:20 +00:00
|
|
|
Event::Scalar(_, _) => {
|
2015-05-26 18:50:51 +00:00
|
|
|
Ok(())
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
|
|
|
Event::SequenceStart => {
|
2015-05-26 18:50:51 +00:00
|
|
|
self.load_sequence(first_ev, recv)
|
2015-05-24 06:27:42 +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-28 14:07:59 +00:00
|
|
|
let next_tok = try!(self.peek());
|
2015-05-27 08:35:13 +00:00
|
|
|
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-05-24 06:27:42 +00:00
|
|
|
_ => unimplemented!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stream_start(&mut self) -> ParseResult {
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::StreamStartToken(_) => {
|
|
|
|
self.state = State::ImplicitDocumentStart;
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::StreamStart)
|
|
|
|
},
|
|
|
|
_ => return Err(ScanError::new(tok.0,
|
|
|
|
"did not find expected <stream-start>")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn document_start(&mut self, implicit: bool) -> ParseResult {
|
|
|
|
let mut tok = try!(self.peek());
|
|
|
|
if !implicit {
|
|
|
|
loop {
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::DocumentEndToken => {
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
},
|
|
|
|
_ => break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::StreamEndToken => {
|
|
|
|
self.state = State::End;
|
|
|
|
self.skip();
|
|
|
|
return Ok(Event::StreamEnd);
|
|
|
|
},
|
2015-05-28 14:07:59 +00:00
|
|
|
TokenType::VersionDirectiveToken(..)
|
2015-05-24 06:27:42 +00:00
|
|
|
| TokenType::TagDirectiveToken
|
|
|
|
| TokenType::DocumentStartToken => {
|
|
|
|
// 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 {
|
|
|
|
TokenType::VersionDirectiveToken(_, _) => {
|
|
|
|
// XXX parsing with warning according to spec
|
|
|
|
//if major != 1 || minor > 2 {
|
|
|
|
// return Err(ScanError::new(tok.0,
|
|
|
|
// "found incompatible YAML document"));
|
|
|
|
//}
|
|
|
|
},
|
|
|
|
TokenType::TagDirectiveToken => {
|
|
|
|
unimplemented!();
|
|
|
|
},
|
|
|
|
_ => 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());
|
2015-05-24 06:27:42 +00:00
|
|
|
if tok.1 != TokenType::DocumentStartToken {
|
|
|
|
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 {
|
2015-05-28 14:07:59 +00:00
|
|
|
TokenType::VersionDirectiveToken(..)
|
2015-05-24 06:27:42 +00:00
|
|
|
|TokenType::TagDirectiveToken
|
|
|
|
|TokenType::DocumentStartToken
|
|
|
|
|TokenType::DocumentEndToken
|
|
|
|
|TokenType::StreamEndToken => {
|
|
|
|
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;
|
|
|
|
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::DocumentEndToken => {
|
|
|
|
self.skip();
|
|
|
|
_implicit = false;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO tag handling
|
|
|
|
self.state = State::DocumentStart;
|
|
|
|
Ok(Event::DocumentEnd)
|
|
|
|
}
|
|
|
|
|
2015-05-24 06:27:42 +00:00
|
|
|
fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> ParseResult {
|
2015-05-24 06:37:36 +00:00
|
|
|
let tok = try!(self.peek());
|
2015-05-24 06:27:42 +00:00
|
|
|
match tok.1 {
|
|
|
|
TokenType::AliasToken => unimplemented!(),
|
|
|
|
TokenType::AnchorToken => unimplemented!(),
|
|
|
|
TokenType::BlockEntryToken if indentless_sequence => {
|
|
|
|
self.state = State::IndentlessSequenceEntry;
|
|
|
|
Ok(Event::SequenceStart)
|
|
|
|
},
|
2015-05-24 19:21:53 +00:00
|
|
|
TokenType::ScalarToken(style, v) => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
2015-05-24 19:21:53 +00:00
|
|
|
Ok(Event::Scalar(v, style))
|
2015-05-24 06:27:42 +00:00
|
|
|
},
|
|
|
|
TokenType::FlowSequenceStartToken => {
|
|
|
|
self.state = State::FlowSequenceFirstEntry;
|
|
|
|
Ok(Event::SequenceStart)
|
|
|
|
},
|
|
|
|
TokenType::FlowMappingStartToken => {
|
|
|
|
self.state = State::FlowMappingFirstKey;
|
|
|
|
Ok(Event::MappingStart)
|
|
|
|
},
|
|
|
|
TokenType::BlockSequenceStartToken if block => {
|
|
|
|
self.state = State::BlockSequenceFirstEntry;
|
|
|
|
Ok(Event::SequenceStart)
|
|
|
|
},
|
|
|
|
TokenType::BlockMappingStartToken if block => {
|
|
|
|
self.state = State::BlockMappingFirstKey;
|
|
|
|
Ok(Event::MappingStart)
|
|
|
|
},
|
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 {
|
|
|
|
// skip BlockMappingStartToken
|
|
|
|
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 {
|
|
|
|
TokenType::KeyToken => {
|
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
2015-05-27 15:04:03 +00:00
|
|
|
TokenType::KeyToken
|
|
|
|
| TokenType::ValueToken
|
|
|
|
| TokenType::BlockEndToken
|
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
|
|
|
|
TokenType::ValueToken => {
|
|
|
|
self.state = State::BlockMappingValue;
|
|
|
|
Ok(Event::empty_scalar())
|
|
|
|
},
|
2015-05-24 06:27:42 +00:00
|
|
|
TokenType::BlockEndToken => {
|
|
|
|
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 {
|
|
|
|
TokenType::ValueToken => {
|
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::KeyToken | TokenType::ValueToken | TokenType::BlockEndToken
|
|
|
|
=> {
|
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());
|
|
|
|
|
|
|
|
if tok.1 != TokenType::FlowMappingEndToken {
|
|
|
|
if !first {
|
|
|
|
if tok.1 == TokenType::FlowEntryToken {
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
} else {
|
|
|
|
return Err(ScanError::new(tok.0,
|
|
|
|
"while parsing a flow mapping, did not find expected ',' or '}'"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if tok.1 == TokenType::KeyToken {
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::ValueToken
|
|
|
|
| TokenType::FlowEntryToken
|
|
|
|
| TokenType::FlowMappingEndToken => {
|
|
|
|
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
|
|
|
|
} else if tok.1 == TokenType::ValueToken {
|
|
|
|
self.state = State::FlowMappingValue;
|
|
|
|
return Ok(Event::empty_scalar());
|
|
|
|
} else if tok.1 != TokenType::FlowMappingEndToken {
|
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());
|
|
|
|
}
|
|
|
|
|
|
|
|
if tok.1 == TokenType::ValueToken {
|
|
|
|
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 {
|
|
|
|
TokenType::FlowEntryToken
|
|
|
|
| TokenType::FlowMappingEndToken => { },
|
|
|
|
_ => {
|
|
|
|
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 {
|
|
|
|
// skip FlowMappingStartToken
|
|
|
|
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 {
|
|
|
|
TokenType::FlowSequenceEndToken => {
|
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
return Ok(Event::SequenceEnd);
|
|
|
|
},
|
|
|
|
TokenType::FlowEntryToken if !first => {
|
|
|
|
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 {
|
2015-05-27 13:34:52 +00:00
|
|
|
TokenType::FlowSequenceEndToken => {
|
2015-05-24 06:27:42 +00:00
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::SequenceEnd)
|
|
|
|
},
|
|
|
|
TokenType::KeyToken => {
|
|
|
|
self.state = State::FlowSequenceEntryMappingKey;
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::MappingStart)
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
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());
|
|
|
|
if tok.1 != TokenType::BlockEntryToken {
|
|
|
|
self.pop_state();
|
|
|
|
return Ok(Event::SequenceEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::BlockEntryToken
|
|
|
|
| TokenType::KeyToken
|
|
|
|
| TokenType::ValueToken
|
|
|
|
| TokenType::BlockEndToken => {
|
|
|
|
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 {
|
|
|
|
TokenType::BlockEndToken => {
|
|
|
|
self.pop_state();
|
|
|
|
self.skip();
|
|
|
|
Ok(Event::SequenceEnd)
|
|
|
|
},
|
|
|
|
TokenType::BlockEntryToken => {
|
|
|
|
self.skip();
|
|
|
|
tok = try!(self.peek());
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::BlockEntryToken | TokenType::BlockEndToken => {
|
|
|
|
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 {
|
|
|
|
TokenType::ValueToken
|
|
|
|
| TokenType::FlowEntryToken
|
|
|
|
| TokenType::FlowSequenceEndToken => {
|
|
|
|
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 {
|
|
|
|
TokenType::ValueToken => {
|
|
|
|
self.skip();
|
|
|
|
let tok = try!(self.peek());
|
|
|
|
self.state = State::FlowSequenceEntryMappingValue;
|
|
|
|
match tok.1 {
|
|
|
|
TokenType::FlowEntryToken
|
|
|
|
| TokenType::FlowSequenceEndToken => {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
}
|
|
|
|
|