mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
Added parsing of anchors, aliases, and tags (still no semantics yet).
Fixed a silly bug in the simple key pushing (queues are FIFO!).
This commit is contained in:
parent
121c2e577f
commit
8180a85a3b
10 changed files with 167 additions and 34 deletions
20
map.cpp
20
map.cpp
|
@ -10,28 +10,37 @@ namespace YAML
|
||||||
}
|
}
|
||||||
|
|
||||||
Map::~Map()
|
Map::~Map()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::Clear()
|
||||||
{
|
{
|
||||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
|
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
|
||||||
delete it->first;
|
delete it->first;
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::Parse(Scanner *pScanner)
|
void Map::Parse(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
// grab start token
|
Clear();
|
||||||
Token *pToken = pScanner->GetNextToken();
|
|
||||||
|
// split based on start token
|
||||||
|
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); break;
|
||||||
case TT_FLOW_MAP_START: ParseFlow(pScanner); break;
|
case TT_FLOW_MAP_START: ParseFlow(pScanner); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::ParseBlock(Scanner *pScanner)
|
void Map::ParseBlock(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
|
// eat start token
|
||||||
|
pScanner->EatNextToken();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(!pToken)
|
if(!pToken)
|
||||||
|
@ -61,6 +70,9 @@ namespace YAML
|
||||||
|
|
||||||
void Map::ParseFlow(Scanner *pScanner)
|
void Map::ParseFlow(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
|
// eat start token
|
||||||
|
pScanner->EatNextToken();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(!pToken)
|
if(!pToken)
|
||||||
|
|
1
map.h
1
map.h
|
@ -13,6 +13,7 @@ namespace YAML
|
||||||
Map();
|
Map();
|
||||||
virtual ~Map();
|
virtual ~Map();
|
||||||
|
|
||||||
|
void Clear();
|
||||||
virtual void Parse(Scanner *pScanner);
|
virtual void Parse(Scanner *pScanner);
|
||||||
virtual void Write(std::ostream& out, int indent);
|
virtual void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
|
|
75
node.cpp
75
node.cpp
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
Node::Node(): m_pContent(0)
|
Node::Node(): m_pContent(0), m_alias(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,19 @@ namespace YAML
|
||||||
{
|
{
|
||||||
delete m_pContent;
|
delete m_pContent;
|
||||||
m_pContent = 0;
|
m_pContent = 0;
|
||||||
|
m_alias = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::Parse(Scanner *pScanner)
|
void Node::Parse(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
ParseHeader(pScanner);
|
ParseHeader(pScanner);
|
||||||
|
|
||||||
|
// is this an alias? if so, it can have no content
|
||||||
|
if(m_alias)
|
||||||
|
return;
|
||||||
|
|
||||||
// now split based on what kind of node we should be
|
// now split based on what kind of node we should be
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(pToken->type == TT_DOC_END)
|
if(pToken->type == TT_DOC_END)
|
||||||
|
@ -57,29 +64,75 @@ namespace YAML
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(!pToken || pToken->type != TT_TAG || pToken->type != TT_ANCHOR || pToken->type != TT_ALIAS)
|
if(!pToken || (pToken->type != TT_TAG && pToken->type != TT_ANCHOR && pToken->type != TT_ALIAS))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pScanner->PopNextToken();
|
|
||||||
switch(pToken->type) {
|
switch(pToken->type) {
|
||||||
case TT_TAG:
|
case TT_TAG: ParseTag(pScanner); break;
|
||||||
break;
|
case TT_ANCHOR: ParseAnchor(pScanner); break;
|
||||||
case TT_ANCHOR:
|
case TT_ALIAS: ParseAlias(pScanner); break;
|
||||||
break;
|
|
||||||
case TT_ALIAS:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
delete pToken;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::ParseTag(Scanner *pScanner)
|
||||||
|
{
|
||||||
|
if(m_tag != "")
|
||||||
|
return; // TODO: throw
|
||||||
|
|
||||||
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
m_tag = pToken->value;
|
||||||
|
for(unsigned i=0;i<pToken->params.size();i++)
|
||||||
|
m_tag += pToken->params[i];
|
||||||
|
pScanner->PopNextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::ParseAnchor(Scanner *pScanner)
|
||||||
|
{
|
||||||
|
if(m_anchor != "")
|
||||||
|
return; // TODO: throw
|
||||||
|
|
||||||
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
m_anchor = pToken->value;
|
||||||
|
m_alias = false;
|
||||||
|
pScanner->PopNextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::ParseAlias(Scanner *pScanner)
|
||||||
|
{
|
||||||
|
if(m_anchor != "")
|
||||||
|
return; // TODO: throw
|
||||||
|
if(m_tag != "")
|
||||||
|
return; // TODO: throw (aliases can't have any content, *including* tags)
|
||||||
|
|
||||||
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
m_anchor = pToken->value;
|
||||||
|
m_alias = true;
|
||||||
|
pScanner->PopNextToken();
|
||||||
|
}
|
||||||
|
|
||||||
void Node::Write(std::ostream& out, int indent)
|
void Node::Write(std::ostream& out, int indent)
|
||||||
{
|
{
|
||||||
|
if(m_tag != "") {
|
||||||
|
for(int i=0;i<indent;i++)
|
||||||
|
out << " ";
|
||||||
|
out << "{tag: " << m_tag << "}\n";
|
||||||
|
}
|
||||||
|
if(m_anchor != "") {
|
||||||
|
for(int i=0;i<indent;i++)
|
||||||
|
out << " ";
|
||||||
|
if(m_alias)
|
||||||
|
out << "{alias: " << m_anchor << "}\n";
|
||||||
|
else
|
||||||
|
out << "{anchor: " << m_anchor << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(!m_pContent) {
|
if(!m_pContent) {
|
||||||
for(int i=0;i<indent;i++)
|
for(int i=0;i<indent;i++)
|
||||||
out << " ";
|
out << " ";
|
||||||
out << "{no content}\n";
|
out << "{no content}\n";
|
||||||
} else
|
} else {
|
||||||
m_pContent->Write(out, indent);
|
m_pContent->Write(out, indent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
6
node.h
6
node.h
|
@ -24,9 +24,13 @@ namespace YAML
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseHeader(Scanner *pScanner);
|
void ParseHeader(Scanner *pScanner);
|
||||||
|
void ParseTag(Scanner *pScanner);
|
||||||
|
void ParseAnchor(Scanner *pScanner);
|
||||||
|
void ParseAlias(Scanner *pScanner);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_tag;
|
bool m_alias;
|
||||||
|
std::string m_anchor, m_tag;
|
||||||
Content *m_pContent;
|
Content *m_pContent;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
13
parser.cpp
13
parser.cpp
|
@ -1,5 +1,7 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
#include "token.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -17,4 +19,15 @@ namespace YAML
|
||||||
{
|
{
|
||||||
document.Parse(m_pScanner);
|
document.Parse(m_pScanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::PrintTokens()
|
||||||
|
{
|
||||||
|
while(1) {
|
||||||
|
Token *pToken = m_pScanner->GetNextToken();
|
||||||
|
if(!pToken)
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::cout << *pToken << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1
parser.h
1
parser.h
|
@ -15,6 +15,7 @@ namespace YAML
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
void GetNextDocument(Document& document);
|
void GetNextDocument(Document& document);
|
||||||
|
void PrintTokens();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scanner *m_pScanner;
|
Scanner *m_pScanner;
|
||||||
|
|
|
@ -254,12 +254,14 @@ namespace YAML
|
||||||
|
|
||||||
// now push
|
// now push
|
||||||
m_indents.push(column);
|
m_indents.push(column);
|
||||||
|
Token *pToken = 0;
|
||||||
if(sequence)
|
if(sequence)
|
||||||
m_tokens.push(new Token(TT_BLOCK_SEQ_START));
|
pToken = new Token(TT_BLOCK_SEQ_START);
|
||||||
else
|
else
|
||||||
m_tokens.push(new Token(TT_BLOCK_MAP_START));
|
pToken = new Token(TT_BLOCK_MAP_START);
|
||||||
|
|
||||||
return m_tokens.front();
|
m_tokens.push(pToken);
|
||||||
|
return pToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopIndentTo
|
// PopIndentTo
|
||||||
|
|
37
sequence.cpp
37
sequence.cpp
|
@ -11,27 +11,36 @@ namespace YAML
|
||||||
}
|
}
|
||||||
|
|
||||||
Sequence::~Sequence()
|
Sequence::~Sequence()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequence::Clear()
|
||||||
{
|
{
|
||||||
for(unsigned i=0;i<m_data.size();i++)
|
for(unsigned i=0;i<m_data.size();i++)
|
||||||
delete m_data[i];
|
delete m_data[i];
|
||||||
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::Parse(Scanner *pScanner)
|
void Sequence::Parse(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
// grab start token
|
Clear();
|
||||||
Token *pToken = pScanner->GetNextToken();
|
|
||||||
|
// split based on start token
|
||||||
|
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); break;
|
||||||
case TT_BLOCK_ENTRY: ParseImplicit(pScanner); break;
|
case TT_BLOCK_ENTRY: ParseImplicit(pScanner); break;
|
||||||
case TT_FLOW_SEQ_START: ParseFlow(pScanner); break;
|
case TT_FLOW_SEQ_START: ParseFlow(pScanner); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::ParseBlock(Scanner *pScanner)
|
void Sequence::ParseBlock(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
|
// eat start token
|
||||||
|
pScanner->EatNextToken();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(!pToken)
|
if(!pToken)
|
||||||
|
@ -52,11 +61,29 @@ namespace YAML
|
||||||
|
|
||||||
void Sequence::ParseImplicit(Scanner *pScanner)
|
void Sequence::ParseImplicit(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
// TODO
|
while(1) {
|
||||||
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
|
// we're actually *allowed* to have no tokens at some point
|
||||||
|
if(!pToken)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// and we end at anything other than a block entry
|
||||||
|
if(pToken->type != TT_BLOCK_ENTRY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pScanner->PopNextToken();
|
||||||
|
|
||||||
|
Node *pNode = new Node;
|
||||||
|
m_data.push_back(pNode);
|
||||||
|
pNode->Parse(pScanner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sequence::ParseFlow(Scanner *pScanner)
|
void Sequence::ParseFlow(Scanner *pScanner)
|
||||||
{
|
{
|
||||||
|
// eat start token
|
||||||
|
pScanner->EatNextToken();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
Token *pToken = pScanner->PeekNextToken();
|
Token *pToken = pScanner->PeekNextToken();
|
||||||
if(!pToken)
|
if(!pToken)
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace YAML
|
||||||
Sequence();
|
Sequence();
|
||||||
virtual ~Sequence();
|
virtual ~Sequence();
|
||||||
|
|
||||||
|
void Clear();
|
||||||
virtual void Parse(Scanner *pScanner);
|
virtual void Parse(Scanner *pScanner);
|
||||||
virtual void Write(std::ostream& out, int indent);
|
virtual void Write(std::ostream& out, int indent);
|
||||||
|
|
||||||
|
|
39
test.yaml
39
test.yaml
|
@ -1,10 +1,29 @@
|
||||||
---
|
--- !<tag:clarkevans.com,2002:invoice>
|
||||||
here's a sequence:
|
invoice: 34843
|
||||||
- item 1
|
date : 2001-01-23
|
||||||
- item 2
|
bill-to: &id001
|
||||||
now an inline sequence: [1, 2, 3]
|
given : Chris
|
||||||
and here's a map:
|
family : Dumars
|
||||||
name: Jesse
|
address:
|
||||||
age: 23
|
lines: |
|
||||||
and here's an inline map: {state: Illinois, city: Urbana-Champaign}
|
458 Walkman Dr.
|
||||||
...
|
Suite #292
|
||||||
|
city : Royal Oak
|
||||||
|
state : MI
|
||||||
|
postal : 48046
|
||||||
|
ship-to: *id001
|
||||||
|
product:
|
||||||
|
- 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.
|
Loading…
Add table
Add a link
Reference in a new issue