Combined the myriad ScannerExceptions and ParserExceptions to a single ParserException class that has a message and a line/column position in the file where the error occurred.

This commit is contained in:
beder
2008-07-08 05:48:38 +00:00
parent 1acc0e4982
commit 2f5c19fa00
12 changed files with 114 additions and 113 deletions

View File

@@ -5,48 +5,16 @@
namespace YAML namespace YAML
{ {
class Exception: public std::exception {}; class Exception: public std::exception {};
class ScannerException: public Exception {}; class ParserException: public Exception {
class ParserException: public Exception {}; public:
ParserException(int line_, int column_, const std::string& msg_)
: line(line_), column(column_), msg(msg_) {}
int line, column;
std::string msg;
};
class RepresentationException: public Exception {}; class RepresentationException: public Exception {};
// scanner exceptions
class UnknownToken: public ScannerException {};
class IllegalBlockEntry: public ScannerException {};
class IllegalMapKey: public ScannerException {};
class IllegalMapValue: public ScannerException {};
class IllegalScalar: public ScannerException {};
class IllegalTabInIndentation: public ScannerException {};
class IllegalFlowEnd: public ScannerException {};
class IllegalDocIndicator: public ScannerException {};
class IllegalEOF: public ScannerException {};
class RequiredSimpleKeyNotFound: public ScannerException {};
class ZeroIndentationInBlockScalar: public ScannerException {};
class UnexpectedCharacterInBlockScalar: public ScannerException {};
class AnchorNotFound: public ScannerException {};
class IllegalCharacterInAnchor: public ScannerException {};
class UnknownEscapeSequence: public ScannerException {
public:
UnknownEscapeSequence(char ch_): ch(ch_) {}
char ch;
};
class NonHexNumber: public ScannerException {
public:
NonHexNumber(char ch_): ch(ch_) {}
char ch;
};
class InvalidUnicode: public ScannerException {
public:
InvalidUnicode(unsigned value_): value(value_) {}
unsigned value;
};
// parser exceptions
class MapEndNotFound: public ParserException {};
class SeqEndNotFound: public ParserException {};
class BadYAMLDirective: public ParserException {};
class BadTAGDirective: public ParserException {};
// representation exceptions // representation exceptions
class InvalidScalar: public RepresentationException {}; class InvalidScalar: public RepresentationException {};
class BadDereference: public RepresentationException {}; class BadDereference: public RepresentationException {};

18
exp.cpp
View File

@@ -1,11 +1,12 @@
#include "exp.h" #include "exp.h"
#include "exceptions.h" #include "exceptions.h"
#include <sstream>
namespace YAML namespace YAML
{ {
namespace Exp namespace Exp
{ {
unsigned ParseHex(std::string str) unsigned ParseHex(const std::string& str, int line, int column)
{ {
unsigned value = 0; unsigned value = 0;
for(unsigned i=0;i<str.size();i++) { for(unsigned i=0;i<str.size();i++) {
@@ -18,7 +19,7 @@ namespace YAML
else if('0' <= ch && ch <= '9') else if('0' <= ch && ch <= '9')
digit = ch - '0'; digit = ch - '0';
else else
throw NonHexNumber(ch); throw ParserException(line, column, "bad character found while scanning hex number");
value = (value << 4) + digit; value = (value << 4) + digit;
} }
@@ -42,11 +43,14 @@ namespace YAML
str += in.get(); str += in.get();
// get the value // get the value
unsigned value = ParseHex(str); unsigned value = ParseHex(str, in.line, in.column);
// legal unicode? // legal unicode?
if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
throw InvalidUnicode(value); std::stringstream msg;
msg << "invalid unicode: " << value;
throw ParserException(in.line, in.column, msg.str());
}
// now break it up into chars // now break it up into chars
if(value <= 0x7F) if(value <= 0x7F)
@@ -101,7 +105,9 @@ namespace YAML
case 'U': return Escape(in, 8); case 'U': return Escape(in, 8);
} }
throw UnknownEscapeSequence(ch); std::stringstream msg;
msg << "unknown escape character: " << ch;
throw ParserException(in.line, in.column, msg.str());
} }
} }
} }

10
map.cpp
View File

@@ -57,10 +57,10 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
throw MapEndNotFound(); throw ParserException(-1, -1, "end of map not found");
if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END) if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END)
throw MapEndNotFound(); throw ParserException(pToken->line, pToken->column, "end of map not found");
pScanner->PopNextToken(); pScanner->PopNextToken();
if(pToken->type == TT_BLOCK_END) if(pToken->type == TT_BLOCK_END)
@@ -96,7 +96,7 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
throw MapEndNotFound(); throw ParserException(-1, -1, "end of map flow not found");
// first check for end // first check for end
if(pToken->type == TT_FLOW_MAP_END) { if(pToken->type == TT_FLOW_MAP_END) {
@@ -106,7 +106,7 @@ namespace YAML
// now it better be a key // now it better be a key
if(pToken->type != TT_KEY) if(pToken->type != TT_KEY)
throw MapEndNotFound(); throw ParserException(pToken->line, pToken->column, "end of map flow not found");
pScanner->PopNextToken(); pScanner->PopNextToken();
@@ -128,7 +128,7 @@ namespace YAML
if(pToken->type == TT_FLOW_ENTRY) if(pToken->type == TT_FLOW_ENTRY)
pScanner->EatNextToken(); pScanner->EatNextToken();
else if(pToken->type != TT_FLOW_MAP_END) else if(pToken->type != TT_FLOW_MAP_END)
throw MapEndNotFound(); throw ParserException(pToken->line, pToken->column, "end of map flow not found");
m_data[pKey] = pValue; m_data[pKey] = pValue;
} catch(Exception& e) { } catch(Exception& e) {

View File

@@ -30,7 +30,7 @@ namespace YAML
// GetNextDocument // GetNextDocument
// . Reads the next document in the queue (of tokens). // . Reads the next document in the queue (of tokens).
// . Throws (ScannerException|ParserException)s on errors. // . Throws (ParserException|ParserException)s on errors.
void Parser::GetNextDocument(Node& document) void Parser::GetNextDocument(Node& document)
{ {
// clear node // clear node
@@ -72,42 +72,43 @@ namespace YAML
m_state.Reset(); m_state.Reset();
readDirective = true; readDirective = true;
HandleDirective(pToken->value, pToken->params); HandleDirective(pToken);
m_pScanner->PopNextToken(); m_pScanner->PopNextToken();
} }
} }
void Parser::HandleDirective(const std::string& name, const std::vector <std::string>& params) void Parser::HandleDirective(Token *pToken)
{ {
if(name == "YAML") if(pToken->value == "YAML")
HandleYamlDirective(params); HandleYamlDirective(pToken);
else if(name == "TAG") else if(pToken->value == "TAG")
HandleTagDirective(params); HandleTagDirective(pToken);
} }
// HandleYamlDirective // HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number) // . Should be of the form 'major.minor' (like a version number)
void Parser::HandleYamlDirective(const std::vector <std::string>& params) void Parser::HandleYamlDirective(Token *pToken)
{ {
if(params.size() != 1) if(pToken->params.size() != 1)
throw BadYAMLDirective(); throw ParserException(pToken->line, pToken->column, "YAML directives must have exactly one argument");
std::stringstream str(params[0]); std::stringstream str(pToken->params[0]);
str >> m_state.version.major; str >> m_state.version.major;
str.get(); str.get();
str >> m_state.version.minor; str >> m_state.version.minor;
if(!str) if(!str)
throw BadYAMLDirective(); // TODO: or throw if there are any more characters in the stream? throw ParserException(pToken->line, pToken->column, "bad YAML directive");
// TODO: or throw if there are any more characters in the stream?
// TODO: throw on major > 1? warning on major == 1, minor > 2? // TODO: throw on major > 1? warning on major == 1, minor > 2?
} }
void Parser::HandleTagDirective(const std::vector <std::string>& params) void Parser::HandleTagDirective(Token *pToken)
{ {
if(params.size() != 2) if(pToken->params.size() != 2)
throw BadTAGDirective(); throw ParserException(pToken->line, pToken->column, "TAG directives must have exactly two arguments");
std::string handle = params[0], prefix = params[1]; std::string handle = pToken->params[0], prefix = pToken->params[1];
m_state.tags[handle] = prefix; m_state.tags[handle] = prefix;
} }

View File

@@ -9,8 +9,8 @@
namespace YAML namespace YAML
{ {
class Node;
class Scanner; class Scanner;
struct Token;
class Parser class Parser
{ {
@@ -26,9 +26,9 @@ namespace YAML
private: private:
void ParseDirectives(); void ParseDirectives();
void HandleDirective(const std::string& name, const std::vector <std::string>& params); void HandleDirective(Token *pToken);
void HandleYamlDirective(const std::vector <std::string>& params); void HandleYamlDirective(Token *pToken);
void HandleTagDirective(const std::vector <std::string>& params); void HandleTagDirective(Token *pToken);
private: private:
Scanner *m_pScanner; Scanner *m_pScanner;

View File

@@ -157,7 +157,7 @@ namespace YAML
return ScanPlainScalar(); return ScanPlainScalar();
// don't know what it is! // don't know what it is!
throw UnknownToken(); throw ParserException(INPUT.line, INPUT.column, "unknown token");
} }
// ScanToNextToken // ScanToNextToken
@@ -256,9 +256,9 @@ namespace YAML
m_indents.push(column); m_indents.push(column);
Token *pToken = 0; Token *pToken = 0;
if(sequence) if(sequence)
pToken = new Token(TT_BLOCK_SEQ_START); pToken = new Token(TT_BLOCK_SEQ_START, INPUT.line, INPUT.column);
else else
pToken = new Token(TT_BLOCK_MAP_START); pToken = new Token(TT_BLOCK_MAP_START, INPUT.line, INPUT.column);
m_tokens.push(pToken); m_tokens.push(pToken);
return pToken; return pToken;
@@ -276,7 +276,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)); m_tokens.push(new Token(TT_BLOCK_END, INPUT.line, INPUT.column));
} }
} }
} }

View File

@@ -35,7 +35,7 @@ namespace YAML
if(params.onDocIndicator == BREAK) if(params.onDocIndicator == BREAK)
break; break;
else if(params.onDocIndicator == THROW) else if(params.onDocIndicator == THROW)
throw IllegalDocIndicator(); throw ParserException(INPUT.line, INPUT.column, "illegal document indicator in scalar");
} }
foundNonEmptyLine = true; foundNonEmptyLine = true;
@@ -61,7 +61,7 @@ namespace YAML
// eof? if we're looking to eat something, then we throw // eof? if we're looking to eat something, then we throw
if(INPUT.peek() == EOF) { if(INPUT.peek() == EOF) {
if(params.eatEnd) if(params.eatEnd)
throw IllegalEOF(); throw ParserException(INPUT.line, INPUT.column, "illegal EOF in scalar");
break; break;
} }
@@ -97,7 +97,7 @@ namespace YAML
while(Exp::Blank.Matches(INPUT)) { while(Exp::Blank.Matches(INPUT)) {
// we check for tabs that masquerade as indentation // we check for tabs that masquerade as indentation
if(INPUT.peek() == '\t'&& INPUT.column < params.indent && params.onTabInIndentation == THROW) if(INPUT.peek() == '\t'&& INPUT.column < params.indent && params.onTabInIndentation == THROW)
throw IllegalTabInIndentation(); throw ParserException(INPUT.line, INPUT.column, "illegal tab when looking for indentation");
if(!params.eatLeadingWhitespace) if(!params.eatLeadingWhitespace)
break; break;

View File

@@ -3,6 +3,7 @@
#include "exceptions.h" #include "exceptions.h"
#include "exp.h" #include "exp.h"
#include "scanscalar.h" #include "scanscalar.h"
#include <sstream>
namespace YAML namespace YAML
{ {
@@ -22,7 +23,8 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat indicator // store pos and eat indicator
int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
// read name // read name
@@ -47,7 +49,7 @@ namespace YAML
params.push_back(param); params.push_back(param);
} }
Token *pToken = new Token(TT_DIRECTIVE); Token *pToken = new Token(TT_DIRECTIVE, line, column);
pToken->value = name; pToken->value = name;
pToken->params = params; pToken->params = params;
m_tokens.push(pToken); m_tokens.push(pToken);
@@ -61,8 +63,9 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(new Token(TT_DOC_START)); m_tokens.push(new Token(TT_DOC_START, line, column));
} }
// DocEnd // DocEnd
@@ -73,8 +76,9 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(new Token(TT_DOC_END)); m_tokens.push(new Token(TT_DOC_END, line, column));
} }
// FlowStart // FlowStart
@@ -86,24 +90,26 @@ namespace YAML
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
// eat // eat
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)); m_tokens.push(new Token(type, line, column));
} }
// FlowEnd // FlowEnd
void Scanner::ScanFlowEnd() void Scanner::ScanFlowEnd()
{ {
if(m_flowLevel == 0) if(m_flowLevel == 0)
throw IllegalFlowEnd(); throw ParserException(INPUT.line, INPUT.column, "illegal flow end");
m_flowLevel--; m_flowLevel--;
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat // eat
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)); m_tokens.push(new Token(type, line, column));
} }
// FlowEntry // FlowEntry
@@ -112,8 +118,9 @@ namespace YAML
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_FLOW_ENTRY)); m_tokens.push(new Token(TT_FLOW_ENTRY, line, column));
} }
// BlockEntry // BlockEntry
@@ -121,18 +128,19 @@ namespace YAML
{ {
// we better be in the block context! // we better be in the block context!
if(m_flowLevel > 0) if(m_flowLevel > 0)
throw IllegalBlockEntry(); throw ParserException(INPUT.line, INPUT.column, "illegal block entry");
// can we put it here? // can we put it here?
if(!m_simpleKeyAllowed) if(!m_simpleKeyAllowed)
throw IllegalBlockEntry(); throw ParserException(INPUT.line, INPUT.column, "illegal block entry");
PushIndentTo(INPUT.column, true); PushIndentTo(INPUT.column, true);
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_BLOCK_ENTRY)); m_tokens.push(new Token(TT_BLOCK_ENTRY, line, column));
} }
// Key // Key
@@ -141,7 +149,7 @@ namespace YAML
// handle keys diffently in the block context (and manage indents) // handle keys diffently in the block context (and manage indents)
if(m_flowLevel == 0) { if(m_flowLevel == 0) {
if(!m_simpleKeyAllowed) if(!m_simpleKeyAllowed)
throw IllegalMapKey(); throw ParserException(INPUT.line, INPUT.column, "illegal map key");
PushIndentTo(INPUT.column, false); PushIndentTo(INPUT.column, false);
} }
@@ -153,8 +161,9 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_KEY)); m_tokens.push(new Token(TT_KEY, line, column));
} }
// Value // Value
@@ -168,7 +177,7 @@ namespace YAML
// handle values diffently in the block context (and manage indents) // handle values diffently in the block context (and manage indents)
if(m_flowLevel == 0) { if(m_flowLevel == 0) {
if(!m_simpleKeyAllowed) if(!m_simpleKeyAllowed)
throw IllegalMapValue(); throw ParserException(INPUT.line, INPUT.column, "illegal map value");
PushIndentTo(INPUT.column, false); PushIndentTo(INPUT.column, false);
} }
@@ -181,8 +190,9 @@ namespace YAML
} }
// eat // eat
int line = INPUT.line, column = INPUT.column;
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(new Token(TT_VALUE)); m_tokens.push(new Token(TT_VALUE, line, column));
} }
// AnchorOrAlias // AnchorOrAlias
@@ -197,6 +207,7 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat the indicator // eat the indicator
int line = INPUT.line, column = INPUT.column;
char indicator = INPUT.get(); char indicator = INPUT.get();
alias = (indicator == Keys::Alias); alias = (indicator == Keys::Alias);
@@ -205,15 +216,24 @@ namespace YAML
name += INPUT.get(); name += INPUT.get();
// we need to have read SOMETHING! // we need to have read SOMETHING!
if(name.empty()) if(name.empty()) {
throw AnchorNotFound(); std::stringstream msg;
msg << (alias ? "alias" : "anchor");
msg << " not found after ";
msg << (alias ? "*" : "&");
throw ParserException(INPUT.line, INPUT.column, msg.str());
}
// and needs to end correctly // and needs to end correctly
if(INPUT.peek() != EOF && !Exp::AnchorEnd.Matches(INPUT)) if(INPUT.peek() != EOF && !Exp::AnchorEnd.Matches(INPUT)) {
throw IllegalCharacterInAnchor(); std::stringstream msg;
msg << "illegal character found while scanning ";
msg << (alias ? "alias" : "anchor");
throw ParserException(INPUT.line, INPUT.column, msg.str());
}
// 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, line, column);
pToken->value = name; pToken->value = name;
m_tokens.push(pToken); m_tokens.push(pToken);
} }
@@ -229,6 +249,7 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
// eat the indicator // eat the indicator
int line = INPUT.line, column = INPUT.column;
handle += INPUT.get(); handle += INPUT.get();
// read the handle // read the handle
@@ -249,7 +270,7 @@ namespace YAML
handle = "!"; handle = "!";
} }
Token *pToken = new Token(TT_TAG); Token *pToken = new Token(TT_TAG, line, column);
pToken->value = handle; pToken->value = handle;
pToken->params.push_back(suffix); pToken->params.push_back(suffix);
m_tokens.push(pToken); m_tokens.push(pToken);
@@ -276,6 +297,7 @@ namespace YAML
if(m_simpleKeyAllowed) if(m_simpleKeyAllowed)
InsertSimpleKey(); InsertSimpleKey();
int line = INPUT.line, column = INPUT.column;
scalar = ScanScalar(INPUT, params); scalar = ScanScalar(INPUT, params);
// can have a simple key only if we ended the scalar by starting a new line // can have a simple key only if we ended the scalar by starting a new line
@@ -284,9 +306,9 @@ namespace YAML
// finally, we can't have any colons in a scalar, so if we ended on a colon, there // finally, we can't have any colons in a scalar, so if we ended on a colon, there
// had better be a break after it // had better be a break after it
if(Exp::IllegalColonInScalar.Matches(INPUT)) if(Exp::IllegalColonInScalar.Matches(INPUT))
throw IllegalScalar(); throw ParserException(INPUT.line, INPUT.column, "illegal character in scalar");
Token *pToken = new Token(TT_SCALAR); Token *pToken = new Token(TT_SCALAR, line, column);
pToken->value = scalar; pToken->value = scalar;
m_tokens.push(pToken); m_tokens.push(pToken);
} }
@@ -316,10 +338,11 @@ namespace YAML
if(m_simpleKeyAllowed) if(m_simpleKeyAllowed)
InsertSimpleKey(); InsertSimpleKey();
int line = INPUT.line, column = INPUT.column;
scalar = ScanScalar(INPUT, params); scalar = ScanScalar(INPUT, params);
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
Token *pToken = new Token(TT_SCALAR); Token *pToken = new Token(TT_SCALAR, line, column);
pToken->value = scalar; pToken->value = scalar;
m_tokens.push(pToken); m_tokens.push(pToken);
} }
@@ -337,6 +360,7 @@ namespace YAML
params.detectIndent = true; params.detectIndent = true;
// eat block indicator ('|' or '>') // eat block indicator ('|' or '>')
int line = INPUT.line, column = INPUT.column;
char indicator = INPUT.get(); char indicator = INPUT.get();
params.fold = (indicator == Keys::FoldedScalar); params.fold = (indicator == Keys::FoldedScalar);
@@ -350,7 +374,7 @@ namespace YAML
params.chomp = STRIP; params.chomp = STRIP;
else if(Exp::Digit.Matches(ch)) { else if(Exp::Digit.Matches(ch)) {
if(ch == '0') if(ch == '0')
throw ZeroIndentationInBlockScalar(); throw ParserException(INPUT.line, INPUT.column, "cannot set zero indentation for a block scalar");
params.indent = ch - '0'; params.indent = ch - '0';
params.detectIndent = false; params.detectIndent = false;
@@ -368,7 +392,7 @@ namespace YAML
// if it's not a line break, then we ran into a bad character inline // if it's not a line break, then we ran into a bad character inline
if(INPUT && !Exp::Break.Matches(INPUT)) if(INPUT && !Exp::Break.Matches(INPUT))
throw UnexpectedCharacterInBlockScalar(); throw ParserException(INPUT.line, INPUT.column, "unexpected character in block scalar");
// set the initial indentation // set the initial indentation
if(m_indents.top() >= 0) if(m_indents.top() >= 0)
@@ -383,7 +407,7 @@ 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); Token *pToken = new Token(TT_SCALAR, line, column);
pToken->value = scalar; pToken->value = scalar;
m_tokens.push(pToken); m_tokens.push(pToken);
} }

View File

@@ -68,10 +68,10 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
throw SeqEndNotFound(); throw ParserException(-1, -1, "end of sequence not found");
if(pToken->type != TT_BLOCK_ENTRY && pToken->type != TT_BLOCK_END) if(pToken->type != TT_BLOCK_ENTRY && pToken->type != TT_BLOCK_END)
throw SeqEndNotFound(); throw ParserException(pToken->line, pToken->column, "end of sequence not found");
pScanner->PopNextToken(); pScanner->PopNextToken();
if(pToken->type == TT_BLOCK_END) if(pToken->type == TT_BLOCK_END)
@@ -111,7 +111,7 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
throw SeqEndNotFound(); throw ParserException(-1, -1, "end of sequence flow not found");
// first check for end // first check for end
if(pToken->type == TT_FLOW_SEQ_END) { if(pToken->type == TT_FLOW_SEQ_END) {
@@ -129,7 +129,7 @@ namespace YAML
if(pToken->type == TT_FLOW_ENTRY) if(pToken->type == TT_FLOW_ENTRY)
pScanner->EatNextToken(); pScanner->EatNextToken();
else if(pToken->type != TT_FLOW_SEQ_END) else if(pToken->type != TT_FLOW_SEQ_END)
throw SeqEndNotFound(); throw ParserException(pToken->line, pToken->column, "end of sequence flow not found");
} }
} }

View File

@@ -21,7 +21,7 @@ namespace YAML
void Scanner::SimpleKey::Invalidate() void Scanner::SimpleKey::Invalidate()
{ {
if(required) if(required)
throw RequiredSimpleKeyNotFound(); throw ParserException(line, column, "required simple key not found");
if(pMapStart) if(pMapStart)
pMapStart->status = TS_INVALID; pMapStart->status = TS_INVALID;
@@ -44,7 +44,7 @@ namespace YAML
// key.required = true; // TODO: is this correct? // key.required = true; // TODO: is this correct?
// then add the (now unverified) key // then add the (now unverified) key
key.pKey = new Token(TT_KEY); key.pKey = new Token(TT_KEY, INPUT.line, INPUT.column);
key.pKey->status = TS_UNVERIFIED; key.pKey->status = TS_UNVERIFIED;
m_tokens.push(key.pKey); m_tokens.push(key.pKey);

View File

@@ -71,7 +71,8 @@ namespace YAML
fout << secondTry << std::endl; fout << secondTry << std::endl;
return false; return false;
} catch(Exception&) { } catch(ParserException& e) {
std::cout << file << " (line " << e.line + 1 << ", col " << e.column + 1 << "): " << e.msg << std::endl;
return false; return false;
} }

View File

@@ -50,7 +50,7 @@ namespace YAML
}; };
struct Token { struct Token {
Token(TOKEN_TYPE type_): status(TS_VALID), type(type_) {} Token(TOKEN_TYPE type_, int line_, int column_): status(TS_VALID), type(type_), line(line_), column(column_) {}
friend std::ostream& operator << (std::ostream& out, const Token& token) { friend std::ostream& operator << (std::ostream& out, const Token& token) {
out << TokenNames[token.type] << ": " << token.value; out << TokenNames[token.type] << ": " << token.value;
@@ -61,6 +61,7 @@ namespace YAML
TOKEN_STATUS status; TOKEN_STATUS status;
TOKEN_TYPE type; TOKEN_TYPE type;
int line, column;
std::string value; std::string value;
std::vector <std::string> params; std::vector <std::string> params;
}; };