diff --git a/document.cpp b/document.cpp index cb5c7cf06c..74286e99a7 100644 --- a/document.cpp +++ b/document.cpp @@ -1,12 +1,5 @@ #include "document.h" #include "node.h" -#include "parser.h" -#include "scanner.h" -#include "exceptions.h" -#include - -#include -#include "token.h" namespace YAML { @@ -14,11 +7,6 @@ namespace YAML { } - Document::Document(const std::string& fileName): m_pRoot(0) - { - Load(fileName); - } - Document::~Document() { Clear(); @@ -29,25 +17,4 @@ namespace YAML delete m_pRoot; m_pRoot = 0; } - - void Document::Load(const std::string& fileName) - { - Clear(); - - std::ifstream fin(fileName.c_str()); - Scanner scanner(fin); - - // scan and output, for now - while(1) { - Token *pToken = scanner.GetNextToken(); - if(!pToken) - break; - - std::cout << typeid(*pToken).name() << ": " << *pToken << std::endl; - delete pToken; - } - getchar(); - -// m_pRoot = parser.ReadNextNode(); - } } diff --git a/document.h b/document.h index 285bf94569..62be716125 100644 --- a/document.h +++ b/document.h @@ -1,7 +1,5 @@ #pragma once -#include - namespace YAML { class Node; @@ -10,11 +8,9 @@ namespace YAML { public: Document(); - Document(const std::string& fileName); ~Document(); void Clear(); - void Load(const std::string& fileName); private: Node *m_pRoot; diff --git a/main.cpp b/main.cpp index 5e02ba3af3..2a8898ab13 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,12 @@ -#include "document.h" -#include "regex.h" +#include "reader.h" +#include int main() { - YAML::Document doc("test.yaml"); + std::ifstream fin("test.yaml"); + YAML::Reader reader(fin); + YAML::Document doc; + reader.GetNextDocument(doc); return 0; } \ No newline at end of file diff --git a/node.cpp b/node.cpp index 33c688fb13..c3ca6a45aa 100644 --- a/node.cpp +++ b/node.cpp @@ -20,15 +20,4 @@ namespace YAML delete m_pContent; m_pContent = 0; } - - void Node::Read(Parser *pParser, const std::string& token) - { - Clear(); - - if(token == std::string("") + SeqToken) { - m_pContent = new Sequence(pParser); - } else { - m_pContent = new Scalar(token); - } - } } diff --git a/node.h b/node.h index c8bd7e5ba3..b553faab74 100644 --- a/node.h +++ b/node.h @@ -10,7 +10,6 @@ namespace YAML const std::string MapTag = "!!map"; class Content; - class Parser; class Node { @@ -19,7 +18,6 @@ namespace YAML ~Node(); void Clear(); - void Read(Parser *pParser, const std::string& token); private: std::string m_tag; diff --git a/parser.cpp b/parser.cpp index 999fa90c13..3ec881cedf 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1,141 +1,33 @@ #include "parser.h" #include "node.h" +#include "token.h" + +#include namespace YAML { - Parser::Parser(std::istream& in): INPUT(in), m_ok(true) + Parser::Parser(std::istream& in): m_scanner(in) { - m_state.push(State(C_BLOCK, -1, true)); - - // read header - std::string token = ReadNextToken(); - if(token != DocStart) - m_ok = false; + // eat the stream start token + // TODO: check? + Token *pToken = m_scanner.GetNextToken(); } Parser::~Parser() { } - Parser::operator bool() const + void Parser::GetNextDocument(Document& document) { - return m_ok; - } + // scan and output, for now + while(1) { + Token *pToken = m_scanner.GetNextToken(); + if(!pToken) + break; - bool Parser::operator !() const - { - return !m_ok; - } - - bool Parser::IsWhitespace(char ch) - { - return (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'); - } - - void Parser::Putback(const std::string& str) - { - for(int i=str.size()-1;i>=0;i--) - INPUT.putback(str[i]); - } - - // StringWhitespace - // . Strips up to n whitespace characters (or as many - // as there are, if n is -1) - void Parser::StripWhitespace(int n) - { - while(--n >= 0 && IsWhitespace(INPUT.peek())) - INPUT.get(); - } - - int Parser::GetNumOfSpaces() - { - // get 'em out - int n = 0; - while(INPUT.peek() == ' ') { - INPUT.get(); - n++; + std::cout << typeid(*pToken).name() << ": " << *pToken << std::endl; + delete pToken; } - - // put 'em back - for(int i=0;iRead(this, token); - return pNode; - } - - // ReadNextToken - // . Reads: - // . If the first character is non-whitespace, non-special token, then until - // the end of this scalar. - std::string Parser::ReadNextToken() - { - const State& state = m_state.top(); - - if(state.startingNewLine) { - int n = GetNumOfSpaces(); - StripWhitespace(n); - if(n > state.indent) { - m_state.push(State(C_BLOCK, n, true)); - }; - - while(m_state.top().startingNewLine && n < m_state.top().indent) - m_state.pop(); - } - - char ch = INPUT.peek(); - if(IsWhitespace(ch)) - return ""; // TODO - - if(ch == SeqToken) { - // grab token - INPUT.get(); - - // is next token whitespace? - if(!IsWhitespace(INPUT.peek())) { - // read entire line - std::string line; - std::getline(INPUT, line); - return ch + line; - } - - // if so, strip whitespace and go - StripWhitespace(); - - return std::string("") + SeqToken; - } - - // read until end-of-line - std::string line; - std::getline(INPUT, line); - return line; + getchar(); } } diff --git a/parser.h b/parser.h index fbbae0b216..6b4602b6bd 100644 --- a/parser.h +++ b/parser.h @@ -2,54 +2,22 @@ #include #include -#include +#include "scanner.h" +#include "document.h" namespace YAML { class Node; - const std::string DocStart = "---"; - const std::string DocEnd = "..."; - - const char SeqToken = '-'; - - enum CONTEXT { C_BLOCK, C_FLOW }; - class Parser { - public: - struct State - { - State(CONTEXT context_, int indent_, bool startingNewLine_) - : context(context_), indent(indent_), startingNewLine(startingNewLine_) {} - - CONTEXT context; - int indent; - bool startingNewLine; - }; - public: Parser(std::istream& in); ~Parser(); - operator bool () const; - bool operator !() const; - - // parse helpers - static bool IsWhitespace(char ch); - void Putback(const std::string& str); - void StripWhitespace(int n = -1); - int GetNumOfSpaces(); - bool SeqContinues(); - - // readers - Node *ReadNextNode(); - std::string ReadNextToken(); + void GetNextDocument(Document& document); private: - bool m_ok; - - std::istream& INPUT; - std::stack m_state; + Scanner m_scanner; }; } diff --git a/reader.cpp b/reader.cpp new file mode 100644 index 0000000000..4d94459066 --- /dev/null +++ b/reader.cpp @@ -0,0 +1,21 @@ +#include "reader.h" +#include "scanner.h" +#include "parser.h" + +namespace YAML +{ + Reader::Reader(std::istream& in): m_pParser(0) + { + m_pParser = new Parser(in); + } + + Reader::~Reader() + { + delete m_pParser; + } + + void Reader::GetNextDocument(Document& document) + { + m_pParser->GetNextDocument(document); + } +} diff --git a/reader.h b/reader.h new file mode 100644 index 0000000000..3226af9c8e --- /dev/null +++ b/reader.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "document.h" + +namespace YAML +{ + class Parser; + + class Reader + { + public: + Reader(std::istream& in); + ~Reader(); + + void GetNextDocument(Document& document); + + private: + Parser *m_pParser; + }; +} diff --git a/sequence.cpp b/sequence.cpp index c9d3e4c4ae..b02b35f1c2 100644 --- a/sequence.cpp +++ b/sequence.cpp @@ -1,12 +1,11 @@ #include "sequence.h" #include "node.h" -#include "parser.h" namespace YAML { - Sequence::Sequence(Parser *pParser) + Sequence::Sequence() { - Read(pParser); + } Sequence::~Sequence() @@ -14,12 +13,4 @@ namespace YAML for(unsigned i=0;iReadNextNode(); - m_data.push_back(pNode); - } while(pParser->SeqContinues()); - } } diff --git a/sequence.h b/sequence.h index f230505b7b..cf7d1dd4d7 100644 --- a/sequence.h +++ b/sequence.h @@ -6,16 +6,13 @@ namespace YAML { class Node; - class Parser; class Sequence: public Content { public: - Sequence(Parser *pParser); + Sequence(); virtual ~Sequence(); - void Read(Parser *pParser); - protected: std::vector m_data; }; diff --git a/yaml-reader.vcproj b/yaml-reader.vcproj index a0ae76d41f..46a4707a09 100644 --- a/yaml-reader.vcproj +++ b/yaml-reader.vcproj @@ -169,10 +169,6 @@ RelativePath=".\document.cpp" > - - @@ -186,41 +182,57 @@ > - - - - - - - - - - - + + + + + + + + + + + + + + + - + + + - - @@ -252,37 +260,53 @@ > - - - - - - - - + + + + + + + + + + + + + + + +