Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  parser.rs   Sprache: unbekannt

 
use crate::scanner::*;
use std::collections::HashMap;

#[derive(Clone, Copy, PartialEq, Debug, Eq)]
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,
}

/// `Event` is used with the low-level event base parsing API,
/// see `EventReceiver` trait.
#[derive(Clone, PartialEq, Debug, Eq)]
pub enum Event {
    /// Reserved for internal use
    Nothing,
    StreamStart,
    StreamEnd,
    DocumentStart,
    DocumentEnd,
    /// Refer to an anchor ID
    Alias(usize),
    /// Value, style, anchor_id, tag
    Scalar(String, TScalarStyle, usize, Option<TokenType>),
    /// Anchor ID
    SequenceStart(usize),
    SequenceEnd,
    /// Anchor ID
    MappingStart(usize),
    MappingEnd,
}

impl Event {
    fn empty_scalar() -> Event {
        // a null scalar
        Event::Scalar("~".to_owned(), TScalarStyle::Plain, 0, None)
    }

    fn empty_scalar_with_anchor(anchor: usize, tag: Option<TokenType>) -> Event {
        Event::Scalar("".to_owned(), TScalarStyle::Plain, anchor, tag)
    }
}

#[derive(Debug)]
pub struct Parser<T> {
    scanner: Scanner<T>,
    states: Vec<State>,
    state: State,
    marks: Vec<Marker>,
    token: Option<Token>,
    current: Option<(Event, Marker)>,
    anchors: HashMap<String, usize>,
    anchor_id: usize,
}

pub trait EventReceiver {
    fn on_event(&mut self, ev: Event);
}

pub trait MarkedEventReceiver {
    fn on_event(&mut self, ev: Event, _mark: Marker);
}

impl<R: EventReceiver> MarkedEventReceiver for R {
    fn on_event(&mut self, ev: Event, _mark: Marker) {
        self.on_event(ev)
    }
}

pub type ParseResult = Result<(Event, Marker), 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(),
            token: None,
            current: None,

            anchors: HashMap::new(),
            // valid anchor_id starts from 1
            anchor_id: 1,
        }
    }

    pub fn peek(&mut self) -> Result<&(Event, Marker), ScanError> {
        match self.current {
            Some(ref x) => Ok(x),
            None => {
                self.current = Some(self.next()?);
                self.peek()
            }
        }
    }

    pub fn next(&mut self) -> ParseResult {
        match self.current {
            None => self.parse(),
            Some(_) => Ok(self.current.take().unwrap()),
        }
    }

    fn peek_token(&mut self) -> Result<&Token, ScanError> {
        match self.token {
            None => {
                self.token = Some(self.scan_next_token()?);
                Ok(self.token.as_ref().unwrap())
            }
            Some(ref tok) => Ok(tok),
        }
    }

    fn scan_next_token(&mut self) -> Result<Token, ScanError> {
        let token = self.scanner.next();
        match token {
            None => match self.scanner.get_error() {
                None => Err(ScanError::new(self.scanner.mark(), "unexpected eof")),
                Some(e) => Err(e),
            },
            Some(tok) => Ok(tok),
        }
    }

    fn fetch_token(&mut self) -> Token {
        self.token
            .take()
            .expect("fetch_token needs to be preceded by peek_token")
    }

    fn skip(&mut self) {
        self.token = None;
        //self.peek_token();
    }
    fn pop_state(&mut self) {
        self.state = self.states.pop().unwrap()
    }
    fn push_state(&mut self, state: State) {
        self.states.push(state);
    }

    fn parse(&mut self) -> ParseResult {
        if self.state == State::End {
            return Ok((Event::StreamEnd, self.scanner.mark()));
        }
        let (ev, mark) = self.state_machine()?;
        // println!("EV {:?}", ev);
        Ok((ev, mark))
    }

    pub fn load<R: MarkedEventReceiver>(
        &mut self,
        recv: &mut R,
        multi: bool,
    ) -> Result<(), ScanError> {
        if !self.scanner.stream_started() {
            let (ev, mark) = self.next()?;
            assert_eq!(ev, Event::StreamStart);
            recv.on_event(ev, mark);
        }

        if self.scanner.stream_ended() {
            // XXX has parsed?
            recv.on_event(Event::StreamEnd, self.scanner.mark());
            return Ok(());
        }
        loop {
            let (ev, mark) = self.next()?;
            if ev == Event::StreamEnd {
                recv.on_event(ev, mark);
                return Ok(());
            }
            // clear anchors before a new document
            self.anchors.clear();
            self.load_document(ev, mark, recv)?;
            if !multi {
                break;
            }
        }
        Ok(())
    }

    fn load_document<R: MarkedEventReceiver>(
        &mut self,
        first_ev: Event,
        mark: Marker,
        recv: &mut R,
    ) -> Result<(), ScanError> {
        assert_eq!(first_ev, Event::DocumentStart);
        recv.on_event(first_ev, mark);

        let (ev, mark) = self.next()?;
        self.load_node(ev, mark, recv)?;

        // DOCUMENT-END is expected.
        let (ev, mark) = self.next()?;
        assert_eq!(ev, Event::DocumentEnd);
        recv.on_event(ev, mark);

        Ok(())
    }

    fn load_node<R: MarkedEventReceiver>(
        &mut self,
        first_ev: Event,
        mark: Marker,
        recv: &mut R,
    ) -> Result<(), ScanError> {
        match first_ev {
            Event::Alias(..) | Event::Scalar(..) => {
                recv.on_event(first_ev, mark);
                Ok(())
            }
            Event::SequenceStart(_) => {
                recv.on_event(first_ev, mark);
                self.load_sequence(recv)
            }
            Event::MappingStart(_) => {
                recv.on_event(first_ev, mark);
                self.load_mapping(recv)
            }
            _ => {
                println!("UNREACHABLE EVENT: {:?}", first_ev);
                unreachable!();
            }
        }
    }

    fn load_mapping<R: MarkedEventReceiver>(&mut self, recv: &mut R) -> Result<(), ScanError> {
        let (mut key_ev, mut key_mark) = self.next()?;
        while key_ev != Event::MappingEnd {
            // key
            self.load_node(key_ev, key_mark, recv)?;

            // value
            let (ev, mark) = self.next()?;
            self.load_node(ev, mark, recv)?;

            // next event
            let (ev, mark) = self.next()?;
            key_ev = ev;
            key_mark = mark;
        }
        recv.on_event(key_ev, key_mark);
        Ok(())
    }

    fn load_sequence<R: MarkedEventReceiver>(&mut self, recv: &mut R) -> Result<(), ScanError> {
        let (mut ev, mut mark) = self.next()?;
        while ev != Event::SequenceEnd {
            self.load_node(ev, mark, recv)?;

            // next event
            let (next_ev, next_mark) = self.next()?;
            ev = next_ev;
            mark = next_mark;
        }
        recv.on_event(ev, mark);
        Ok(())
    }

    fn state_machine(&mut self) -> ParseResult {
        // let next_tok = self.peek_token()?;
        // println!("cur_state {:?}, next tok: {:?}", self.state, next_tok);
        match self.state {
            State::StreamStart => self.stream_start(),

            State::ImplicitDocumentStart => self.document_start(true),
            State::DocumentStart => self.document_start(false),
            State::DocumentContent => self.document_content(),
            State::DocumentEnd => self.document_end(),

            State::BlockNode => self.parse_node(true, false),
            // State::BlockNodeOrIndentlessSequence => self.parse_node(true, true),
            // State::FlowNode => self.parse_node(false, false),
            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),

            State::FlowMappingFirstKey => self.flow_mapping_key(true),
            State::FlowMappingKey => self.flow_mapping_key(false),
            State::FlowMappingValue => self.flow_mapping_value(false),

            State::IndentlessSequenceEntry => self.indentless_sequence_entry(),

            State::FlowSequenceEntryMappingKey => self.flow_sequence_entry_mapping_key(),
            State::FlowSequenceEntryMappingValue => self.flow_sequence_entry_mapping_value(),
            State::FlowSequenceEntryMappingEnd => self.flow_sequence_entry_mapping_end(),
            State::FlowMappingEmptyValue => self.flow_mapping_value(true),

            /* impossible */
            State::End => unreachable!(),
        }
    }

    fn stream_start(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(mark, TokenType::StreamStart(_)) => {
                self.state = State::ImplicitDocumentStart;
                self.skip();
                Ok((Event::StreamStart, mark))
            }
            Token(mark, _) => Err(ScanError::new(mark, "did not find expected <stream-start>")),
        }
    }

    fn document_start(&mut self, implicit: bool) -> ParseResult {
        if !implicit {
            while let TokenType::DocumentEnd = self.peek_token()?.1 {
                self.skip();
            }
        }

        match *self.peek_token()? {
            Token(mark, TokenType::StreamEnd) => {
                self.state = State::End;
                self.skip();
                Ok((Event::StreamEnd, mark))
            }
            Token(_, TokenType::VersionDirective(..))
            | Token(_, TokenType::TagDirective(..))
            | Token(_, TokenType::DocumentStart) => {
                // explicit document
                self._explicit_document_start()
            }
            Token(mark, _) if implicit => {
                self.parser_process_directives()?;
                self.push_state(State::DocumentEnd);
                self.state = State::BlockNode;
                Ok((Event::DocumentStart, mark))
            }
            _ => {
                // explicit document
                self._explicit_document_start()
            }
        }
    }

    fn parser_process_directives(&mut self) -> Result<(), ScanError> {
        loop {
            match self.peek_token()?.1 {
                TokenType::VersionDirective(_, _) => {
                    // XXX parsing with warning according to spec
                    //if major != 1 || minor > 2 {
                    //    return Err(ScanError::new(tok.0,
                    //        "found incompatible YAML document"));
                    //}
                }
                TokenType::TagDirective(..) => {
                    // TODO add tag directive
                }
                _ => break,
            }
            self.skip();
        }
        // TODO tag directive
        Ok(())
    }

    fn _explicit_document_start(&mut self) -> ParseResult {
        self.parser_process_directives()?;
        match *self.peek_token()? {
            Token(mark, TokenType::DocumentStart) => {
                self.push_state(State::DocumentEnd);
                self.state = State::DocumentContent;
                self.skip();
                Ok((Event::DocumentStart, mark))
            }
            Token(mark, _) => Err(ScanError::new(
                mark,
                "did not find expected <document start>",
            )),
        }
    }

    fn document_content(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(mark, TokenType::VersionDirective(..))
            | Token(mark, TokenType::TagDirective(..))
            | Token(mark, TokenType::DocumentStart)
            | Token(mark, TokenType::DocumentEnd)
            | Token(mark, TokenType::StreamEnd) => {
                self.pop_state();
                // empty scalar
                Ok((Event::empty_scalar(), mark))
            }
            _ => self.parse_node(true, false),
        }
    }

    fn document_end(&mut self) -> ParseResult {
        let mut _implicit = true;
        let marker: Marker = match *self.peek_token()? {
            Token(mark, TokenType::DocumentEnd) => {
                self.skip();
                _implicit = false;
                mark
            }
            Token(mark, _) => mark,
        };

        // TODO tag handling
        self.state = State::DocumentStart;
        Ok((Event::DocumentEnd, marker))
    }

    fn register_anchor(&mut self, name: String, _: &Marker) -> Result<usize, ScanError> {
        // anchors can be overridden/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;
        self.anchors.insert(name, new_id);
        Ok(new_id)
    }

    fn parse_node(&mut self, block: bool, indentless_sequence: bool) -> ParseResult {
        let mut anchor_id = 0;
        let mut tag = None;
        match *self.peek_token()? {
            Token(_, TokenType::Alias(_)) => {
                self.pop_state();
                if let Token(mark, TokenType::Alias(name)) = self.fetch_token() {
                    match self.anchors.get(&name) {
                        None => {
                            return Err(ScanError::new(
                                mark,
                                "while parsing node, found unknown anchor",
                            ))
                        }
                        Some(id) => return Ok((Event::Alias(*id), mark)),
                    }
                } else {
                    unreachable!()
                }
            }
            Token(_, TokenType::Anchor(_)) => {
                if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
                    anchor_id = self.register_anchor(name, &mark)?;
                    if let TokenType::Tag(..) = self.peek_token()?.1 {
                        if let tg @ TokenType::Tag(..) = self.fetch_token().1 {
                            tag = Some(tg);
                        } else {
                            unreachable!()
                        }
                    }
                } else {
                    unreachable!()
                }
            }
            Token(_, TokenType::Tag(..)) => {
                if let tg @ TokenType::Tag(..) = self.fetch_token().1 {
                    tag = Some(tg);
                    if let TokenType::Anchor(_) = self.peek_token()?.1 {
                        if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
                            anchor_id = self.register_anchor(name, &mark)?;
                        } else {
                            unreachable!()
                        }
                    }
                } else {
                    unreachable!()
                }
            }
            _ => {}
        }
        match *self.peek_token()? {
            Token(mark, TokenType::BlockEntry) if indentless_sequence => {
                self.state = State::IndentlessSequenceEntry;
                Ok((Event::SequenceStart(anchor_id), mark))
            }
            Token(_, TokenType::Scalar(..)) => {
                self.pop_state();
                if let Token(mark, TokenType::Scalar(style, v)) = self.fetch_token() {
                    Ok((Event::Scalar(v, style, anchor_id, tag), mark))
                } else {
                    unreachable!()
                }
            }
            Token(mark, TokenType::FlowSequenceStart) => {
                self.state = State::FlowSequenceFirstEntry;
                Ok((Event::SequenceStart(anchor_id), mark))
            }
            Token(mark, TokenType::FlowMappingStart) => {
                self.state = State::FlowMappingFirstKey;
                Ok((Event::MappingStart(anchor_id), mark))
            }
            Token(mark, TokenType::BlockSequenceStart) if block => {
                self.state = State::BlockSequenceFirstEntry;
                Ok((Event::SequenceStart(anchor_id), mark))
            }
            Token(mark, TokenType::BlockMappingStart) if block => {
                self.state = State::BlockMappingFirstKey;
                Ok((Event::MappingStart(anchor_id), mark))
            }
            // ex 7.2, an empty scalar can follow a secondary tag
            Token(mark, _) if tag.is_some() || anchor_id > 0 => {
                self.pop_state();
                Ok((Event::empty_scalar_with_anchor(anchor_id, tag), mark))
            }
            Token(mark, _) => Err(ScanError::new(
                mark,
                "while parsing a node, did not find expected node content",
            )),
        }
    }

    fn block_mapping_key(&mut self, first: bool) -> ParseResult {
        // skip BlockMappingStart
        if first {
            let _ = self.peek_token()?;
            //self.marks.push(tok.0);
            self.skip();
        }
        match *self.peek_token()? {
            Token(_, TokenType::Key) => {
                self.skip();
                match *self.peek_token()? {
                    Token(mark, TokenType::Key)
                    | Token(mark, TokenType::Value)
                    | Token(mark, TokenType::BlockEnd) => {
                        self.state = State::BlockMappingValue;
                        // empty scalar
                        Ok((Event::empty_scalar(), mark))
                    }
                    _ => {
                        self.push_state(State::BlockMappingValue);
                        self.parse_node(true, true)
                    }
                }
            }
            // XXX(chenyh): libyaml failed to parse spec 1.2, ex8.18
            Token(mark, TokenType::Value) => {
                self.state = State::BlockMappingValue;
                Ok((Event::empty_scalar(), mark))
            }
            Token(mark, TokenType::BlockEnd) => {
                self.pop_state();
                self.skip();
                Ok((Event::MappingEnd, mark))
            }
            Token(mark, _) => Err(ScanError::new(
                mark,
                "while parsing a block mapping, did not find expected key",
            )),
        }
    }

    fn block_mapping_value(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(_, TokenType::Value) => {
                self.skip();
                match *self.peek_token()? {
                    Token(mark, TokenType::Key)
                    | Token(mark, TokenType::Value)
                    | Token(mark, TokenType::BlockEnd) => {
                        self.state = State::BlockMappingKey;
                        // empty scalar
                        Ok((Event::empty_scalar(), mark))
                    }
                    _ => {
                        self.push_state(State::BlockMappingKey);
                        self.parse_node(true, true)
                    }
                }
            }
            Token(mark, _) => {
                self.state = State::BlockMappingKey;
                // empty scalar
                Ok((Event::empty_scalar(), mark))
            }
        }
    }

    fn flow_mapping_key(&mut self, first: bool) -> ParseResult {
        if first {
            let _ = self.peek_token()?;
            self.skip();
        }
        let marker: Marker =
            {
                match *self.peek_token()? {
                    Token(mark, TokenType::FlowMappingEnd) => mark,
                    Token(mark, _) => {
                        if !first {
                            match *self.peek_token()? {
                            Token(_, TokenType::FlowEntry) => self.skip(),
                            Token(mark, _) => return Err(ScanError::new(mark,
                                "while parsing a flow mapping, did not find expected ',' or '}'"))
                        }
                        }

                        match *self.peek_token()? {
                            Token(_, TokenType::Key) => {
                                self.skip();
                                match *self.peek_token()? {
                                    Token(mark, TokenType::Value)
                                    | Token(mark, TokenType::FlowEntry)
                                    | Token(mark, TokenType::FlowMappingEnd) => {
                                        self.state = State::FlowMappingValue;
                                        return Ok((Event::empty_scalar(), mark));
                                    }
                                    _ => {
                                        self.push_state(State::FlowMappingValue);
                                        return self.parse_node(false, false);
                                    }
                                }
                            }
                            Token(marker, TokenType::Value) => {
                                self.state = State::FlowMappingValue;
                                return Ok((Event::empty_scalar(), marker));
                            }
                            Token(_, TokenType::FlowMappingEnd) => (),
                            _ => {
                                self.push_state(State::FlowMappingEmptyValue);
                                return self.parse_node(false, false);
                            }
                        }

                        mark
                    }
                }
            };

        self.pop_state();
        self.skip();
        Ok((Event::MappingEnd, marker))
    }

    fn flow_mapping_value(&mut self, empty: bool) -> ParseResult {
        let mark: Marker = {
            if empty {
                let Token(mark, _) = *self.peek_token()?;
                self.state = State::FlowMappingKey;
                return Ok((Event::empty_scalar(), mark));
            } else {
                match *self.peek_token()? {
                    Token(marker, TokenType::Value) => {
                        self.skip();
                        match self.peek_token()?.1 {
                            TokenType::FlowEntry | TokenType::FlowMappingEnd => {}
                            _ => {
                                self.push_state(State::FlowMappingKey);
                                return self.parse_node(false, false);
                            }
                        }
                        marker
                    }
                    Token(marker, _) => marker,
                }
            }
        };

        self.state = State::FlowMappingKey;
        Ok((Event::empty_scalar(), mark))
    }

    fn flow_sequence_entry(&mut self, first: bool) -> ParseResult {
        // skip FlowMappingStart
        if first {
            let _ = self.peek_token()?;
            //self.marks.push(tok.0);
            self.skip();
        }
        match *self.peek_token()? {
            Token(mark, TokenType::FlowSequenceEnd) => {
                self.pop_state();
                self.skip();
                return Ok((Event::SequenceEnd, mark));
            }
            Token(_, TokenType::FlowEntry) if !first => {
                self.skip();
            }
            Token(mark, _) if !first => {
                return Err(ScanError::new(
                    mark,
                    "while parsing a flow sequence, expected ',' or ']'",
                ));
            }
            _ => { /* next */ }
        }
        match *self.peek_token()? {
            Token(mark, TokenType::FlowSequenceEnd) => {
                self.pop_state();
                self.skip();
                Ok((Event::SequenceEnd, mark))
            }
            Token(mark, TokenType::Key) => {
                self.state = State::FlowSequenceEntryMappingKey;
                self.skip();
                Ok((Event::MappingStart(0), mark))
            }
            _ => {
                self.push_state(State::FlowSequenceEntry);
                self.parse_node(false, false)
            }
        }
    }

    fn indentless_sequence_entry(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(_, TokenType::BlockEntry) => (),
            Token(mark, _) => {
                self.pop_state();
                return Ok((Event::SequenceEnd, mark));
            }
        }
        self.skip();
        match *self.peek_token()? {
            Token(mark, TokenType::BlockEntry)
            | Token(mark, TokenType::Key)
            | Token(mark, TokenType::Value)
            | Token(mark, TokenType::BlockEnd) => {
                self.state = State::IndentlessSequenceEntry;
                Ok((Event::empty_scalar(), mark))
            }
            _ => {
                self.push_state(State::IndentlessSequenceEntry);
                self.parse_node(true, false)
            }
        }
    }

    fn block_sequence_entry(&mut self, first: bool) -> ParseResult {
        // BLOCK-SEQUENCE-START
        if first {
            let _ = self.peek_token()?;
            //self.marks.push(tok.0);
            self.skip();
        }
        match *self.peek_token()? {
            Token(mark, TokenType::BlockEnd) => {
                self.pop_state();
                self.skip();
                Ok((Event::SequenceEnd, mark))
            }
            Token(_, TokenType::BlockEntry) => {
                self.skip();
                match *self.peek_token()? {
                    Token(mark, TokenType::BlockEntry) | Token(mark, TokenType::BlockEnd) => {
                        self.state = State::BlockSequenceEntry;
                        Ok((Event::empty_scalar(), mark))
                    }
                    _ => {
                        self.push_state(State::BlockSequenceEntry);
                        self.parse_node(true, false)
                    }
                }
            }
            Token(mark, _) => Err(ScanError::new(
                mark,
                "while parsing a block collection, did not find expected '-' indicator",
            )),
        }
    }

    fn flow_sequence_entry_mapping_key(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(mark, TokenType::Value)
            | Token(mark, TokenType::FlowEntry)
            | Token(mark, TokenType::FlowSequenceEnd) => {
                self.skip();
                self.state = State::FlowSequenceEntryMappingValue;
                Ok((Event::empty_scalar(), mark))
            }
            _ => {
                self.push_state(State::FlowSequenceEntryMappingValue);
                self.parse_node(false, false)
            }
        }
    }

    fn flow_sequence_entry_mapping_value(&mut self) -> ParseResult {
        match *self.peek_token()? {
            Token(_, TokenType::Value) => {
                self.skip();
                self.state = State::FlowSequenceEntryMappingValue;
                match *self.peek_token()? {
                    Token(mark, TokenType::FlowEntry) | Token(mark, TokenType::FlowSequenceEnd) => {
                        self.state = State::FlowSequenceEntryMappingEnd;
                        Ok((Event::empty_scalar(), mark))
                    }
                    _ => {
                        self.push_state(State::FlowSequenceEntryMappingEnd);
                        self.parse_node(false, false)
                    }
                }
            }
            Token(mark, _) => {
                self.state = State::FlowSequenceEntryMappingEnd;
                Ok((Event::empty_scalar(), mark))
            }
        }
    }

    fn flow_sequence_entry_mapping_end(&mut self) -> ParseResult {
        self.state = State::FlowSequenceEntry;
        Ok((Event::MappingEnd, self.scanner.mark()))
    }
}

#[cfg(test)]
mod test {
    use super::{Event, Parser};

    #[test]
    fn test_peek_eq_parse() {
        let s = "
a0 bb: val
a1: &x
    b1: 4
    b2: d
a2: 4
a3: [1, 2, 3]
a4:
    - [a1, a2]
    - 2
a5: *x
";
        let mut p = Parser::new(s.chars());
        while {
            let event_peek = p.peek().unwrap().clone();
            let event = p.next().unwrap();
            assert_eq!(event, event_peek);
            event.0 != Event::StreamEnd
        } {}
    }
}

[ Dauer der Verarbeitung: 0.33 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge