Add indentless_sequence_entry

This commit is contained in:
Yuheng Chen 2015-05-27 16:35:13 +08:00
parent 63c0a32918
commit 56e28c630e
2 changed files with 65 additions and 3 deletions

View file

@ -199,7 +199,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
fn state_machine(&mut self) -> ParseResult { fn state_machine(&mut self) -> ParseResult {
let next_tok = self.peek(); let next_tok = self.peek();
//println!("cur_state {:?}, next tok: {:?}", self.state, next_tok); println!("cur_state {:?}, next tok: {:?}", self.state, next_tok);
match self.state { match self.state {
State::StreamStart => self.stream_start(), State::StreamStart => self.stream_start(),
@ -222,6 +222,8 @@ impl<T: Iterator<Item=char>> Parser<T> {
State::FlowSequenceFirstEntry => self.flow_sequence_entry(true), State::FlowSequenceFirstEntry => self.flow_sequence_entry(true),
State::FlowSequenceEntry => self.flow_sequence_entry(false), State::FlowSequenceEntry => self.flow_sequence_entry(false),
State::IndentlessSequenceEntry => self.indentless_sequence_entry(),
_ => unimplemented!() _ => unimplemented!()
} }
} }
@ -464,6 +466,30 @@ impl<T: Iterator<Item=char>> Parser<T> {
} }
} }
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)
}
}
}
fn block_sequence_entry(&mut self, first: bool) -> ParseResult { fn block_sequence_entry(&mut self, first: bool) -> ParseResult {
// BLOCK-SEQUENCE-START // BLOCK-SEQUENCE-START
if first { if first {

View file

@ -1,4 +1,5 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::char;
#[derive(Clone, Copy, PartialEq, Debug, Eq)] #[derive(Clone, Copy, PartialEq, Debug, Eq)]
pub enum TEncoding { pub enum TEncoding {
@ -151,6 +152,21 @@ fn is_blankz(c: char) -> bool {
fn is_digit(c: char) -> bool { fn is_digit(c: char) -> bool {
c >= '0' && c <= '9' c >= '0' && c <= '9'
} }
#[inline]
fn is_hex(c: char) -> bool {
(c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'f')
|| (c >= 'A' && c <= 'F')
}
#[inline]
fn as_hex(c: char) -> u32 {
match c {
'0'...'9' => (c as u32) - ('0' as u32),
'a'...'f' => (c as u32) - ('a' as u32) + 10,
'A'...'F' => (c as u32) - ('A' as u32) + 10,
_ => unreachable!()
}
}
pub type ScanResult = Result<(), ScanError>; pub type ScanResult = Result<(), ScanError>;
@ -804,9 +820,29 @@ impl<T: Iterator<Item=char>> Scanner<T> {
self.skip(); self.skip();
// Consume an arbitrary escape code. // Consume an arbitrary escape code.
if code_length > 0 { if code_length > 0 {
let val = 0; let val = 0usize;
self.lookahead(code_length); self.lookahead(code_length);
unimplemented!(); let mut value = 0u32;
for i in 0..code_length {
if !is_hex(self.buffer[i]) {
return Err(ScanError::new(start_mark,
"while parsing a quoted scalar, did not find expected hexdecimal number"));
}
value = (value << 4) + as_hex(self.buffer[i]);
}
let ch = match char::from_u32(value) {
Some(v) => v,
None => {
return Err(ScanError::new(start_mark,
"while parsing a quoted scalar, found invalid Unicode character escape code"));
}
};
string.push(ch);
for i in 0..code_length {
self.skip();
}
} }
}, },
c => { string.push(c); self.skip(); } c => { string.push(c); self.skip(); }