Started the parser.

This commit is contained in:
Jesse Beder 2008-06-30 06:51:22 +00:00
parent ed6c294749
commit b6a0ef207b
12 changed files with 143 additions and 276 deletions

View file

@ -1,12 +1,5 @@
#include "document.h"
#include "node.h"
#include "parser.h"
#include "scanner.h"
#include "exceptions.h"
#include <fstream>
#include <iostream>
#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();
}
}

View file

@ -1,7 +1,5 @@
#pragma once
#include <string>
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;

View file

@ -1,9 +1,12 @@
#include "document.h"
#include "regex.h"
#include "reader.h"
#include <fstream>
int main()
{
YAML::Document doc("test.yaml");
std::ifstream fin("test.yaml");
YAML::Reader reader(fin);
YAML::Document doc;
reader.GetNextDocument(doc);
return 0;
}

View file

@ -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);
}
}
}

2
node.h
View file

@ -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;

View file

@ -1,141 +1,33 @@
#include "parser.h"
#include "node.h"
#include "token.h"
#include <iostream>
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;i<n;i++)
INPUT.putback(' ');
return n;
}
// SeqContinues
// . Returns true if the next item to be read is a continuation of the current sequence.
bool Parser::SeqContinues()
{
const State& state = m_state.top();
if(state.context != C_BLOCK)
return false;
int n = GetNumOfSpaces();
return (n == state.indent);
}
// ReadNextNode
// . Reads and returns the next node from the current input (to be used recursively).
// . The caller is responsible for cleanup!
Node *Parser::ReadNextNode()
{
if(!INPUT)
return 0;
std::string token = ReadNextToken();
if(token == DocStart || token == DocEnd)
return 0; // TODO: putback DocStart?
Node *pNode = new Node;
pNode->Read(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();
}
}

View file

@ -2,54 +2,22 @@
#include <ios>
#include <string>
#include <stack>
#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 <State> m_state;
Scanner m_scanner;
};
}

21
reader.cpp Normal file
View file

@ -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);
}
}

21
reader.h Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include <ios>
#include "document.h"
namespace YAML
{
class Parser;
class Reader
{
public:
Reader(std::istream& in);
~Reader();
void GetNextDocument(Document& document);
private:
Parser *m_pParser;
};
}

View file

@ -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;i<m_data.size();i++)
delete m_data[i];
}
void Sequence::Read(Parser *pParser)
{
do {
Node *pNode = pParser->ReadNextNode();
m_data.push_back(pNode);
} while(pParser->SeqContinues());
}
}

View file

@ -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 <Node *> m_data;
};

View file

@ -169,10 +169,6 @@
RelativePath=".\document.cpp"
>
</File>
<File
RelativePath=".\exp.cpp"
>
</File>
<File
RelativePath=".\main.cpp"
>
@ -186,41 +182,57 @@
>
</File>
<File
RelativePath=".\parser.cpp"
>
</File>
<File
RelativePath=".\regex.cpp"
RelativePath=".\reader.cpp"
>
</File>
<File
RelativePath=".\scalar.cpp"
>
</File>
<File
RelativePath=".\scanner.cpp"
>
</File>
<File
RelativePath=".\scanscalar.cpp"
>
</File>
<File
RelativePath=".\scantoken.cpp"
>
</File>
<File
RelativePath=".\sequence.cpp"
>
</File>
<File
RelativePath=".\simplekey.cpp"
<Filter
Name="Scanner"
>
</File>
<File
RelativePath=".\stream.cpp"
<File
RelativePath=".\exp.cpp"
>
</File>
<File
RelativePath=".\regex.cpp"
>
</File>
<File
RelativePath=".\scanner.cpp"
>
</File>
<File
RelativePath=".\scanscalar.cpp"
>
</File>
<File
RelativePath=".\scantoken.cpp"
>
</File>
<File
RelativePath=".\simplekey.cpp"
>
</File>
<File
RelativePath=".\stream.cpp"
>
</File>
</Filter>
<Filter
Name="Parser"
>
</File>
<File
RelativePath=".\parser.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
@ -239,10 +251,6 @@
RelativePath=".\exceptions.h"
>
</File>
<File
RelativePath=".\exp.h"
>
</File>
<File
RelativePath=".\map.h"
>
@ -252,37 +260,53 @@
>
</File>
<File
RelativePath=".\parser.h"
>
</File>
<File
RelativePath=".\regex.h"
RelativePath=".\reader.h"
>
</File>
<File
RelativePath=".\scalar.h"
>
</File>
<File
RelativePath=".\scanner.h"
>
</File>
<File
RelativePath=".\scanscalar.h"
>
</File>
<File
RelativePath=".\sequence.h"
>
</File>
<File
RelativePath=".\stream.h"
>
</File>
<File
RelativePath=".\token.h"
>
</File>
<Filter
Name="Scanner"
>
<File
RelativePath=".\exp.h"
>
</File>
<File
RelativePath=".\regex.h"
>
</File>
<File
RelativePath=".\scanner.h"
>
</File>
<File
RelativePath=".\scanscalar.h"
>
</File>
<File
RelativePath=".\stream.h"
>
</File>
</Filter>
<Filter
Name="Parser"
>
<File
RelativePath=".\parser.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"