mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
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:
48
exceptions.h
48
exceptions.h
@@ -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
18
exp.cpp
@@ -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
10
map.cpp
@@ -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) {
|
||||||
|
33
parser.cpp
33
parser.cpp
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
parser.h
8
parser.h
@@ -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;
|
||||||
|
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
token.h
3
token.h
@@ -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;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user