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:
Jesse Beder 2008-07-01 01:17:10 +00:00
parent 121c2e577f
commit 8180a85a3b
10 changed files with 167 additions and 34 deletions

20
map.cpp
View file

@ -10,28 +10,37 @@ namespace YAML
}
Map::~Map()
{
Clear();
}
void Map::Clear()
{
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
delete it->first;
delete it->second;
}
m_data.clear();
}
void Map::Parse(Scanner *pScanner)
{
// grab start token
Token *pToken = pScanner->GetNextToken();
Clear();
// split based on start token
Token *pToken = pScanner->PeekNextToken();
switch(pToken->type) {
case TT_BLOCK_MAP_START: ParseBlock(pScanner); break;
case TT_FLOW_MAP_START: ParseFlow(pScanner); break;
}
delete pToken;
}
void Map::ParseBlock(Scanner *pScanner)
{
// eat start token
pScanner->EatNextToken();
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)
@ -61,6 +70,9 @@ namespace YAML
void Map::ParseFlow(Scanner *pScanner)
{
// eat start token
pScanner->EatNextToken();
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)

1
map.h
View file

@ -13,6 +13,7 @@ namespace YAML
Map();
virtual ~Map();
void Clear();
virtual void Parse(Scanner *pScanner);
virtual void Write(std::ostream& out, int indent);

View file

@ -9,7 +9,7 @@
namespace YAML
{
Node::Node(): m_pContent(0)
Node::Node(): m_pContent(0), m_alias(false)
{
}
@ -22,12 +22,19 @@ namespace YAML
{
delete m_pContent;
m_pContent = 0;
m_alias = false;
}
void Node::Parse(Scanner *pScanner)
{
Clear();
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
Token *pToken = pScanner->PeekNextToken();
if(pToken->type == TT_DOC_END)
@ -57,29 +64,75 @@ namespace YAML
{
while(1) {
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;
pScanner->PopNextToken();
switch(pToken->type) {
case TT_TAG:
break;
case TT_ANCHOR:
break;
case TT_ALIAS:
break;
case TT_TAG: ParseTag(pScanner); break;
case TT_ANCHOR: ParseAnchor(pScanner); break;
case TT_ALIAS: ParseAlias(pScanner); 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)
{
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) {
for(int i=0;i<indent;i++)
out << " ";
out << "{no content}\n";
} else
} else {
m_pContent->Write(out, indent);
}
}
}

6
node.h
View file

@ -24,9 +24,13 @@ namespace YAML
private:
void ParseHeader(Scanner *pScanner);
void ParseTag(Scanner *pScanner);
void ParseAnchor(Scanner *pScanner);
void ParseAlias(Scanner *pScanner);
private:
std::string m_tag;
bool m_alias;
std::string m_anchor, m_tag;
Content *m_pContent;
};
}

View file

@ -1,5 +1,7 @@
#include "parser.h"
#include "scanner.h"
#include "token.h"
#include <iostream>
namespace YAML
{
@ -17,4 +19,15 @@ namespace YAML
{
document.Parse(m_pScanner);
}
void Parser::PrintTokens()
{
while(1) {
Token *pToken = m_pScanner->GetNextToken();
if(!pToken)
break;
std::cout << *pToken << std::endl;
}
}
}

View file

@ -15,6 +15,7 @@ namespace YAML
~Parser();
void GetNextDocument(Document& document);
void PrintTokens();
private:
Scanner *m_pScanner;

View file

@ -254,12 +254,14 @@ namespace YAML
// now push
m_indents.push(column);
Token *pToken = 0;
if(sequence)
m_tokens.push(new Token(TT_BLOCK_SEQ_START));
pToken = new Token(TT_BLOCK_SEQ_START);
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

View file

@ -11,27 +11,36 @@ namespace YAML
}
Sequence::~Sequence()
{
Clear();
}
void Sequence::Clear()
{
for(unsigned i=0;i<m_data.size();i++)
delete m_data[i];
m_data.clear();
}
void Sequence::Parse(Scanner *pScanner)
{
// grab start token
Token *pToken = pScanner->GetNextToken();
Clear();
// split based on start token
Token *pToken = pScanner->PeekNextToken();
switch(pToken->type) {
case TT_BLOCK_SEQ_START: ParseBlock(pScanner); break;
case TT_BLOCK_ENTRY: ParseImplicit(pScanner); break;
case TT_FLOW_SEQ_START: ParseFlow(pScanner); break;
}
delete pToken;
}
void Sequence::ParseBlock(Scanner *pScanner)
{
// eat start token
pScanner->EatNextToken();
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)
@ -52,11 +61,29 @@ namespace YAML
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)
{
// eat start token
pScanner->EatNextToken();
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)

View file

@ -13,6 +13,7 @@ namespace YAML
Sequence();
virtual ~Sequence();
void Clear();
virtual void Parse(Scanner *pScanner);
virtual void Write(std::ostream& out, int indent);

View file

@ -1,10 +1,29 @@
---
here's a sequence:
- item 1
- item 2
now an inline sequence: [1, 2, 3]
and here's a map:
name: Jesse
age: 23
and here's an inline map: {state: Illinois, city: Urbana-Champaign}
...
--- !<tag:clarkevans.com,2002:invoice>
invoice: 34843
date : 2001-01-23
bill-to: &id001
given : Chris
family : Dumars
address:
lines: |
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.