Commit 09d7ab36 authored by Jesse Beder's avatar Jesse 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 2eab1e02
#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
if(pToken && pToken->status == TS_UNVERIFIED)
pToken = 0;
// then that's what we want // note: what's left are the unverified tokens
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