Small plain scalar scanning fixes.

This commit is contained in:
Jesse Beder 2008-06-27 20:54:43 +00:00
parent 8fca02fb2a
commit a224c7818b
6 changed files with 82 additions and 48 deletions

View file

@ -34,10 +34,7 @@ namespace YAML
std::ifstream fin(fileName.c_str()); std::ifstream fin(fileName.c_str());
Scanner scanner(fin); Scanner scanner(fin);
try { scanner.Scan();
scanner.Scan();
} catch(const Exception& e) {
}
getchar(); getchar();
// if(!scanner) // if(!scanner)
// return; // return;

View file

@ -37,6 +37,16 @@ namespace YAML
return ch; return ch;
} }
// GetChar
// . Extracts 'n' characters from the stream and updates our position
std::string Scanner::GetChar(int n)
{
std::string ret;
for(int i=0;i<n;i++)
ret += GetChar();
return ret;
}
// Eat // Eat
// . Eats 'n' characters and updates our position. // . Eats 'n' characters and updates our position.
void Scanner::Eat(int n) void Scanner::Eat(int n)
@ -199,11 +209,8 @@ namespace YAML
if(INPUT.peek() == Keys::FoldedScalar && m_flowLevel == 0) if(INPUT.peek() == Keys::FoldedScalar && m_flowLevel == 0)
return; return;
if(INPUT.peek() == '\'') if(INPUT.peek() == '\'' || INPUT.peek() == '\"')
return; return ScanAndEnqueue(new QuotedScalarToken);
if(INPUT.peek() == '\"')
return;
// plain scalars // plain scalars
if(IsPlainScalar()) if(IsPlainScalar())
@ -290,7 +297,7 @@ namespace YAML
while(!m_tokens.empty()) { while(!m_tokens.empty()) {
Token *pToken = m_tokens.front(); Token *pToken = m_tokens.front();
m_tokens.pop(); m_tokens.pop();
std::cout << typeid(*pToken).name() << std::endl; std::cout << typeid(*pToken).name() << ": " << *pToken << std::endl;
delete pToken; delete pToken;
} }
} }

View file

@ -8,7 +8,7 @@
namespace YAML namespace YAML
{ {
class Token; struct Token;
class Scanner class Scanner
{ {
@ -25,6 +25,7 @@ namespace YAML
private: private:
char GetChar(); char GetChar();
std::string GetChar(int n);
void Eat(int n = 1); void Eat(int n = 1);
void EatLineBreak(); void EatLineBreak();

View file

@ -199,6 +199,10 @@ namespace YAML
} }
// PlainScalarToken // PlainScalarToken
// . We scan these in passes of two steps each: First, grab all non-whitespace
// characters we can, and then grab all whitespace characters we can.
// . This has the benefit of letting us handle leading whitespace (which is chomped)
// and in-line whitespace (which is kept) separately.
template <> PlainScalarToken *Scanner::ScanToken(PlainScalarToken *pToken) template <> PlainScalarToken *Scanner::ScanToken(PlainScalarToken *pToken)
{ {
// TODO: "save simple key" // TODO: "save simple key"
@ -230,20 +234,21 @@ namespace YAML
if(m_flowLevel == 0 && Exp::EndScalar.Matches(INPUT)) if(m_flowLevel == 0 && Exp::EndScalar.Matches(INPUT))
break; break;
// join whitespace
if(leadingBlanks) { if(leadingBlanks) {
if(!leadingBreaks.empty() && leadingBreaks[0] == '\n') { if(Exp::Break.Matches(leadingBreaks)) {
// fold line break? // fold line break?
if(trailingBreaks.empty()) if(trailingBreaks.empty())
scalar += ' '; scalar += ' ';
else { else
scalar += trailingBreaks; scalar += trailingBreaks;
trailingBreaks = "";
}
} else { } else {
scalar += leadingBreaks + trailingBreaks; scalar += leadingBreaks + trailingBreaks;
leadingBreaks = "";
trailingBreaks = "";
} }
leadingBlanks = false;
leadingBreaks = "";
trailingBreaks = "";
} else if(!whitespace.empty()) { } else if(!whitespace.empty()) {
scalar += whitespace; scalar += whitespace;
whitespace = ""; whitespace = "";
@ -260,7 +265,8 @@ namespace YAML
// now eat blanks // now eat blanks
while(INPUT && Exp::BlankOrBreak.Matches(INPUT)) { while(INPUT && Exp::BlankOrBreak.Matches(INPUT)) {
if(Exp::Blank.Matches(INPUT)) { if(Exp::Blank.Matches(INPUT)) {
if(leadingBlanks && m_column <= m_indents.top()) // can't use tabs as indentation! only spaces!
if(INPUT.peek() == '\t' && leadingBlanks && m_column <= m_indents.top())
throw IllegalTabInScalar(); throw IllegalTabInScalar();
// maybe store this character // maybe store this character
@ -269,13 +275,17 @@ namespace YAML
else else
Eat(1); Eat(1);
} else { } else {
// we know it's a line break; see how many characters to read
int n = Exp::Break.Match(INPUT);
std::string line = GetChar(n);
// where to store this character? // where to store this character?
if(!leadingBlanks) { if(!leadingBlanks) {
leadingBlanks = true; leadingBlanks = true;
whitespace = ""; whitespace = "";
leadingBreaks += GetChar(); leadingBreaks += line;
} else } else
trailingBreaks += GetChar(); trailingBreaks += line;
} }
} }
@ -285,10 +295,16 @@ namespace YAML
} }
// now modify our token // now modify our token
pToken->SetValue(scalar); pToken->value = scalar;
if(leadingBlanks) if(leadingBlanks)
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
return pToken; return pToken;
} }
// QuotedScalarToken
template <> QuotedScalarToken *Scanner::ScanToken(QuotedScalarToken *pToken)
{
return pToken;
}
} }

View file

@ -1,5 +1,10 @@
--- ---
- milk - green
eggs,
and
ham!
- eggs # this is really important! - eggs # this is really important!
- cheese and bread - - cheddar cheese
- american cheese
- bread
... ...

58
token.h
View file

@ -1,32 +1,40 @@
#pragma once #pragma once
#include <ios>
namespace YAML namespace YAML
{ {
class Token { public: virtual ~Token() {} }; struct Token {
virtual ~Token() {}
virtual void Write(std::ostream& out) const {}
class StreamStartToken: public Token {}; friend std::ostream& operator << (std::ostream& out, const Token& token) { token.Write(out); return out; }
class StreamEndToken: public Token {};
class DocumentStartToken: public Token {};
class DocumentEndToken: public Token {};
class BlockSeqStartToken: public Token {};
class BlockMapStartToken: public Token {};
class BlockEndToken: public Token {};
class BlockEntryToken: public Token {};
class FlowSeqStartToken: public Token {};
class FlowMapStartToken: public Token {};
class FlowSeqEndToken: public Token {};
class FlowMapEndToken: public Token {};
class FlowEntryToken: public Token {};
class KeyToken: public Token {};
class ValueToken: public Token {};
class PlainScalarToken: public Token {
public:
void SetValue(const std::string& value) { m_value = value; }
protected:
std::string m_value;
}; };
struct StreamStartToken: public Token {};
struct StreamEndToken: public Token {};
struct DocumentStartToken: public Token {};
struct DocumentEndToken: public Token {};
struct BlockSeqStartToken: public Token {};
struct BlockMapStartToken: public Token {};
struct BlockEndToken: public Token {};
struct BlockEntryToken: public Token {};
struct FlowSeqStartToken: public Token {};
struct FlowMapStartToken: public Token {};
struct FlowSeqEndToken: public Token {};
struct FlowMapEndToken: public Token {};
struct FlowEntryToken: public Token {};
struct KeyToken: public Token {};
struct ValueToken: public Token {};
struct ScalarToken: public Token {
std::string value;
virtual void Write(std::ostream& out) const { out << value; }
};
struct PlainScalarToken: public ScalarToken {};
struct QuotedScalarToken: public ScalarToken {};
} }