From 011a608b5ac79ee2545b6d484e7df82499f92a0a Mon Sep 17 00:00:00 2001 From: jbeder Date: Thu, 29 Oct 2009 21:05:48 +0000 Subject: [PATCH] Implemented adjacent key:value pairs when the key is JSON-like --- src/exp.h | 3 ++- src/scanner.cpp | 15 +++++++++++++-- src/scanner.h | 3 +++ src/scantoken.cpp | 13 +++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/exp.h b/src/exp.h index c84f12a..f8dbc29 100644 --- a/src/exp.h +++ b/src/exp.h @@ -43,7 +43,8 @@ namespace YAML const RegEx Key = RegEx('?'), KeyInFlow = RegEx('?') + BlankOrBreak; const RegEx Value = RegEx(':') + (BlankOrBreak || RegEx()), - ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR)); + ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR)), + ValueInJSONFlow = RegEx(':'); const RegEx Comment = RegEx('#'); const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak; const RegEx URI = Word || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex + Hex); diff --git a/src/scanner.cpp b/src/scanner.cpp index 81900d0..13963a4 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -8,7 +8,7 @@ namespace YAML { Scanner::Scanner(std::istream& in) - : INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false) + : INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false) { } @@ -142,7 +142,7 @@ namespace YAML if((InBlockContext() ? Exp::Key : Exp::KeyInFlow).Matches(INPUT)) return ScanKey(); - if((InBlockContext() ? Exp::Value : Exp::ValueInFlow).Matches(INPUT)) + if(GetValueRegex().Matches(INPUT)) return ScanValue(); // alias/anchor @@ -226,6 +226,16 @@ namespace YAML return false; } + // GetValueRegex + // . Get the appropriate regex to check if it's a value token + const RegEx& Scanner::GetValueRegex() const + { + if(InBlockContext()) + return Exp::Value; + + return m_canBeJSONFlow ? Exp::ValueInJSONFlow : Exp::ValueInFlow; + } + // StartStream // . Set the initial conditions for starting a stream. void Scanner::StartStream() @@ -410,3 +420,4 @@ namespace YAML m_anchors.clear(); } } + diff --git a/src/scanner.h b/src/scanner.h index a0ac7ee..28ce96d 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -16,6 +16,7 @@ namespace YAML { class Node; + class RegEx; class Scanner { @@ -78,6 +79,7 @@ namespace YAML void ThrowParserException(const std::string& msg) const; bool IsWhitespaceToBeEaten(char ch); + const RegEx& GetValueRegex() const; struct SimpleKey { SimpleKey(const Mark& mark_, int flowLevel_); @@ -120,6 +122,7 @@ namespace YAML // state info bool m_startedStream, m_endedStream; bool m_simpleKeyAllowed; + bool m_canBeJSONFlow; std::stack m_simpleKeys; std::stack m_indents; std::vector m_indentRefs; // for "garbage collection" diff --git a/src/scantoken.cpp b/src/scantoken.cpp index b026356..4320364 100644 --- a/src/scantoken.cpp +++ b/src/scantoken.cpp @@ -24,6 +24,7 @@ namespace YAML PopAllSimpleKeys(); m_simpleKeyAllowed = false; + m_canBeJSONFlow = false; // store pos and eat indicator Token token(Token::DIRECTIVE, INPUT.mark()); @@ -60,6 +61,7 @@ namespace YAML PopAllIndents(); PopAllSimpleKeys(); m_simpleKeyAllowed = false; + m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); @@ -73,6 +75,7 @@ namespace YAML PopAllIndents(); PopAllSimpleKeys(); m_simpleKeyAllowed = false; + m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); @@ -86,6 +89,7 @@ namespace YAML // flows can be simple keys InsertPotentialSimpleKey(); m_simpleKeyAllowed = true; + m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); @@ -111,6 +115,7 @@ namespace YAML } m_simpleKeyAllowed = false; + m_canBeJSONFlow = true; // eat Mark mark = INPUT.mark(); @@ -138,6 +143,7 @@ namespace YAML } m_simpleKeyAllowed = true; + m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); @@ -158,6 +164,7 @@ namespace YAML PushIndentTo(INPUT.column(), IndentMarker::SEQ); m_simpleKeyAllowed = true; + m_canBeJSONFlow = false; // eat Mark mark = INPUT.mark(); @@ -190,6 +197,7 @@ namespace YAML { // and check that simple key bool isSimpleKey = VerifySimpleKey(); + m_canBeJSONFlow = false; if(isSimpleKey) { // can't follow a simple key with another simple key (dunno why, though - it seems fine) @@ -222,6 +230,7 @@ namespace YAML // insert a potential simple key InsertPotentialSimpleKey(); m_simpleKeyAllowed = false; + m_canBeJSONFlow = false; // eat the indicator Mark mark = INPUT.mark(); @@ -252,6 +261,7 @@ namespace YAML // insert a potential simple key InsertPotentialSimpleKey(); m_simpleKeyAllowed = false; + m_canBeJSONFlow = false; Token token(Token::TAG, INPUT.mark()); @@ -305,6 +315,7 @@ namespace YAML // 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)) @@ -347,6 +358,7 @@ namespace YAML // and scan scalar = ScanScalar(INPUT, params); m_simpleKeyAllowed = false; + m_canBeJSONFlow = true; Token token(Token::SCALAR, mark); token.value = scalar; @@ -413,6 +425,7 @@ namespace YAML // simple keys always ok after block scalars (since we're gonna start a new line anyways) m_simpleKeyAllowed = true; + m_canBeJSONFlow = false; Token token(Token::SCALAR, mark); token.value = scalar;