// FlowEnd void Scanner::ScanFlowEnd() { if(InBlockContext()) throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); // we might have a solo entry in the flow context if(InFlowContext()) { if(m_flows.top() == FLOW_MAP && VerifySimpleKey()) m_tokens.push(Token(Token::VALUE, INPUT.mark())); else if(m_flows.top() == FLOW_SEQ) InvalidateSimpleKey(); } m_simpleKeyAllowed = false; m_canBeJSONFlow = true; // eat Mark mark = INPUT.mark(); char ch = INPUT.get(); // check that it matches the start FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP); if(m_flows.top() != flowType) throw ParserException(mark, ErrorMsg::FLOW_END); m_flows.pop(); Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END); m_tokens.push(Token(type, mark)); }
// ScanToNextToken // . Eats input until we reach the next token-like thing. void Scanner::ScanToNextToken() { while (1) { // first eat whitespace while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { if (InBlockContext() && Exp::Tab().Matches(INPUT)) m_simpleKeyAllowed = false; INPUT.eat(1); } // then eat a comment if (Exp::Comment().Matches(INPUT)) { // eat until line break while (INPUT && !Exp::Break().Matches(INPUT)) INPUT.eat(1); } // if it's NOT a line break, then we're done! if (!Exp::Break().Matches(INPUT)) break; // otherwise, let's eat the line break and keep going int n = Exp::Break().Match(INPUT); INPUT.eat(n); // oh yeah, and let's get rid of that simple key InvalidateSimpleKey(); // new line - we may be able to accept a simple key now if (InBlockContext()) m_simpleKeyAllowed = true; } }
// PopIndent // . Pops a single indent, pushing the proper token void Scanner::PopIndent() { const IndentMarker& indent = *m_indents.top(); m_indents.pop(); if (indent.status != IndentMarker::VALID) { InvalidateSimpleKey(); return; } if (indent.type == IndentMarker::SEQ) m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark())); else if (indent.type == IndentMarker::MAP) m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark())); }
// FlowEntry void Scanner::ScanFlowEntry() { // we might have a solo entry in the flow context if (InFlowContext()) { if (m_flows.top() == FLOW_MAP && VerifySimpleKey()) m_tokens.push(Token(Token::VALUE, INPUT.mark())); else if (m_flows.top() == FLOW_SEQ) InvalidateSimpleKey(); } m_simpleKeyAllowed = true; m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); INPUT.eat(1); m_tokens.push(Token(Token::FLOW_ENTRY, mark)); }