// BlockScalarToken // . These need a little extra processing beforehand. // . We need to scan the line where the indicator is (this doesn't count as part of the scalar), // and then we need to figure out what level of indentation we'll be using. void Scanner::ScanBlockScalar() { std::string scalar; ScanScalarParams params; params.indent = 1; params.detectIndent = true; // eat block indicator ('|' or '>') Mark mark = INPUT.mark(); char indicator = INPUT.get(); params.fold = (indicator == Keys::FoldedScalar); // eat chomping/indentation indicators int n = Exp::Chomp.Match(INPUT); for(int i=0;i<n;i++) { char ch = INPUT.get(); if(ch == '+') params.chomp = KEEP; else if(ch == '-') params.chomp = STRIP; else if(Exp::Digit.Matches(ch)) { if(ch == '0') throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); params.indent = ch - '0'; params.detectIndent = false; } } // now eat whitespace while(Exp::Blank.Matches(INPUT)) INPUT.eat(1); // and comments to the end of the line if(Exp::Comment.Matches(INPUT)) while(INPUT && !Exp::Break.Matches(INPUT)) INPUT.eat(1); // if it's not a line break, then we ran into a bad character inline if(INPUT && !Exp::Break.Matches(INPUT)) throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK); // set the initial indentation if(GetTopIndent() >= 0) params.indent += GetTopIndent(); params.eatLeadingWhitespace = false; params.trimTrailingSpaces = false; params.onTabInIndentation = THROW; scalar = ScanScalar(INPUT, params); // simple keys always ok after block scalars (since we're gonna start a new line anyways) m_simpleKeyAllowed = true; Token token(TT_SCALAR, mark); token.value = scalar; m_tokens.push(token); }
// PlainScalar void Scanner::ScanPlainScalar() { std::string scalar; // set up the scanning parameters ScanScalarParams params; params.end = (InFlowContext() ? Exp::EndScalarInFlow() : Exp::EndScalar()) || (Exp::BlankOrBreak() + Exp::Comment()); params.eatEnd = false; params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); params.fold = FOLD_FLOW; params.eatLeadingWhitespace = true; params.trimTrailingSpaces = true; params.chomp = STRIP; params.onDocIndicator = BREAK; params.onTabInIndentation = THROW; // insert a potential simple key InsertPotentialSimpleKey(); Mark mark = INPUT.mark(); scalar = ScanScalar(INPUT, params); // can have a simple key only if we ended the scalar by starting a new line m_simpleKeyAllowed = params.leadingSpaces; m_canBeJSONFlow = false; // finally, check and see if we ended on an illegal character //if(Exp::IllegalCharInScalar.Matches(INPUT)) // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); Token token(Token::PLAIN_SCALAR, mark); token.value = scalar; m_tokens.push(token); }
// QuotedScalar void Scanner::ScanQuotedScalar() { std::string scalar; // peek at single or double quote (don't eat because we need to preserve (for // the time being) the input position) char quote = INPUT.peek(); bool single = (quote == '\''); // setup the scanning parameters ScanScalarParams params; RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote)); params.end = &end; params.eatEnd = true; params.escape = (single ? '\'' : '\\'); params.indent = 0; params.fold = FOLD_FLOW; params.eatLeadingWhitespace = true; params.trimTrailingSpaces = false; params.chomp = CLIP; params.onDocIndicator = THROW; // insert a potential simple key InsertPotentialSimpleKey(); Mark mark = INPUT.mark(); // now eat that opening quote INPUT.get(); // and scan scalar = ScanScalar(INPUT, params); m_simpleKeyAllowed = false; m_canBeJSONFlow = true; Token token(Token::NON_PLAIN_SCALAR, mark); token.value = scalar; m_tokens.push(token); }