Commit 557f81e6 authored by beder's avatar beder
Browse files

Replaced the queue of Token pointers with values.

We were getting memory leaks (as told by the CRT detectors, which I also added), and there's really no reason (as long as we're careful) to use pointers there.
parent f4e52249
#pragma once
// for memory leaks
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif // _DEBUG
\ No newline at end of file
#pragma once #pragma once
#include <exception> #include <exception>
#include <string>
namespace YAML namespace YAML
{ {
...@@ -9,6 +10,7 @@ namespace YAML ...@@ -9,6 +10,7 @@ namespace YAML
public: public:
ParserException(int line_, int column_, const std::string& msg_) ParserException(int line_, int column_, const std::string& msg_)
: line(line_), column(column_), msg(msg_) {} : line(line_), column(column_), msg(msg_) {}
int line, column; int line, column;
std::string msg; std::string msg;
}; };
......
#pragma once
#include "crt.h"
#include "parser.h"
#include "node.h"
#include "exceptions.h"
\ No newline at end of file
#include "crt.h"
#include "content.h" #include "content.h"
namespace YAML namespace YAML
......
#include "crt.h"
#include "exp.h" #include "exp.h"
#include "exceptions.h" #include "exceptions.h"
#include <sstream> #include <sstream>
......
#include "crt.h"
#include "node.h" #include "node.h"
#include "exceptions.h" #include "exceptions.h"
......
#include "crt.h"
#include "map.h" #include "map.h"
#include "node.h" #include "node.h"
#include "scanner.h" #include "scanner.h"
...@@ -41,9 +42,9 @@ namespace YAML ...@@ -41,9 +42,9 @@ namespace YAML
Clear(); Clear();
// split based on start token // split based on start token
Token *pToken = pScanner->PeekNextToken(); Token& token = pScanner->PeekToken();
switch(pToken->type) { switch(token.type) {
case TT_BLOCK_MAP_START: ParseBlock(pScanner, state); break; case TT_BLOCK_MAP_START: ParseBlock(pScanner, state); break;
case TT_FLOW_MAP_START: ParseFlow(pScanner, state); break; case TT_FLOW_MAP_START: ParseFlow(pScanner, state); break;
} }
...@@ -52,18 +53,18 @@ namespace YAML ...@@ -52,18 +53,18 @@ namespace YAML
void Map::ParseBlock(Scanner *pScanner, const ParserState& state) void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->EatNextToken(); pScanner->PopToken();
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); if(pScanner->IsEmpty())
if(!pToken)
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP); throw ParserException(-1, -1, ErrorMsg::END_OF_MAP);
if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END) Token token = pScanner->PeekToken();
throw ParserException(pToken->line, pToken->column, ErrorMsg::END_OF_MAP); if(token.type != TT_KEY && token.type != TT_BLOCK_END)
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP);
pScanner->PopNextToken(); pScanner->PopToken();
if(pToken->type == TT_BLOCK_END) if(token.type == TT_BLOCK_END)
break; break;
Node *pKey = new Node; Node *pKey = new Node;
...@@ -74,8 +75,8 @@ namespace YAML ...@@ -74,8 +75,8 @@ namespace YAML
pKey->Parse(pScanner, state); pKey->Parse(pScanner, state);
// now grab value (optional) // now grab value (optional)
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) { if(!pScanner->IsEmpty() && pScanner->PeekToken().type == TT_VALUE) {
pScanner->PopNextToken(); pScanner->PopToken();
pValue->Parse(pScanner, state); pValue->Parse(pScanner, state);
} }
...@@ -91,24 +92,24 @@ namespace YAML ...@@ -91,24 +92,24 @@ namespace YAML
void Map::ParseFlow(Scanner *pScanner, const ParserState& state) void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->EatNextToken(); pScanner->PopToken();
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); if(pScanner->IsEmpty())
if(!pToken)
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW);
Token& token = pScanner->PeekToken();
// first check for end // first check for end
if(pToken->type == TT_FLOW_MAP_END) { if(token.type == TT_FLOW_MAP_END) {
pScanner->EatNextToken(); pScanner->PopToken();
break; break;
} }
// now it better be a key // now it better be a key
if(pToken->type != TT_KEY) if(token.type != TT_KEY)
throw ParserException(pToken->line, pToken->column, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW);
pScanner->PopNextToken(); pScanner->PopToken();
Node *pKey = new Node; Node *pKey = new Node;
Node *pValue = new Node; Node *pValue = new Node;
...@@ -118,17 +119,17 @@ namespace YAML ...@@ -118,17 +119,17 @@ namespace YAML
pKey->Parse(pScanner, state); pKey->Parse(pScanner, state);
// now grab value (optional) // now grab value (optional)
if(pScanner->PeekNextToken() && pScanner->PeekNextToken()->type == TT_VALUE) { if(!pScanner->IsEmpty() && pScanner->PeekToken().type == TT_VALUE) {
pScanner->PopNextToken(); pScanner->PopToken();
pValue->Parse(pScanner, state); 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)
pToken = pScanner->PeekNextToken(); Token& nextToken = pScanner->PeekToken();
if(pToken->type == TT_FLOW_ENTRY) if(nextToken.type == TT_FLOW_ENTRY)
pScanner->EatNextToken(); pScanner->PopToken();
else if(pToken->type != TT_FLOW_MAP_END) else if(nextToken.type != TT_FLOW_MAP_END)
throw ParserException(pToken->line, pToken->column, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(nextToken.line, nextToken.column, ErrorMsg::END_OF_MAP_FLOW);
m_data[pKey] = pValue; m_data[pKey] = pValue;
} catch(Exception& e) { } catch(Exception& e) {
......
#include "crt.h"
#include "node.h" #include "node.h"
#include "token.h" #include "token.h"
#include "scanner.h" #include "scanner.h"
...@@ -42,11 +43,7 @@ namespace YAML ...@@ -42,11 +43,7 @@ namespace YAML
return; 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(); switch(pScanner->PeekToken().type) {
if(pToken->type == TT_DOC_END)
return;
switch(pToken->type) {
case TT_SCALAR: case TT_SCALAR:
m_pContent = new Scalar; m_pContent = new Scalar;
m_pContent->Parse(pScanner, state); m_pContent->Parse(pScanner, state);
...@@ -61,6 +58,7 @@ namespace YAML ...@@ -61,6 +58,7 @@ namespace YAML
case TT_BLOCK_MAP_START: case TT_BLOCK_MAP_START:
m_pContent = new Map; m_pContent = new Map;
m_pContent->Parse(pScanner, state); m_pContent->Parse(pScanner, state);
break;
} }
} }
...@@ -69,53 +67,53 @@ namespace YAML ...@@ -69,53 +67,53 @@ namespace YAML
void Node::ParseHeader(Scanner *pScanner, const ParserState& state) void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
{ {
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); if(pScanner->IsEmpty())
if(!pToken || (pToken->type != TT_TAG && pToken->type != TT_ANCHOR && pToken->type != TT_ALIAS)) return;
break;
switch(pToken->type) { switch(pScanner->PeekToken().type) {
case TT_TAG: ParseTag(pScanner, state); break; case TT_TAG: ParseTag(pScanner, state); break;
case TT_ANCHOR: ParseAnchor(pScanner, state); break; case TT_ANCHOR: ParseAnchor(pScanner, state); break;
case TT_ALIAS: ParseAlias(pScanner, state); break; case TT_ALIAS: ParseAlias(pScanner, state); break;
default: return;
} }
} }
} }
void Node::ParseTag(Scanner *pScanner, const ParserState& state) void Node::ParseTag(Scanner *pScanner, const ParserState& state)
{ {
Token *pToken = pScanner->PeekNextToken(); Token& token = pScanner->PeekToken();
if(m_tag != "") if(m_tag != "")
throw ParserException(pToken->line, pToken->column, ErrorMsg::MULTIPLE_TAGS); throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_TAGS);
m_tag = state.TranslateTag(pToken->value); m_tag = state.TranslateTag(token.value);
for(unsigned i=0;i<pToken->params.size();i++) for(unsigned i=0;i<token.params.size();i++)
m_tag += pToken->params[i]; m_tag += token.params[i];
pScanner->PopNextToken(); pScanner->PopToken();
} }
void Node::ParseAnchor(Scanner *pScanner, const ParserState& state) void Node::ParseAnchor(Scanner *pScanner, const ParserState& state)
{ {
Token *pToken = pScanner->PeekNextToken(); Token& token = pScanner->PeekToken();
if(m_anchor != "") if(m_anchor != "")
throw ParserException(pToken->line, pToken->column, ErrorMsg::MULTIPLE_ANCHORS); throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ANCHORS);
m_anchor = pToken->value; m_anchor = token.value;
m_alias = false; m_alias = false;
pScanner->PopNextToken(); pScanner->PopToken();
} }
void Node::ParseAlias(Scanner *pScanner, const ParserState& state) void Node::ParseAlias(Scanner *pScanner, const ParserState& state)
{ {
Token *pToken = pScanner->PeekNextToken(); Token& token = pScanner->PeekToken();
if(m_anchor != "") if(m_anchor != "")
throw ParserException(pToken->line, pToken->column, ErrorMsg::MULTIPLE_ALIASES); throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ALIASES);
if(m_tag != "") if(m_tag != "")
throw ParserException(pToken->line, pToken->column, ErrorMsg::ALIAS_CONTENT); throw ParserException(token.line, token.column, ErrorMsg::ALIAS_CONTENT);
m_anchor = pToken->value; m_anchor = token.value;
m_alias = true; m_alias = true;
pScanner->PopNextToken(); pScanner->PopToken();
} }
void Node::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const void Node::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const
......
#include "crt.h"
#include "parser.h" #include "parser.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
...@@ -18,7 +19,7 @@ namespace YAML ...@@ -18,7 +19,7 @@ namespace YAML
Parser::operator bool() const Parser::operator bool() const
{ {
return m_pScanner->PeekNextToken() != 0; return !m_pScanner->IsEmpty();
} }
void Parser::Load(std::istream& in) void Parser::Load(std::istream& in)
...@@ -40,19 +41,19 @@ namespace YAML ...@@ -40,19 +41,19 @@ namespace YAML
ParseDirectives(); ParseDirectives();
// we better have some tokens in the queue // we better have some tokens in the queue
if(!m_pScanner->PeekNextToken()) if(m_pScanner->IsEmpty())
return; return;
// first eat doc start (optional) // first eat doc start (optional)
if(m_pScanner->PeekNextToken()->type == TT_DOC_START) if(m_pScanner->PeekToken().type == TT_DOC_START)
m_pScanner->EatNextToken(); m_pScanner->PopToken();
// now parse our root node // now parse our root node
document.Parse(m_pScanner, m_state); document.Parse(m_pScanner, m_state);
// and finally eat any doc ends we see // and finally eat any doc ends we see
while(m_pScanner->PeekNextToken() && m_pScanner->PeekNextToken()->type == TT_DOC_END) while(!m_pScanner->IsEmpty() && m_pScanner->PeekToken().type == TT_DOC_END)
m_pScanner->EatNextToken(); m_pScanner->PopToken();
} }
// ParseDirectives // ParseDirectives
...@@ -62,8 +63,11 @@ namespace YAML ...@@ -62,8 +63,11 @@ namespace YAML
bool readDirective = false; bool readDirective = false;
while(1) { while(1) {
Token *pToken = m_pScanner->PeekNextToken(); if(m_pScanner->IsEmpty())
if(!pToken || pToken->type != TT_DIRECTIVE) break;
Token& token = m_pScanner->PeekToken();
if(token.type != TT_DIRECTIVE)
break; break;
// we keep the directives from the last document if none are specified; // we keep the directives from the last document if none are specified;
...@@ -72,8 +76,8 @@ namespace YAML ...@@ -72,8 +76,8 @@ namespace YAML
m_state.Reset(); m_state.Reset();
readDirective = true; readDirective = true;
HandleDirective(pToken); HandleDirective(&token);
m_pScanner->PopNextToken(); m_pScanner->PopToken();
} }
} }
...@@ -119,11 +123,11 @@ namespace YAML ...@@ -119,11 +123,11 @@ namespace YAML
void Parser::PrintTokens(std::ostream& out) void Parser::PrintTokens(std::ostream& out)
{ {
while(1) { while(1) {
Token *pToken = m_pScanner->GetNextToken(); if(m_pScanner->IsEmpty())
if(!pToken)
break; break;
out << *pToken << std::endl; out << m_pScanner->PeekToken() << std::endl;
m_pScanner->PopToken();
} }
} }
} }
#include "crt.h"
#include "parserstate.h" #include "parserstate.h"
namespace YAML namespace YAML
......
#include "crt.h"
#include "regex.h" #include "regex.h"
namespace YAML namespace YAML
......
#include "crt.h"
#include "scalar.h" #include "scalar.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
...@@ -16,9 +17,9 @@ namespace YAML ...@@ -16,9 +17,9 @@ namespace YAML
void Scalar::Parse(Scanner *pScanner, const ParserState& state) void Scalar::Parse(Scanner *pScanner, const ParserState& state)
{ {
Token *pToken = pScanner->GetNextToken(); Token& token = pScanner->PeekToken();
m_data = pToken->value; m_data = token.value;
delete pToken; pScanner->PopToken();
} }
void Scalar::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) void Scalar::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
......
#include "crt.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h" #include "exceptions.h"
...@@ -12,61 +13,45 @@ namespace YAML ...@@ -12,61 +13,45 @@ namespace YAML
Scanner::~Scanner() Scanner::~Scanner()
{ {
while(!m_tokens.empty()) {
delete m_tokens.front();
m_tokens.pop();
}
} }
// GetNextToken // IsEmpty
// . Removes and returns the next token on the queue. // . Returns true if there are no more tokens to be read
Token *Scanner::GetNextToken() bool Scanner::IsEmpty()
{ {
Token *pToken = PeekNextToken(); PeekToken(); // to ensure that there are tokens in the queue, if possible
if(!m_tokens.empty()) return m_tokens.empty();
m_tokens.pop();
return pToken;
} }
// PopNextToken // PopToken
// . Simply removes the next token on the queue. // . Simply removes the next token on the queue.
void Scanner::PopNextToken() void Scanner::PopToken()
{
GetNextToken();
}
// EatNextToken
// . Removes and deletes the next token on the queue
void Scanner::EatNextToken()
{ {
delete GetNextToken(); PeekToken(); // to ensure that there are tokens in the queue
if(!m_tokens.empty())
m_tokens.pop();
} }
// PeekNextToken // PeekToken
// . Returns (but does not remove) the next token on the queue, and scans if only we need to. // . Returns (but does not remove) the next token on the queue, and scans if only we need to.
Token *Scanner::PeekNextToken() Token& Scanner::PeekToken()
{ {
while(1) { while(1) {
Token *pToken = 0; if(!m_tokens.empty()) {
Token& token = m_tokens.front();
// is there a token in the queue? // return this guy if it's valid
if(!m_tokens.empty()) if(token.status == TS_VALID)
pToken = m_tokens.front(); return token;
// (here's where we clean up the impossible tokens) // here's where we clean up the impossible tokens
if(pToken && pToken->status == TS_INVALID) { if(token.status == TS_INVALID) {
m_tokens.pop(); m_tokens.pop();
delete pToken;
continue; continue;
} }
// on unverified tokens, we just have to wait // note: what's left are the unverified tokens
if(pToken && pToken->status == TS_UNVERIFIED) }
pToken = 0;
// then that's what we want
if(pToken)
return pToken;
// no token? maybe we've actually finished // no token? maybe we've actually finished
if(m_endedStream) if(m_endedStream)
...@@ -76,7 +61,7 @@ namespace YAML ...@@ -76,7 +61,7 @@ namespace YAML
ScanNextToken(); ScanNextToken();
} }
return 0; // TODO: find something to return here, or assert (but can't do that! maybe split into two functions?)
} }
// ScanNextToken // ScanNextToken
...@@ -254,14 +239,12 @@ namespace YAML ...@@ -254,14 +239,12 @@ namespace YAML
// now push // now push
m_indents.push(column); m_indents.push(column);
Token *pToken = 0;
if(sequence) if(sequence)
pToken = new Token(TT_BLOCK_SEQ_START, INPUT.line, INPUT.column); m_tokens.push(Token(TT_BLOCK_SEQ_START, INPUT.line, INPUT.column));
else else
pToken = new Token(TT_BLOCK_MAP_START, INPUT.line, INPUT.column); m_tokens.push(Token(TT_BLOCK_MAP_START, INPUT.line, INPUT.column));
m_tokens.push(pToken); return &m_tokens.back();
return pToken;
} }
// PopIndentTo // PopIndentTo
...@@ -276,7 +259,7 @@ namespace YAML ...@@ -276,7 +259,7 @@ namespace YAML
// now pop away // now pop away
while(!m_indents.empty() && m_indents.top() > column) { while(!m_indents.empty() && m_indents.top() > column) {
m_indents.pop(); m_indents.pop();
m_tokens.push(new Token(TT_BLOCK_END, INPUT.line, INPUT.column)); m_tokens.push(Token(TT_BLOCK_END, INPUT.line, INPUT.column));
} }
} }
} }
...@@ -6,21 +6,19 @@ ...@@ -6,21 +6,19 @@
#include <stack> #include <stack>
#include <set> #include <set>
#include "stream.h" #include "stream.h"
#include "token.h"
namespace YAML namespace YAML
{ {
struct Token;
class Scanner class Scanner
{ {
public: public:
Scanner(std::istream& in); Scanner(std::istream& in);
~Scanner(); ~Scanner();
Token *GetNextToken(); bool IsEmpty();
void EatNextToken(); void PopToken();
void PopNextToken(); Token& PeekToken();
Token *PeekNextToken();
private: private:
// scanning // scanning
...@@ -72,7 +70,7 @@ namespace YAML ...@@ -72,7 +70,7 @@ namespace YAML
Stream INPUT; Stream INPUT;
// the output (tokens) // the output (tokens)
std::queue <Token *> m_tokens; std::queue <Token> m_tokens;
// state info // state info
bool m_startedStream, m_endedStream; bool m_startedStream, m_endedStream;
......
#include "crt.h"
#include "scanscalar.h" #include "scanscalar.h"
#include "scanner.h" #include "scanner.h"
#include "exp.h" #include "exp.h"
......
#include "crt.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h" #include "exceptions.h"
...@@ -49,10 +50,10 @@ namespace YAML ...@@ -49,10 +50,10 @@ namespace YAML
params.push_back(param); params.push_back(param);
} }
Token *pToken = new Token(TT_DIRECTIVE, line, column); Token token(TT_DIRECTIVE, line, column);
pToken->value = name; token.value = name;
pToken->params = params; token.params = params;
m_tokens.push(pToken); m_tokens.push(token);
} }
// DocStart // DocStart
...@@ -65,7 +66,7 @@ namespace YAML ...@@ -65,7 +66,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(new Token(TT_DOC_START, line, column)); m_tokens.push(Token(TT_DOC_START, line, column));
} }
// DocEnd // DocEnd
...@@ -78,7 +79,7 @@ namespace YAML ...@@ -78,7 +79,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(new Token(TT_DOC_END, line, column)); m_tokens.push(Token(TT_DOC_END, line, column));
} }
// FlowStart // FlowStart
...@@ -93,7 +94,7 @@ namespace YAML ...@@ -93,7 +94,7 @@ namespace YAML
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
char ch = INPUT.get(); char ch = INPUT.get();
TOKEN_TYPE type = (ch == Keys::FlowSeqStart ? TT_FLOW_SEQ_START : TT_FLOW_MAP_START); TOKEN_TYPE type = (ch == Keys::FlowSeqStart ? TT_FLOW_SEQ_START : TT_FLOW_MAP_START);
m_tokens.push(new Token(type, line, column)); m_tokens.push(Token(type, line, column));
} }
// FlowEnd // FlowEnd
...@@ -109,7 +110,7 @@ namespace YAML ...@@ -109,7 +110,7 @@ namespace YAML
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
char ch = INPUT.get(); char ch = INPUT.get();
TOKEN_TYPE type = (ch == Keys::FlowSeqEnd ? TT_FLOW_SEQ_END : TT_FLOW_MAP_END); TOKEN_TYPE type = (ch == Keys::FlowSeqEnd ? TT_FLOW_SEQ_END : TT_FLOW_MAP_END);
m_tokens.push(new Token(type, line, column)); m_tokens.push(Token(type, line, column));
} }
// FlowEntry // FlowEntry
...@@ -120,7 +121,7 @@ namespace YAML ...@@ -120,7 +121,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_FLOW_ENTRY, line, column)); m_tokens.push(Token(TT_FLOW_ENTRY, line, column));
} }
// BlockEntry // BlockEntry
...@@ -140,7 +141,7 @@ namespace YAML ...@@ -140,7 +141,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_BLOCK_ENTRY, line, column)); m_tokens.push(Token(TT_BLOCK_ENTRY, line, column));
} }
// Key // Key
...@@ -163,7 +164,7 @@ namespace YAML ...@@ -163,7 +164,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_KEY, line, column)); m_tokens.push(Token(TT_KEY, line, column));
} }
// Value // Value
...@@ -192,7 +193,7 @@ namespace YAML ...@@ -192,7 +193,7 @@ namespace YAML
// eat // eat
int line = INPUT.line, column = INPUT.column; int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_VALUE, line, column)); m_tokens.push(Token(TT_VALUE, line, column));
} }
// AnchorOrAlias // AnchorOrAlias
...@@ -224,9 +225,9 @@ namespace YAML ...@@ -224,9 +225,9 @@ namespace YAML
throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR); throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);
// and we're done // and we're done
Token *pToken = new Token(alias ? TT_ALIAS : TT_ANCHOR, line, column); Token token(alias ? TT_ALIAS : TT_ANCHOR, line, column);
pToken->value = name; token.value = name;
m_tokens.push(pToken); m_tokens.push(token);
} }
// Tag // Tag
...@@ -261,10 +262,10 @@ namespace YAML ...@@ -261,10 +262,10 @@ namespace YAML
handle = "!"; handle = "!";
} }
Token *pToken = new Token(TT_TAG, line, column); Token token(TT_TAG, line, column);
pToken->value = handle; token.value = handle;
pToken->params.push_back(suffix); token.params.push_back(suffix);
m_tokens.push(pToken); m_tokens.push(token);
} }
// PlainScalar // PlainScalar
...@@ -298,9 +299,9 @@ namespace YAML ...@@ -298,9 +299,9 @@ namespace YAML
//if(Exp::IllegalCharInScalar.Matches(INPUT)) //if(Exp::IllegalCharInScalar.Matches(INPUT))
// throw ParserException(INPUT.line, INPUT.column, ErrorMsg::CHAR_IN_SCALAR); // throw ParserException(INPUT.line, INPUT.column, ErrorMsg::CHAR_IN_SCALAR);
Token *pToken = new Token(TT_SCALAR, line, column); Token token(TT_SCALAR, line, column);
pToken->value = scalar; token.value = scalar;
m_tokens.push(pToken); m_tokens.push(token);
} }
// QuotedScalar // QuotedScalar
...@@ -332,9 +333,9 @@ namespace YAML ...@@ -332,9 +333,9 @@ namespace YAML
scalar = ScanScalar(INPUT, params); scalar = ScanScalar(INPUT, params);
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
Token *pToken = new Token(TT_SCALAR, line, column); Token token(TT_SCALAR, line, column);
pToken->value = scalar; token.value = scalar;
m_tokens.push(pToken); m_tokens.push(token);
} }
// BlockScalarToken // BlockScalarToken
...@@ -397,8 +398,8 @@ namespace YAML ...@@ -397,8 +398,8 @@ namespace YAML
// simple keys always ok after block scalars (since we're gonna start a new line anyways) // simple keys always ok after block scalars (since we're gonna start a new line anyways)
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
Token *pToken = new Token(TT_SCALAR, line, column); Token token(TT_SCALAR, line, column);
pToken->value = scalar; token.value = scalar;
m_tokens.push(pToken); m_tokens.push(token);
} }
} }
#include "crt.h"
#include "sequence.h" #include "sequence.h"
#include "node.h" #include "node.h"
#include "scanner.h" #include "scanner.h"
...@@ -51,9 +52,9 @@ namespace YAML ...@@ -51,9 +52,9 @@ namespace YAML
Clear(); Clear();
// split based on start token // split based on start token
Token *pToken = pScanner->PeekNextToken(); Token& token = pScanner->PeekToken();
switch(pToken->type) { switch(token.type) {
case TT_BLOCK_SEQ_START: ParseBlock(pScanner, state); break; case TT_BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
case TT_BLOCK_ENTRY: ParseImplicit(pScanner, state); break; case TT_BLOCK_ENTRY: ParseImplicit(pScanner, state); break;
case TT_FLOW_SEQ_START: ParseFlow(pScanner, state); break; case TT_FLOW_SEQ_START: ParseFlow(pScanner, state); break;
...@@ -63,18 +64,18 @@ namespace YAML ...@@ -63,18 +64,18 @@ namespace YAML
void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state) void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->EatNextToken(); pScanner->PopToken();
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); if(pScanner->IsEmpty())
if(!pToken)
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ); throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ);
if(pToken->type != TT_BLOCK_ENTRY && pToken->type != TT_BLOCK_END) Token token = pScanner->PeekToken();
throw ParserException(pToken->line, pToken->column, ErrorMsg::END_OF_SEQ); if(token.type != TT_BLOCK_ENTRY && token.type != TT_BLOCK_END)
throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ);
pScanner->PopNextToken(); pScanner->PopToken();
if(pToken->type == TT_BLOCK_END) if(token.type == TT_BLOCK_END)
break; break;
Node *pNode = new Node; Node *pNode = new Node;
...@@ -86,16 +87,16 @@ namespace YAML ...@@ -86,16 +87,16 @@ namespace YAML
void Sequence::ParseImplicit(Scanner *pScanner, const ParserState& state) void Sequence::ParseImplicit(Scanner *pScanner, const ParserState& state)
{ {
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken();
// we're actually *allowed* to have no tokens at some point // we're actually *allowed* to have no tokens at some point
if(!pToken) if(pScanner->IsEmpty())
break; break;
// and we end at anything other than a block entry // and we end at anything other than a block entry
if(pToken->type != TT_BLOCK_ENTRY) Token& token = pScanner->PeekToken();
if(token.type != TT_BLOCK_ENTRY)
break; break;
pScanner->PopNextToken(); pScanner->PopToken();
Node *pNode = new Node; Node *pNode = new Node;
m_data.push_back(pNode); m_data.push_back(pNode);
...@@ -106,16 +107,15 @@ namespace YAML ...@@ -106,16 +107,15 @@ namespace YAML
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state) void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->EatNextToken(); pScanner->PopToken();
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); if(pScanner->IsEmpty())
if(!pToken)
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ_FLOW);
// first check for end // first check for end
if(pToken->type == TT_FLOW_SEQ_END) { if(pScanner->PeekToken().type == TT_FLOW_SEQ_END) {
pScanner->PopNextToken(); pScanner->PopToken();
break; break;
} }
...@@ -125,11 +125,11 @@ namespace YAML ...@@ -125,11 +125,11 @@ namespace YAML
pNode->Parse(pScanner, state); 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(); Token& token = pScanner->PeekToken();
if(pToken->type == TT_FLOW_ENTRY) if(token.type == TT_FLOW_ENTRY)
pScanner->EatNextToken(); pScanner->PopToken();
else if(pToken->type != TT_FLOW_SEQ_END) else if(token.type != TT_FLOW_SEQ_END)
throw ParserException(pToken->line, pToken->column, ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ_FLOW);
} }
} }
......
#include "crt.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h" #include "exceptions.h"
...@@ -39,9 +40,9 @@ namespace YAML ...@@ -39,9 +40,9 @@ namespace YAML
key.pMapStart->status = TS_UNVERIFIED; key.pMapStart->status = TS_UNVERIFIED;
// then add the (now unverified) key // then add the (now unverified) key
key.pKey = new Token(TT_KEY, INPUT.line, INPUT.column); m_tokens.push(Token(TT_KEY, INPUT.line, INPUT.column));
key.pKey = &m_tokens.back();
key.pKey->status = TS_UNVERIFIED; key.pKey->status = TS_UNVERIFIED;
m_tokens.push(key.pKey);
m_simpleKeys.push(key); m_simpleKeys.push(key);
} }
......
#include "crt.h"
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML
......
abeginning: value
zend: value
middle: value
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment