mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
Tags, anchors, and aliases are all parsed now.
This commit is contained in:
parent
8180a85a3b
commit
4c5a488f68
19 changed files with 303 additions and 93 deletions
|
@ -1,10 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
#include "parserstate.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
class Scanner;
|
class Scanner;
|
||||||
|
class Parser;
|
||||||
|
|
||||||
class Content
|
class Content
|
||||||
{
|
{
|
||||||
|
@ -12,7 +14,7 @@ namespace YAML
|
||||||
Content();
|
Content();
|
||||||
virtual ~Content();
|
virtual ~Content();
|
||||||
|
|
||||||
virtual void Parse(Scanner *pScanner) = 0;
|
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
|
||||||
virtual void Write(std::ostream& out, int indent) = 0;
|
virtual void Write(std::ostream& out, int indent) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace YAML
|
||||||
m_pRoot = 0;
|
m_pRoot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::Parse(Scanner *pScanner)
|
void Document::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace YAML
|
||||||
|
|
||||||
// now create our root node and parse it
|
// now create our root node and parse it
|
||||||
m_pRoot = new Node;
|
m_pRoot = new Node;
|
||||||
m_pRoot->Parse(pScanner);
|
m_pRoot->Parse(pScanner, state);
|
||||||
|
|
||||||
// and finally eat any doc ends we see
|
// and finally eat any doc ends we see
|
||||||
while(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_DOC_END)
|
while(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_DOC_END)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
#include "parserstate.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -14,7 +15,7 @@ namespace YAML
|
||||||
~Document();
|
~Document();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Parse(Scanner *pScanner);
|
void Parse(Scanner *pScanner, const ParserState& state);
|
||||||
|
|
||||||
friend std::ostream& operator << (std::ostream& out, const Document& doc);
|
friend std::ostream& operator << (std::ostream& out, const Document& doc);
|
||||||
|
|
||||||
|
|
3
main.cpp
3
main.cpp
|
@ -8,8 +8,11 @@ int main()
|
||||||
YAML::Parser parser(fin);
|
YAML::Parser parser(fin);
|
||||||
|
|
||||||
YAML::Document doc;
|
YAML::Document doc;
|
||||||
|
while(parser) {
|
||||||
|
std::cout << "---\n";
|
||||||
parser.GetNextDocument(doc);
|
parser.GetNextDocument(doc);
|
||||||
std::cout << doc;
|
std::cout << doc;
|
||||||
|
}
|
||||||
getchar();
|
getchar();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
18
map.cpp
18
map.cpp
|
@ -23,7 +23,7 @@ namespace YAML
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::Parse(Scanner *pScanner)
|
void Map::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ namespace YAML
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
|
||||||
switch(pToken->type) {
|
switch(pToken->type) {
|
||||||
case TT_BLOCK_MAP_START: ParseBlock(pScanner); break;
|
case TT_BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
||||||
case TT_FLOW_MAP_START: ParseFlow(pScanner); break;
|
case TT_FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::ParseBlock(Scanner *pScanner)
|
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->EatNextToken();
|
pScanner->EatNextToken();
|
||||||
|
@ -58,17 +58,17 @@ namespace YAML
|
||||||
m_data[pKey] = pValue;
|
m_data[pKey] = pValue;
|
||||||
|
|
||||||
// grab key
|
// grab key
|
||||||
pKey->Parse(pScanner);
|
pKey->Parse(pScanner, state);
|
||||||
|
|
||||||
// now grab value (optional)
|
// now grab value (optional)
|
||||||
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) {
|
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) {
|
||||||
pScanner->PopNextToken();
|
pScanner->PopNextToken();
|
||||||
pValue->Parse(pScanner);
|
pValue->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::ParseFlow(Scanner *pScanner)
|
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->EatNextToken();
|
pScanner->EatNextToken();
|
||||||
|
@ -95,12 +95,12 @@ namespace YAML
|
||||||
m_data[pKey] = pValue;
|
m_data[pKey] = pValue;
|
||||||
|
|
||||||
// grab key
|
// grab key
|
||||||
pKey->Parse(pScanner);
|
pKey->Parse(pScanner, state);
|
||||||
|
|
||||||
// now grab value (optional)
|
// now grab value (optional)
|
||||||
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) {
|
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) {
|
||||||
pScanner->PopNextToken();
|
pScanner->PopNextToken();
|
||||||
pValue->Parse(pScanner);
|
pValue->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||||
|
|
6
map.h
6
map.h
|
@ -14,12 +14,12 @@ namespace YAML
|
||||||
virtual ~Map();
|
virtual ~Map();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
virtual void Parse(Scanner *pScanner);
|
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||||
virtual void Write(std::ostream& out, int indent);
|
virtual void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseBlock(Scanner *pScanner);
|
void ParseBlock(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseFlow(Scanner *pScanner);
|
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map <Node *, Node *> node_map;
|
typedef std::map <Node *, Node *> node_map;
|
||||||
|
|
27
node.cpp
27
node.cpp
|
@ -25,11 +25,11 @@ namespace YAML
|
||||||
m_alias = false;
|
m_alias = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::Parse(Scanner *pScanner)
|
void Node::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
ParseHeader(pScanner);
|
ParseHeader(pScanner, state);
|
||||||
|
|
||||||
// is this an alias? if so, it can have no content
|
// is this an alias? if so, it can have no content
|
||||||
if(m_alias)
|
if(m_alias)
|
||||||
|
@ -43,24 +43,24 @@ namespace YAML
|
||||||
switch(pToken->type) {
|
switch(pToken->type) {
|
||||||
case TT_SCALAR:
|
case TT_SCALAR:
|
||||||
m_pContent = new Scalar;
|
m_pContent = new Scalar;
|
||||||
m_pContent->Parse(pScanner);
|
m_pContent->Parse(pScanner, state);
|
||||||
break;
|
break;
|
||||||
case TT_FLOW_SEQ_START:
|
case TT_FLOW_SEQ_START:
|
||||||
case TT_BLOCK_SEQ_START:
|
case TT_BLOCK_SEQ_START:
|
||||||
case TT_BLOCK_ENTRY:
|
case TT_BLOCK_ENTRY:
|
||||||
m_pContent = new Sequence;
|
m_pContent = new Sequence;
|
||||||
m_pContent->Parse(pScanner);
|
m_pContent->Parse(pScanner, state);
|
||||||
break;
|
break;
|
||||||
case TT_FLOW_MAP_START:
|
case TT_FLOW_MAP_START:
|
||||||
case TT_BLOCK_MAP_START:
|
case TT_BLOCK_MAP_START:
|
||||||
m_pContent = new Map;
|
m_pContent = new Map;
|
||||||
m_pContent->Parse(pScanner);
|
m_pContent->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHeader
|
// ParseHeader
|
||||||
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
||||||
void Node::ParseHeader(Scanner *pScanner)
|
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
@ -68,26 +68,27 @@ namespace YAML
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch(pToken->type) {
|
switch(pToken->type) {
|
||||||
case TT_TAG: ParseTag(pScanner); break;
|
case TT_TAG: ParseTag(pScanner, state); break;
|
||||||
case TT_ANCHOR: ParseAnchor(pScanner); break;
|
case TT_ANCHOR: ParseAnchor(pScanner, state); break;
|
||||||
case TT_ALIAS: ParseAlias(pScanner); break;
|
case TT_ALIAS: ParseAlias(pScanner, state); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseTag(Scanner *pScanner)
|
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
if(m_tag != "")
|
if(m_tag != "")
|
||||||
return; // TODO: throw
|
return; // TODO: throw
|
||||||
|
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
m_tag = pToken->value;
|
m_tag = state.TranslateTag(pToken->value);
|
||||||
|
|
||||||
for(unsigned i=0;i<pToken->params.size();i++)
|
for(unsigned i=0;i<pToken->params.size();i++)
|
||||||
m_tag += pToken->params[i];
|
m_tag += pToken->params[i];
|
||||||
pScanner->PopNextToken();
|
pScanner->PopNextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAnchor(Scanner *pScanner)
|
void Node::ParseAnchor(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
if(m_anchor != "")
|
if(m_anchor != "")
|
||||||
return; // TODO: throw
|
return; // TODO: throw
|
||||||
|
@ -98,7 +99,7 @@ namespace YAML
|
||||||
pScanner->PopNextToken();
|
pScanner->PopNextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAlias(Scanner *pScanner)
|
void Node::ParseAlias(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
if(m_anchor != "")
|
if(m_anchor != "")
|
||||||
return; // TODO: throw
|
return; // TODO: throw
|
||||||
|
|
11
node.h
11
node.h
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
#include "parserstate.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -19,14 +20,14 @@ namespace YAML
|
||||||
~Node();
|
~Node();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Parse(Scanner *pScanner);
|
void Parse(Scanner *pScanner, const ParserState& state);
|
||||||
void Write(std::ostream& out, int indent);
|
void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseHeader(Scanner *pScanner);
|
void ParseHeader(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseTag(Scanner *pScanner);
|
void ParseTag(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseAnchor(Scanner *pScanner);
|
void ParseAnchor(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseAlias(Scanner *pScanner);
|
void ParseAlias(Scanner *pScanner, const ParserState& state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_alias;
|
bool m_alias;
|
||||||
|
|
74
parser.cpp
74
parser.cpp
|
@ -1,13 +1,14 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include <iostream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
Parser::Parser(std::istream& in): m_pScanner(0)
|
Parser::Parser(std::istream& in): m_pScanner(0)
|
||||||
{
|
{
|
||||||
m_pScanner = new Scanner(in);
|
m_pScanner = new Scanner(in);
|
||||||
|
m_state.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::~Parser()
|
Parser::~Parser()
|
||||||
|
@ -15,19 +16,82 @@ namespace YAML
|
||||||
delete m_pScanner;
|
delete m_pScanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::GetNextDocument(Document& document)
|
Parser::operator bool() const
|
||||||
{
|
{
|
||||||
document.Parse(m_pScanner);
|
return m_pScanner->PeekNextToken() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::PrintTokens()
|
void Parser::GetNextDocument(Document& document)
|
||||||
|
{
|
||||||
|
// first read directives
|
||||||
|
ParseDirectives();
|
||||||
|
|
||||||
|
// then parse the document
|
||||||
|
document.Parse(m_pScanner, m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::ParseDirectives()
|
||||||
|
{
|
||||||
|
bool readDirective = false;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
Token *pToken = m_pScanner->PeekNextToken();
|
||||||
|
if(!pToken || pToken->type != TT_DIRECTIVE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// we keep the directives from the last document if none are specified;
|
||||||
|
// but if any directives are specific, then we reset them
|
||||||
|
if(!readDirective)
|
||||||
|
m_state.Reset();
|
||||||
|
|
||||||
|
readDirective = true;
|
||||||
|
HandleDirective(pToken->value, pToken->params);
|
||||||
|
m_pScanner->PopNextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::HandleDirective(const std::string& name, const std::vector <std::string>& params)
|
||||||
|
{
|
||||||
|
if(name == "YAML")
|
||||||
|
HandleYamlDirective(params);
|
||||||
|
else if(name == "TAG")
|
||||||
|
HandleTagDirective(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleYamlDirective
|
||||||
|
// . Should be of the form 'major.minor' (like a version number)
|
||||||
|
void Parser::HandleYamlDirective(const std::vector <std::string>& params)
|
||||||
|
{
|
||||||
|
if(params.empty())
|
||||||
|
return; // TODO: throw? (or throw on params.size() > 1?)
|
||||||
|
|
||||||
|
std::stringstream str(params[0]);
|
||||||
|
str >> m_state.version.major;
|
||||||
|
str.get();
|
||||||
|
str >> m_state.version.minor;
|
||||||
|
if(!str)
|
||||||
|
return; // TODO: throw? (or throw if there are any more characters in the stream?)
|
||||||
|
|
||||||
|
// TODO: throw on major > 1? warning on major == 1, minor > 1?
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::HandleTagDirective(const std::vector <std::string>& params)
|
||||||
|
{
|
||||||
|
if(params.size() != 2)
|
||||||
|
return; // TODO: throw?
|
||||||
|
|
||||||
|
std::string handle = params[0], prefix = params[1];
|
||||||
|
m_state.tags[handle] = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::PrintTokens(std::ostream& out)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = m_pScanner->GetNextToken();
|
Token *pToken = m_pScanner->GetNextToken();
|
||||||
if(!pToken)
|
if(!pToken)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
std::cout << *pToken << std::endl;
|
out << *pToken << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
parser.h
15
parser.h
|
@ -1,7 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
|
#include "parserstate.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -14,10 +18,19 @@ namespace YAML
|
||||||
Parser(std::istream& in);
|
Parser(std::istream& in);
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
void GetNextDocument(Document& document);
|
void GetNextDocument(Document& document);
|
||||||
void PrintTokens();
|
void PrintTokens(std::ostream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ParseDirectives();
|
||||||
|
void HandleDirective(const std::string& name, const std::vector <std::string>& params);
|
||||||
|
void HandleYamlDirective(const std::vector <std::string>& params);
|
||||||
|
void HandleTagDirective(const std::vector <std::string>& params);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scanner *m_pScanner;
|
Scanner *m_pScanner;
|
||||||
|
ParserState m_state;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
25
parserstate.cpp
Normal file
25
parserstate.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "parserstate.h"
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
void ParserState::Reset()
|
||||||
|
{
|
||||||
|
// version
|
||||||
|
version.major = 1;
|
||||||
|
version.minor = 1;
|
||||||
|
|
||||||
|
// and tags
|
||||||
|
tags.clear();
|
||||||
|
tags["!"] = "!";
|
||||||
|
tags["!!"] = "tag:yaml.org,2002:";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ParserState::TranslateTag(const std::string& handle) const
|
||||||
|
{
|
||||||
|
std::map <std::string, std::string>::const_iterator it = tags.find(handle);
|
||||||
|
if(it == tags.end())
|
||||||
|
return handle;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
20
parserstate.h
Normal file
20
parserstate.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
struct Version {
|
||||||
|
int major, minor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParserState
|
||||||
|
{
|
||||||
|
Version version;
|
||||||
|
std::map <std::string, std::string> tags;
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
std::string TranslateTag(const std::string& handle) const;
|
||||||
|
};
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ namespace YAML
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scalar::Parse(Scanner *pScanner)
|
void Scalar::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Token *pToken = pScanner->GetNextToken();
|
Token *pToken = pScanner->GetNextToken();
|
||||||
m_data = pToken->value;
|
m_data = pToken->value;
|
||||||
|
|
2
scalar.h
2
scalar.h
|
@ -11,7 +11,7 @@ namespace YAML
|
||||||
Scalar();
|
Scalar();
|
||||||
virtual ~Scalar();
|
virtual ~Scalar();
|
||||||
|
|
||||||
virtual void Parse(Scanner *pScanner);
|
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||||
virtual void Write(std::ostream& out, int indent);
|
virtual void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace YAML
|
||||||
void Scanner::ScanAnchorOrAlias()
|
void Scanner::ScanAnchorOrAlias()
|
||||||
{
|
{
|
||||||
bool alias;
|
bool alias;
|
||||||
std::string tag;
|
std::string name;
|
||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
if(m_simpleKeyAllowed)
|
if(m_simpleKeyAllowed)
|
||||||
|
@ -202,10 +202,10 @@ namespace YAML
|
||||||
|
|
||||||
// now eat the content
|
// now eat the content
|
||||||
while(Exp::AlphaNumeric.Matches(INPUT))
|
while(Exp::AlphaNumeric.Matches(INPUT))
|
||||||
tag += INPUT.get();
|
name += INPUT.get();
|
||||||
|
|
||||||
// we need to have read SOMETHING!
|
// we need to have read SOMETHING!
|
||||||
if(tag.empty())
|
if(name.empty())
|
||||||
throw AnchorNotFound();
|
throw AnchorNotFound();
|
||||||
|
|
||||||
// and needs to end correctly
|
// and needs to end correctly
|
||||||
|
@ -214,7 +214,7 @@ namespace YAML
|
||||||
|
|
||||||
// and we're done
|
// and we're done
|
||||||
Token *pToken = new Token(alias ? TT_ALIAS : TT_ANCHOR);
|
Token *pToken = new Token(alias ? TT_ALIAS : TT_ANCHOR);
|
||||||
pToken->value = tag;
|
pToken->value = name;
|
||||||
m_tokens.push(pToken);
|
m_tokens.push(pToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ namespace YAML
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
INPUT.eat(1);
|
handle += INPUT.get();
|
||||||
|
|
||||||
// read the handle
|
// read the handle
|
||||||
while(INPUT.peek() != EOF && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
|
while(INPUT.peek() != EOF && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
|
||||||
|
@ -238,11 +238,15 @@ namespace YAML
|
||||||
// is there a suffix?
|
// is there a suffix?
|
||||||
if(INPUT.peek() == Keys::Tag) {
|
if(INPUT.peek() == Keys::Tag) {
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
INPUT.eat(1);
|
handle += INPUT.get();
|
||||||
|
|
||||||
// then read it
|
// then read it
|
||||||
while(INPUT.peek() != EOF && !Exp::BlankOrBreak.Matches(INPUT))
|
while(INPUT.peek() != EOF && !Exp::BlankOrBreak.Matches(INPUT))
|
||||||
suffix += INPUT.get();
|
suffix += INPUT.get();
|
||||||
|
} else {
|
||||||
|
// this is a bit weird: we keep just the '!' as the handle and move the rest to the suffix
|
||||||
|
suffix = handle.substr(1);
|
||||||
|
handle = "!";
|
||||||
}
|
}
|
||||||
|
|
||||||
Token *pToken = new Token(TT_TAG);
|
Token *pToken = new Token(TT_TAG);
|
||||||
|
|
20
sequence.cpp
20
sequence.cpp
|
@ -22,7 +22,7 @@ namespace YAML
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::Parse(Scanner *pScanner)
|
void Sequence::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ namespace YAML
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
|
||||||
switch(pToken->type) {
|
switch(pToken->type) {
|
||||||
case TT_BLOCK_SEQ_START: ParseBlock(pScanner); break;
|
case TT_BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
|
||||||
case TT_BLOCK_ENTRY: ParseImplicit(pScanner); break;
|
case TT_BLOCK_ENTRY: ParseImplicit(pScanner, state); break;
|
||||||
case TT_FLOW_SEQ_START: ParseFlow(pScanner); break;
|
case TT_FLOW_SEQ_START: ParseFlow(pScanner, state); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::ParseBlock(Scanner *pScanner)
|
void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->EatNextToken();
|
pScanner->EatNextToken();
|
||||||
|
@ -55,11 +55,11 @@ namespace YAML
|
||||||
|
|
||||||
Node *pNode = new Node;
|
Node *pNode = new Node;
|
||||||
m_data.push_back(pNode);
|
m_data.push_back(pNode);
|
||||||
pNode->Parse(pScanner);
|
pNode->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::ParseImplicit(Scanner *pScanner)
|
void Sequence::ParseImplicit(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
@ -75,11 +75,11 @@ namespace YAML
|
||||||
|
|
||||||
Node *pNode = new Node;
|
Node *pNode = new Node;
|
||||||
m_data.push_back(pNode);
|
m_data.push_back(pNode);
|
||||||
pNode->Parse(pScanner);
|
pNode->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::ParseFlow(Scanner *pScanner)
|
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->EatNextToken();
|
pScanner->EatNextToken();
|
||||||
|
@ -98,7 +98,7 @@ namespace YAML
|
||||||
// then read the node
|
// then read the node
|
||||||
Node *pNode = new Node;
|
Node *pNode = new Node;
|
||||||
m_data.push_back(pNode);
|
m_data.push_back(pNode);
|
||||||
pNode->Parse(pScanner);
|
pNode->Parse(pScanner, state);
|
||||||
|
|
||||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
||||||
pToken = pScanner->PeekNextToken();
|
pToken = pScanner->PeekNextToken();
|
||||||
|
|
|
@ -14,13 +14,13 @@ namespace YAML
|
||||||
virtual ~Sequence();
|
virtual ~Sequence();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
virtual void Parse(Scanner *pScanner);
|
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||||
virtual void Write(std::ostream& out, int indent);
|
virtual void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseBlock(Scanner *pScanner);
|
void ParseBlock(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseImplicit(Scanner *pScanner);
|
void ParseImplicit(Scanner *pScanner, const ParserState& state);
|
||||||
void ParseFlow(Scanner *pScanner);
|
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector <Node *> m_data;
|
std::vector <Node *> m_data;
|
||||||
|
|
126
test.yaml
126
test.yaml
|
@ -1,29 +1,97 @@
|
||||||
--- !<tag:clarkevans.com,2002:invoice>
|
---
|
||||||
invoice: 34843
|
model:
|
||||||
date : 2001-01-23
|
file: data/models/compound.model
|
||||||
bill-to: &id001
|
textures: data/materials/compound
|
||||||
given : Chris
|
rooms:
|
||||||
family : Dumars
|
- name: "Room #1"
|
||||||
address:
|
pos: [0, 0, 0]
|
||||||
lines: |
|
size: [1000, 1000, 500]
|
||||||
458 Walkman Dr.
|
height: 500
|
||||||
Suite #292
|
stairtype: none
|
||||||
city : Royal Oak
|
display: []
|
||||||
state : MI
|
pathfinding:
|
||||||
postal : 48046
|
tilesize: 50
|
||||||
ship-to: *id001
|
size: [24, 24]
|
||||||
product:
|
map: |
|
||||||
- sku : BL394D
|
-----------------------
|
||||||
quantity : 4
|
-+++++++++++++++++++++-
|
||||||
description : Basketball
|
-+-------------------+-
|
||||||
price : 450.00
|
-+-------------------+-
|
||||||
- sku : BL4438H
|
-+-------------------+-
|
||||||
quantity : 1
|
-+-------------------+-
|
||||||
description : Super Hoop
|
-+-------------------+-
|
||||||
price : 2392.00
|
-+-------------------+-
|
||||||
tax : 251.42
|
-+-------------------+-
|
||||||
total: 4443.52
|
-+-------------------+-
|
||||||
comments:
|
-+---------------------
|
||||||
Late afternoon is best.
|
-+---------------------
|
||||||
Backup contact is Nancy
|
-+---------------------
|
||||||
Billsmer @ 338-4338.
|
-+---------------------
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+++++++++++++++++++++-
|
||||||
|
-----------------------
|
||||||
|
- name: Doorway
|
||||||
|
pos: [1000, 400, 0]
|
||||||
|
size: [50, 200, 500]
|
||||||
|
height: 500
|
||||||
|
stairtype: none
|
||||||
|
display: []
|
||||||
|
pathfinding:
|
||||||
|
tilesize: 50
|
||||||
|
size: [5, 9]
|
||||||
|
map: |
|
||||||
|
-----
|
||||||
|
-+++-
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
-+++-
|
||||||
|
-----
|
||||||
|
- name: "Room #2"
|
||||||
|
pos: [1050, 0, 0]
|
||||||
|
size: [1000, 1000, 500]
|
||||||
|
height: 500
|
||||||
|
stairtype: none
|
||||||
|
display: []
|
||||||
|
pathfinding:
|
||||||
|
tilesize: 50
|
||||||
|
size: [24, 24]
|
||||||
|
map: |
|
||||||
|
-----------------------
|
||||||
|
-+++++++++++++++++++++-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
---------------------+-
|
||||||
|
---------------------+-
|
||||||
|
---------------------+-
|
||||||
|
---------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+-------------------+-
|
||||||
|
-+++++++++++++++++++++-
|
||||||
|
-----------------------
|
||||||
|
exits:
|
||||||
|
- room1: "Room #1"
|
||||||
|
room2: "Room #2"
|
||||||
|
dir: e
|
||||||
|
pos: [400, 600]
|
||||||
|
|
|
@ -204,6 +204,10 @@
|
||||||
RelativePath=".\parser.cpp"
|
RelativePath=".\parser.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\parserstate.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Representation"
|
Name="Representation"
|
||||||
|
@ -278,6 +282,10 @@
|
||||||
RelativePath=".\parser.h"
|
RelativePath=".\parser.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\parserstate.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Representation"
|
Name="Representation"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue