mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 13:28:01 +03:00
Beginning of first attempt to parse.
Will be completely wiped, I think, in favor of a Scanner (to tokens), then Parser mechanism.
This commit is contained in:
parent
4ed7f62431
commit
bcbca461de
11 changed files with 247 additions and 9 deletions
|
@ -1,5 +1,6 @@
|
|||
#include "document.h"
|
||||
#include "node.h"
|
||||
#include "parser.h"
|
||||
#include <fstream>
|
||||
|
||||
namespace YAML
|
||||
|
@ -29,7 +30,10 @@ namespace YAML
|
|||
Clear();
|
||||
|
||||
std::ifstream fin(fileName.c_str());
|
||||
m_pRoot = new Node;
|
||||
m_pRoot->Read(fin);
|
||||
Parser parser(fin);
|
||||
if(!parser)
|
||||
return;
|
||||
|
||||
m_pRoot = parser.ReadNextNode();
|
||||
}
|
||||
}
|
||||
|
|
12
node.cpp
12
node.cpp
|
@ -1,5 +1,8 @@
|
|||
#include "node.h"
|
||||
#include "content.h"
|
||||
#include "parser.h"
|
||||
#include "scalar.h"
|
||||
#include "sequence.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@ -18,7 +21,14 @@ namespace YAML
|
|||
m_pContent = 0;
|
||||
}
|
||||
|
||||
void Node::Read(std::istream& in)
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
3
node.h
3
node.h
|
@ -10,6 +10,7 @@ namespace YAML
|
|||
const std::string MapTag = "!!map";
|
||||
|
||||
class Content;
|
||||
class Parser;
|
||||
|
||||
class Node
|
||||
{
|
||||
|
@ -18,7 +19,7 @@ namespace YAML
|
|||
~Node();
|
||||
|
||||
void Clear();
|
||||
void Read(std::istream& in);
|
||||
void Read(Parser *pParser, const std::string& token);
|
||||
|
||||
private:
|
||||
std::string m_tag;
|
||||
|
|
141
parser.cpp
Normal file
141
parser.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "parser.h"
|
||||
#include "node.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Parser::Parser(std::istream& in): INPUT(in), m_ok(true)
|
||||
{
|
||||
m_state.push(State(C_BLOCK, -1, true));
|
||||
|
||||
// read header
|
||||
std::string token = ReadNextToken();
|
||||
if(token != DocStart)
|
||||
m_ok = false;
|
||||
}
|
||||
|
||||
Parser::~Parser()
|
||||
{
|
||||
}
|
||||
|
||||
Parser::operator bool() const
|
||||
{
|
||||
return m_ok;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
55
parser.h
Normal file
55
parser.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
bool m_ok;
|
||||
|
||||
std::istream& INPUT;
|
||||
std::stack <State> m_state;
|
||||
};
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace YAML
|
||||
{
|
||||
Scalar::Scalar()
|
||||
Scalar::Scalar(const std::string& data): m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
2
scalar.h
2
scalar.h
|
@ -8,7 +8,7 @@ namespace YAML
|
|||
class Scalar: public Content
|
||||
{
|
||||
public:
|
||||
Scalar();
|
||||
Scalar(const std::string& data);
|
||||
virtual ~Scalar();
|
||||
|
||||
protected:
|
||||
|
|
12
sequence.cpp
12
sequence.cpp
|
@ -1,10 +1,12 @@
|
|||
#include "sequence.h"
|
||||
#include "node.h"
|
||||
#include "parser.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Sequence::Sequence()
|
||||
Sequence::Sequence(Parser *pParser)
|
||||
{
|
||||
Read(pParser);
|
||||
}
|
||||
|
||||
Sequence::~Sequence()
|
||||
|
@ -12,4 +14,12 @@ 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,16 @@
|
|||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
class Parser;
|
||||
|
||||
class Sequence: public Content
|
||||
{
|
||||
public:
|
||||
Sequence();
|
||||
Sequence(Parser *pParser);
|
||||
virtual ~Sequence();
|
||||
|
||||
void Read(Parser *pParser);
|
||||
|
||||
protected:
|
||||
std::vector <Node *> m_data;
|
||||
};
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
---
|
||||
test
|
||||
- milk
|
||||
- eggs
|
||||
- cheese
|
|
@ -181,6 +181,10 @@
|
|||
RelativePath=".\node.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\parser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scalar.cpp"
|
||||
>
|
||||
|
@ -211,6 +215,10 @@
|
|||
RelativePath=".\node.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\parser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scalar.h"
|
||||
>
|
||||
|
@ -225,6 +233,10 @@
|
|||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\test.yaml"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue