Set the eol style to native for all files.

This commit is contained in:
Jesse Beder
2008-09-03 22:20:39 +00:00
parent a45f083e00
commit 45322566c7
42 changed files with 3546 additions and 3546 deletions
+11 -11
View File
@@ -1,11 +1,11 @@
#pragma once #pragma once
// for detecting memory leaks // for detecting memory leaks
#ifdef _DEBUG #ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC #define _CRTDBG_MAP_ALLOC
#include <stdlib.h> #include <stdlib.h>
#include <crtdbg.h> #include <crtdbg.h>
#endif // _DEBUG #endif // _DEBUG
+59 -59
View File
@@ -1,59 +1,59 @@
#pragma once #pragma once
#include <exception> #include <exception>
#include <string> #include <string>
namespace YAML namespace YAML
{ {
class Exception: public std::exception {}; class Exception: public std::exception {};
class ParserException: public Exception { class ParserException: public Exception {
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_) {}
virtual ~ParserException() throw () {} virtual ~ParserException() throw () {}
int line, column; int line, column;
std::string msg; std::string msg;
}; };
class RepresentationException: public Exception {}; class RepresentationException: public Exception {};
// representation exceptions // representation exceptions
class InvalidScalar: public RepresentationException {}; class InvalidScalar: public RepresentationException {};
class BadDereference: public RepresentationException {}; class BadDereference: public RepresentationException {};
// error messages // error messages
namespace ErrorMsg namespace ErrorMsg
{ {
const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument"; const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
const std::string YAML_VERSION = "bad YAML version: "; const std::string YAML_VERSION = "bad YAML version: ";
const std::string YAML_MAJOR_VERSION = "YAML major version too large"; const std::string YAML_MAJOR_VERSION = "YAML major version too large";
const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments"; const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
const std::string END_OF_MAP = "end of map not found"; const std::string END_OF_MAP = "end of map not found";
const std::string END_OF_MAP_FLOW = "end of map flow not found"; const std::string END_OF_MAP_FLOW = "end of map flow not found";
const std::string END_OF_SEQ = "end of sequence not found"; const std::string END_OF_SEQ = "end of sequence not found";
const std::string END_OF_SEQ_FLOW = "end of sequence flow not found"; const std::string END_OF_SEQ_FLOW = "end of sequence flow not found";
const std::string MULTIPLE_TAGS = "cannot assign multiple tags to the same node"; const std::string MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
const std::string MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node"; const std::string MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
const std::string MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node"; const std::string MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
const std::string ALIAS_CONTENT = "aliases can't have any content, *including* tags"; const std::string ALIAS_CONTENT = "aliases can't have any content, *including* tags";
const std::string INVALID_HEX = "bad character found while scanning hex number"; const std::string INVALID_HEX = "bad character found while scanning hex number";
const std::string INVALID_UNICODE = "invalid unicode: "; const std::string INVALID_UNICODE = "invalid unicode: ";
const std::string INVALID_ESCAPE = "unknown escape character: "; const std::string INVALID_ESCAPE = "unknown escape character: ";
const std::string UNKNOWN_TOKEN = "unknown token"; const std::string UNKNOWN_TOKEN = "unknown token";
const std::string DOC_IN_SCALAR = "illegal document indicator in scalar"; const std::string DOC_IN_SCALAR = "illegal document indicator in scalar";
const std::string EOF_IN_SCALAR = "illegal EOF in scalar"; const std::string EOF_IN_SCALAR = "illegal EOF in scalar";
const std::string CHAR_IN_SCALAR = "illegal character in scalar"; const std::string CHAR_IN_SCALAR = "illegal character in scalar";
const std::string TAB_IN_INDENTATION = "illegal tab when looking for indentation"; const std::string TAB_IN_INDENTATION = "illegal tab when looking for indentation";
const std::string FLOW_END = "illegal flow end"; const std::string FLOW_END = "illegal flow end";
const std::string BLOCK_ENTRY = "illegal block entry"; const std::string BLOCK_ENTRY = "illegal block entry";
const std::string MAP_KEY = "illegal map key"; const std::string MAP_KEY = "illegal map key";
const std::string MAP_VALUE = "illegal map value"; const std::string MAP_VALUE = "illegal map value";
const std::string ALIAS_NOT_FOUND = "alias not found after *"; const std::string ALIAS_NOT_FOUND = "alias not found after *";
const std::string ANCHOR_NOT_FOUND = "anchor not found after &"; const std::string ANCHOR_NOT_FOUND = "anchor not found after &";
const std::string CHAR_IN_ALIAS = "illegal character found while scanning alias"; const std::string CHAR_IN_ALIAS = "illegal character found while scanning alias";
const std::string CHAR_IN_ANCHOR = "illegal character found while scanning anchor"; const std::string CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
const std::string ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar"; const std::string ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
const std::string CHAR_IN_BLOCK = "unexpected character in block scalar"; const std::string CHAR_IN_BLOCK = "unexpected character in block scalar";
} }
} }
+30 -30
View File
@@ -1,30 +1,30 @@
#pragma once #pragma once
namespace YAML namespace YAML
{ {
class Node; class Node;
struct IterPriv; struct IterPriv;
class Iterator class Iterator
{ {
public: public:
Iterator(); Iterator();
Iterator(IterPriv *pData); Iterator(IterPriv *pData);
Iterator(const Iterator& rhs); Iterator(const Iterator& rhs);
~Iterator(); ~Iterator();
Iterator& operator = (const Iterator& rhs); Iterator& operator = (const Iterator& rhs);
Iterator& operator ++ (); Iterator& operator ++ ();
Iterator operator ++ (int); Iterator operator ++ (int);
const Node& operator * () const; const Node& operator * () const;
const Node *operator -> () const; const Node *operator -> () const;
const Node& first() const; const Node& first() const;
const Node& second() const; const Node& second() const;
friend bool operator == (const Iterator& it, const Iterator& jt); friend bool operator == (const Iterator& it, const Iterator& jt);
friend bool operator != (const Iterator& it, const Iterator& jt); friend bool operator != (const Iterator& it, const Iterator& jt);
private: private:
IterPriv *m_pData; IterPriv *m_pData;
}; };
} }
+92 -92
View File
@@ -1,92 +1,92 @@
#pragma once #pragma once
#include <string> #include <string>
#include <ios> #include <ios>
#include <vector> #include <vector>
#include <map> #include <map>
#include "parserstate.h" #include "parserstate.h"
#include "exceptions.h" #include "exceptions.h"
#include "iterator.h" #include "iterator.h"
namespace YAML namespace YAML
{ {
class Content; class Content;
class Scanner; class Scanner;
enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP }; enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP };
class Node class Node
{ {
public: public:
Node(); Node();
~Node(); ~Node();
void Clear(); void Clear();
void Parse(Scanner *pScanner, const ParserState& state); void Parse(Scanner *pScanner, const ParserState& state);
void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const; void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const;
CONTENT_TYPE GetType() const; CONTENT_TYPE GetType() const;
// accessors // accessors
Iterator begin() const; Iterator begin() const;
Iterator end() const; Iterator end() const;
unsigned size() const; unsigned size() const;
template <typename T> template <typename T>
const Node& GetValue(const T& key) const { const Node& GetValue(const T& key) const {
if(!m_pContent) if(!m_pContent)
throw BadDereference(); throw BadDereference();
for(Iterator it=begin();it!=end();++it) { for(Iterator it=begin();it!=end();++it) {
T t; T t;
try { try {
it.first() >> t; it.first() >> t;
if(key == t) if(key == t)
return it.second(); return it.second();
} catch(RepresentationException&) { } catch(RepresentationException&) {
} }
} }
throw BadDereference(); throw BadDereference();
} }
template <typename T> template <typename T>
const Node& operator [] (const T& key) const { const Node& operator [] (const T& key) const {
return GetValue(key); return GetValue(key);
} }
const Node& operator [] (const char *key) const { const Node& operator [] (const char *key) const {
return GetValue(std::string(key)); return GetValue(std::string(key));
} }
const Node& operator [] (unsigned u) const; const Node& operator [] (unsigned u) const;
const Node& operator [] (int i) const; const Node& operator [] (int i) const;
// extraction // extraction
friend void operator >> (const Node& node, std::string& s); friend void operator >> (const Node& node, std::string& s);
friend void operator >> (const Node& node, int& i); friend void operator >> (const Node& node, int& i);
friend void operator >> (const Node& node, unsigned& u); friend void operator >> (const Node& node, unsigned& u);
friend void operator >> (const Node& node, long& l); friend void operator >> (const Node& node, long& l);
friend void operator >> (const Node& node, float& f); friend void operator >> (const Node& node, float& f);
friend void operator >> (const Node& node, double& d); friend void operator >> (const Node& node, double& d);
friend void operator >> (const Node& node, char& c); friend void operator >> (const Node& node, char& c);
// insertion // insertion
friend std::ostream& operator << (std::ostream& out, const Node& node); friend std::ostream& operator << (std::ostream& out, const Node& node);
// ordering // ordering
int Compare(const Node& rhs) const; int Compare(const Node& rhs) const;
friend bool operator < (const Node& n1, const Node& n2); friend bool operator < (const Node& n1, const Node& n2);
private: private:
void ParseHeader(Scanner *pScanner, const ParserState& state); void ParseHeader(Scanner *pScanner, const ParserState& state);
void ParseTag(Scanner *pScanner, const ParserState& state); void ParseTag(Scanner *pScanner, const ParserState& state);
void ParseAnchor(Scanner *pScanner, const ParserState& state); void ParseAnchor(Scanner *pScanner, const ParserState& state);
void ParseAlias(Scanner *pScanner, const ParserState& state); void ParseAlias(Scanner *pScanner, const ParserState& state);
private: private:
std::string m_anchor, m_tag; std::string m_anchor, m_tag;
Content *m_pContent; Content *m_pContent;
bool m_alias; bool m_alias;
}; };
} }
+42 -42
View File
@@ -1,42 +1,42 @@
#pragma once #pragma once
#include <ios> #include <ios>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include "node.h" #include "node.h"
#include "parserstate.h" #include "parserstate.h"
namespace YAML namespace YAML
{ {
class Scanner; class Scanner;
struct Token; struct Token;
class Parser class Parser
{ {
public: public:
Parser(std::istream& in); Parser(std::istream& in);
~Parser(); ~Parser();
operator bool() const; operator bool() const;
void Load(std::istream& in); void Load(std::istream& in);
void GetNextDocument(Node& document); void GetNextDocument(Node& document);
void PrintTokens(std::ostream& out); void PrintTokens(std::ostream& out);
private: private:
void ParseDirectives(); void ParseDirectives();
void HandleDirective(Token *pToken); void HandleDirective(Token *pToken);
void HandleYamlDirective(Token *pToken); void HandleYamlDirective(Token *pToken);
void HandleTagDirective(Token *pToken); void HandleTagDirective(Token *pToken);
private: private:
// can't copy this // can't copy this
Parser(const Parser& rhs) {} Parser(const Parser& rhs) {}
Parser& operator = (const Parser& rhs) { return *this; } Parser& operator = (const Parser& rhs) { return *this; }
private: private:
Scanner *m_pScanner; Scanner *m_pScanner;
ParserState m_state; ParserState m_state;
}; };
} }
+20 -20
View File
@@ -1,20 +1,20 @@
#pragma once #pragma once
#include <string> #include <string>
#include <map> #include <map>
namespace YAML namespace YAML
{ {
struct Version { struct Version {
int major, minor; int major, minor;
}; };
struct ParserState struct ParserState
{ {
Version version; Version version;
std::map <std::string, std::string> tags; std::map <std::string, std::string> tags;
void Reset(); void Reset();
std::string TranslateTag(const std::string& handle) const; std::string TranslateTag(const std::string& handle) const;
}; };
} }
+8 -8
View File
@@ -1,8 +1,8 @@
#pragma once #pragma once
#include "crt.h" #include "crt.h"
#include "parser.h" #include "parser.h"
#include "node.h" #include "node.h"
#include "iterator.h" #include "iterator.h"
#include "exceptions.h" #include "exceptions.h"
+13 -13
View File
@@ -1,13 +1,13 @@
#include "crt.h" #include "crt.h"
#include "content.h" #include "content.h"
namespace YAML namespace YAML
{ {
Content::Content() Content::Content()
{ {
} }
Content::~Content() Content::~Content()
{ {
} }
} }
+55 -55
View File
@@ -1,55 +1,55 @@
#pragma once #pragma once
#include <ios> #include <ios>
#include <vector> #include <vector>
#include <map> #include <map>
#include "parserstate.h" #include "parserstate.h"
#include "exceptions.h" #include "exceptions.h"
#include "ltnode.h" #include "ltnode.h"
namespace YAML namespace YAML
{ {
class Scanner; class Scanner;
class Parser; class Parser;
class Node; class Node;
class Scalar; class Scalar;
class Sequence; class Sequence;
class Map; class Map;
class Content class Content
{ {
public: public:
Content(); Content();
virtual ~Content(); virtual ~Content();
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0; virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) = 0; virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) = 0;
virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const { return false; } virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const { return false; }
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; } virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; }
virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const { return false; } virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const { return false; }
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; } virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; }
virtual Node *GetNode(unsigned i) const { return 0; } virtual Node *GetNode(unsigned i) const { return 0; }
virtual unsigned GetSize() const { return 0; } virtual unsigned GetSize() const { return 0; }
virtual bool IsScalar() const { return false; } virtual bool IsScalar() const { return false; }
virtual bool IsMap() const { return false; } virtual bool IsMap() const { return false; }
virtual bool IsSequence() const { return false; } virtual bool IsSequence() const { return false; }
// extraction // extraction
virtual void Read(std::string& s) { throw InvalidScalar(); } virtual void Read(std::string& s) { throw InvalidScalar(); }
virtual void Read(int& i) { throw InvalidScalar(); } virtual void Read(int& i) { throw InvalidScalar(); }
virtual void Read(unsigned& u) { throw InvalidScalar(); } virtual void Read(unsigned& u) { throw InvalidScalar(); }
virtual void Read(long& l) { throw InvalidScalar(); } virtual void Read(long& l) { throw InvalidScalar(); }
virtual void Read(float& f) { throw InvalidScalar(); } virtual void Read(float& f) { throw InvalidScalar(); }
virtual void Read(double& d) { throw InvalidScalar(); } virtual void Read(double& d) { throw InvalidScalar(); }
virtual void Read(char& c) { throw InvalidScalar(); } virtual void Read(char& c) { throw InvalidScalar(); }
// ordering // ordering
virtual int Compare(Content *pContent) { return 0; } virtual int Compare(Content *pContent) { return 0; }
virtual int Compare(Scalar *pScalar) { return 0; } virtual int Compare(Scalar *pScalar) { return 0; }
virtual int Compare(Sequence *pSeq) { return 0; } virtual int Compare(Sequence *pSeq) { return 0; }
virtual int Compare(Map *pMap) { return 0; } virtual int Compare(Map *pMap) { return 0; }
protected: protected:
}; };
} }
+113 -113
View File
@@ -1,113 +1,113 @@
#include "crt.h" #include "crt.h"
#include "exp.h" #include "exp.h"
#include "exceptions.h" #include "exceptions.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML
{ {
namespace Exp namespace Exp
{ {
unsigned ParseHex(const std::string& str, int line, int column) 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++) {
char ch = str[i]; char ch = str[i];
int digit = 0; int digit = 0;
if('a' <= ch && ch <= 'f') if('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10; digit = ch - 'a' + 10;
else if('A' <= ch && ch <= 'F') else if('A' <= ch && ch <= 'F')
digit = ch - 'A' + 10; digit = ch - 'A' + 10;
else if('0' <= ch && ch <= '9') else if('0' <= ch && ch <= '9')
digit = ch - '0'; digit = ch - '0';
else else
throw ParserException(line, column, ErrorMsg::INVALID_HEX); throw ParserException(line, column, ErrorMsg::INVALID_HEX);
value = (value << 4) + digit; value = (value << 4) + digit;
} }
return value; return value;
} }
std::string Str(char ch) std::string Str(char ch)
{ {
return std::string("") + ch; return std::string("") + ch;
} }
// Escape // Escape
// . Translates the next 'codeLength' characters into a hex number and returns the result. // . Translates the next 'codeLength' characters into a hex number and returns the result.
// . Throws if it's not actually hex. // . Throws if it's not actually hex.
std::string Escape(Stream& in, int codeLength) std::string Escape(Stream& in, int codeLength)
{ {
// grab string // grab string
std::string str; std::string str;
for(int i=0;i<codeLength;i++) for(int i=0;i<codeLength;i++)
str += in.get(); str += in.get();
// get the value // get the value
unsigned value = ParseHex(str, in.line, in.column); 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) {
std::stringstream msg; std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value; msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.line, in.column, msg.str()); 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)
return Str(value); return Str(value);
else if(value <= 0x7FF) else if(value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
else if(value <= 0xFFFF) else if(value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
else else
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
} }
// Escape // Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote) // . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
// and returns the result. // and returns the result.
// . Throws if it's an unknown escape character. // . Throws if it's an unknown escape character.
std::string Escape(Stream& in) std::string Escape(Stream& in)
{ {
// eat slash // eat slash
char escape = in.get(); char escape = in.get();
// switch on escape character // switch on escape character
char ch = in.get(); char ch = in.get();
// first do single quote, since it's easier // first do single quote, since it's easier
if(escape == '\'' && ch == '\'') if(escape == '\'' && ch == '\'')
return "\'"; return "\'";
// now do the slash (we're not gonna check if it's a slash - you better pass one!) // now do the slash (we're not gonna check if it's a slash - you better pass one!)
switch(ch) { switch(ch) {
case '0': return "\0"; case '0': return "\0";
case 'a': return "\x07"; case 'a': return "\x07";
case 'b': return "\x08"; case 'b': return "\x08";
case 't': case 't':
case '\t': return "\x09"; case '\t': return "\x09";
case 'n': return "\x0A"; case 'n': return "\x0A";
case 'v': return "\x0B"; case 'v': return "\x0B";
case 'f': return "\x0C"; case 'f': return "\x0C";
case 'r': return "\x0D"; case 'r': return "\x0D";
case 'e': return "\x1B"; case 'e': return "\x1B";
case ' ': return "\x20"; case ' ': return "\x20";
case '\"': return "\""; case '\"': return "\"";
case '\'': return "\'"; case '\'': return "\'";
case '\\': return "\\"; case '\\': return "\\";
case 'N': return "\xC2\x85"; // NEL (#x85) case 'N': return "\xC2\x85"; // NEL (#x85)
case '_': return "\xC2\xA0"; // #xA0 case '_': return "\xC2\xA0"; // #xA0
case 'L': return "\xE2\x80\xA8"; // LS (#x2028) case 'L': return "\xE2\x80\xA8"; // LS (#x2028)
case 'P': return "\xE2\x80\xA9"; // PS (#x2029) case 'P': return "\xE2\x80\xA9"; // PS (#x2029)
case 'x': return Escape(in, 2); case 'x': return Escape(in, 2);
case 'u': return Escape(in, 4); case 'u': return Escape(in, 4);
case 'U': return Escape(in, 8); case 'U': return Escape(in, 8);
} }
std::stringstream msg; std::stringstream msg;
throw ParserException(in.line, in.column, ErrorMsg::INVALID_ESCAPE + ch); throw ParserException(in.line, in.column, ErrorMsg::INVALID_ESCAPE + ch);
} }
} }
} }
+71 -71
View File
@@ -1,71 +1,71 @@
#pragma once #pragma once
#include "regex.h" #include "regex.h"
#include <string> #include <string>
#include <ios> #include <ios>
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Here we store a bunch of expressions for matching different parts of the file. // Here we store a bunch of expressions for matching different parts of the file.
namespace Exp namespace Exp
{ {
// misc // misc
const RegEx Blank = RegEx(' ') || RegEx('\t'); const RegEx Blank = RegEx(' ') || RegEx('\t');
const RegEx Break = RegEx('\n') || RegEx("\r\n"); const RegEx Break = RegEx('\n') || RegEx("\r\n");
const RegEx BlankOrBreak = Blank || Break; const RegEx BlankOrBreak = Blank || Break;
const RegEx Digit = RegEx('0', '9'); const RegEx Digit = RegEx('0', '9');
const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z'); const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z');
const RegEx AlphaNumeric = Alpha || Digit; const RegEx AlphaNumeric = Alpha || Digit;
const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f'); const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f');
// actual tags // actual tags
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx(EOF) || RegEx()); const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx(EOF) || RegEx());
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx(EOF) || RegEx()); const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx(EOF) || RegEx());
const RegEx DocIndicator = DocStart || DocEnd; const RegEx DocIndicator = DocStart || DocEnd;
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx(EOF)); const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx(EOF));
const RegEx Key = RegEx('?'), const RegEx Key = RegEx('?'),
KeyInFlow = RegEx('?') + BlankOrBreak; KeyInFlow = RegEx('?') + BlankOrBreak;
const RegEx Value = RegEx(':') + BlankOrBreak, const RegEx Value = RegEx(':') + BlankOrBreak,
ValueInFlow = RegEx(':') + BlankOrBreak; ValueInFlow = RegEx(':') + BlankOrBreak;
const RegEx Comment = RegEx('#'); const RegEx Comment = RegEx('#');
const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak; const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak;
// Plain scalar rules: // Plain scalar rules:
// . Cannot start with a blank. // . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ ` // . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . In the block context - ? : must be not be followed with a space. // . In the block context - ? : must be not be followed with a space.
// . In the flow context ? is illegal and : and - must not be followed with a space. // . In the flow context ? is illegal and : and - must not be followed with a space.
const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)), const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)),
PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank)); PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank));
const RegEx EndScalar = RegEx(':') + BlankOrBreak, const RegEx EndScalar = RegEx(':') + BlankOrBreak,
EndScalarInFlow = (RegEx(':') + BlankOrBreak) || RegEx(",?[]{}", REGEX_OR); EndScalarInFlow = (RegEx(':') + BlankOrBreak) || RegEx(",?[]{}", REGEX_OR);
const RegEx EscSingleQuote = RegEx("\'\'"); const RegEx EscSingleQuote = RegEx("\'\'");
const RegEx EscBreak = RegEx('\\') + Break; const RegEx EscBreak = RegEx('\\') + Break;
const RegEx ChompIndicator = RegEx("+-", REGEX_OR); const RegEx ChompIndicator = RegEx("+-", REGEX_OR);
const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit; const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit;
// and some functions // and some functions
std::string Escape(Stream& in); std::string Escape(Stream& in);
} }
namespace Keys namespace Keys
{ {
const char Directive = '%'; const char Directive = '%';
const char FlowSeqStart = '['; const char FlowSeqStart = '[';
const char FlowSeqEnd = ']'; const char FlowSeqEnd = ']';
const char FlowMapStart = '{'; const char FlowMapStart = '{';
const char FlowMapEnd = '}'; const char FlowMapEnd = '}';
const char FlowEntry = ','; const char FlowEntry = ',';
const char Alias = '*'; const char Alias = '*';
const char Anchor = '&'; const char Anchor = '&';
const char Tag = '!'; const char Tag = '!';
const char LiteralScalar = '|'; const char LiteralScalar = '|';
const char FoldedScalar = '>'; const char FoldedScalar = '>';
} }
} }
+108 -108
View File
@@ -1,108 +1,108 @@
#include "crt.h" #include "crt.h"
#include "node.h" #include "node.h"
#include "exceptions.h" #include "exceptions.h"
#include "iterpriv.h" #include "iterpriv.h"
namespace YAML namespace YAML
{ {
Iterator::Iterator(): m_pData(0) Iterator::Iterator(): m_pData(0)
{ {
m_pData = new IterPriv; m_pData = new IterPriv;
} }
Iterator::Iterator(IterPriv *pData): m_pData(pData) Iterator::Iterator(IterPriv *pData): m_pData(pData)
{ {
} }
Iterator::Iterator(const Iterator& rhs): m_pData(0) Iterator::Iterator(const Iterator& rhs): m_pData(0)
{ {
m_pData = new IterPriv(*rhs.m_pData); m_pData = new IterPriv(*rhs.m_pData);
} }
Iterator& Iterator::operator = (const Iterator& rhs) Iterator& Iterator::operator = (const Iterator& rhs)
{ {
if(this == &rhs) if(this == &rhs)
return *this; return *this;
delete m_pData; delete m_pData;
m_pData = new IterPriv(*rhs.m_pData); m_pData = new IterPriv(*rhs.m_pData);
return *this; return *this;
} }
Iterator::~Iterator() Iterator::~Iterator()
{ {
delete m_pData; delete m_pData;
} }
Iterator& Iterator::operator ++ () Iterator& Iterator::operator ++ ()
{ {
if(m_pData->type == IterPriv::IT_SEQ) if(m_pData->type == IterPriv::IT_SEQ)
++m_pData->seqIter; ++m_pData->seqIter;
else if(m_pData->type == IterPriv::IT_MAP) else if(m_pData->type == IterPriv::IT_MAP)
++m_pData->mapIter; ++m_pData->mapIter;
return *this; return *this;
} }
Iterator Iterator::operator ++ (int) Iterator Iterator::operator ++ (int)
{ {
Iterator temp = *this; Iterator temp = *this;
if(m_pData->type == IterPriv::IT_SEQ) if(m_pData->type == IterPriv::IT_SEQ)
++m_pData->seqIter; ++m_pData->seqIter;
else if(m_pData->type == IterPriv::IT_MAP) else if(m_pData->type == IterPriv::IT_MAP)
++m_pData->mapIter; ++m_pData->mapIter;
return temp; return temp;
} }
const Node& Iterator::operator * () const const Node& Iterator::operator * () const
{ {
if(m_pData->type == IterPriv::IT_SEQ) if(m_pData->type == IterPriv::IT_SEQ)
return **m_pData->seqIter; return **m_pData->seqIter;
throw BadDereference(); throw BadDereference();
} }
const Node *Iterator::operator -> () const const Node *Iterator::operator -> () const
{ {
if(m_pData->type == IterPriv::IT_SEQ) if(m_pData->type == IterPriv::IT_SEQ)
return *m_pData->seqIter; return *m_pData->seqIter;
throw BadDereference(); throw BadDereference();
} }
const Node& Iterator::first() const const Node& Iterator::first() const
{ {
if(m_pData->type == IterPriv::IT_MAP) if(m_pData->type == IterPriv::IT_MAP)
return *m_pData->mapIter->first; return *m_pData->mapIter->first;
throw BadDereference(); throw BadDereference();
} }
const Node& Iterator::second() const const Node& Iterator::second() const
{ {
if(m_pData->type == IterPriv::IT_MAP) if(m_pData->type == IterPriv::IT_MAP)
return *m_pData->mapIter->second; return *m_pData->mapIter->second;
throw BadDereference(); throw BadDereference();
} }
bool operator == (const Iterator& it, const Iterator& jt) bool operator == (const Iterator& it, const Iterator& jt)
{ {
if(it.m_pData->type != jt.m_pData->type) if(it.m_pData->type != jt.m_pData->type)
return false; return false;
if(it.m_pData->type == IterPriv::IT_SEQ) if(it.m_pData->type == IterPriv::IT_SEQ)
return it.m_pData->seqIter == jt.m_pData->seqIter; return it.m_pData->seqIter == jt.m_pData->seqIter;
else if(it.m_pData->type == IterPriv::IT_MAP) else if(it.m_pData->type == IterPriv::IT_MAP)
return it.m_pData->mapIter == jt.m_pData->mapIter; return it.m_pData->mapIter == jt.m_pData->mapIter;
return true; return true;
} }
bool operator != (const Iterator& it, const Iterator& jt) bool operator != (const Iterator& it, const Iterator& jt)
{ {
return !(it == jt); return !(it == jt);
} }
} }
+25 -25
View File
@@ -1,25 +1,25 @@
#pragma once #pragma once
#include "ltnode.h" #include "ltnode.h"
#include <vector> #include <vector>
#include <map> #include <map>
namespace YAML namespace YAML
{ {
class Node; class Node;
// IterPriv // IterPriv
// . The implementation for iterators - essentially a union of sequence and map iterators. // . The implementation for iterators - essentially a union of sequence and map iterators.
struct IterPriv struct IterPriv
{ {
IterPriv(): type(IT_NONE) {} IterPriv(): type(IT_NONE) {}
IterPriv(std::vector <Node *>::const_iterator it): type(IT_SEQ), seqIter(it) {} IterPriv(std::vector <Node *>::const_iterator it): type(IT_SEQ), seqIter(it) {}
IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): type(IT_MAP), mapIter(it) {} IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): type(IT_MAP), mapIter(it) {}
enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP }; enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
ITER_TYPE type; ITER_TYPE type;
std::vector <Node *>::const_iterator seqIter; std::vector <Node *>::const_iterator seqIter;
std::map <Node *, Node *, ltnode>::const_iterator mapIter; std::map <Node *, Node *, ltnode>::const_iterator mapIter;
}; };
} }
+10 -10
View File
@@ -1,10 +1,10 @@
#pragma once #pragma once
namespace YAML namespace YAML
{ {
class Node; class Node;
struct ltnode { struct ltnode {
bool operator()(const Node *pNode1, const Node *pNode2) const; bool operator()(const Node *pNode1, const Node *pNode2) const;
}; };
} }
+196 -196
View File
@@ -1,196 +1,196 @@
#include "crt.h" #include "crt.h"
#include "map.h" #include "map.h"
#include "node.h" #include "node.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h" #include "exceptions.h"
#include <iostream> #include <iostream>
namespace YAML namespace YAML
{ {
Map::Map() Map::Map()
{ {
} }
Map::~Map() Map::~Map()
{ {
Clear(); Clear();
} }
void Map::Clear() void Map::Clear()
{ {
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) { for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
delete it->first; delete it->first;
delete it->second; delete it->second;
} }
m_data.clear(); m_data.clear();
} }
bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
{ {
it = m_data.begin(); it = m_data.begin();
return true; return true;
} }
bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const
{ {
it = m_data.end(); it = m_data.end();
return true; return true;
} }
void Map::Parse(Scanner *pScanner, const ParserState& state) void Map::Parse(Scanner *pScanner, const ParserState& state)
{ {
Clear(); Clear();
// split based on start token // split based on start token
switch(pScanner->peek().type) { switch(pScanner->peek().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;
} }
} }
void Map::ParseBlock(Scanner *pScanner, const ParserState& state) void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->pop(); pScanner->pop();
while(1) { while(1) {
if(pScanner->empty()) if(pScanner->empty())
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP); throw ParserException(-1, -1, ErrorMsg::END_OF_MAP);
Token token = pScanner->peek(); Token token = pScanner->peek();
if(token.type != TT_KEY && token.type != TT_BLOCK_END) if(token.type != TT_KEY && token.type != TT_BLOCK_END)
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP); throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP);
pScanner->pop(); pScanner->pop();
if(token.type == TT_BLOCK_END) if(token.type == TT_BLOCK_END)
break; break;
Node *pKey = new Node; Node *pKey = new Node;
Node *pValue = new Node; Node *pValue = new Node;
try { try {
// grab key // grab key
pKey->Parse(pScanner, state); pKey->Parse(pScanner, state);
// now grab value (optional) // now grab value (optional)
if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) { if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) {
pScanner->pop(); pScanner->pop();
pValue->Parse(pScanner, state); pValue->Parse(pScanner, state);
} }
m_data[pKey] = pValue; m_data[pKey] = pValue;
} catch(Exception& e) { } catch(Exception& e) {
delete pKey; delete pKey;
delete pValue; delete pValue;
throw e; throw e;
} }
} }
} }
void Map::ParseFlow(Scanner *pScanner, const ParserState& state) void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
{ {
// eat start token // eat start token
pScanner->pop(); pScanner->pop();
while(1) { while(1) {
if(pScanner->empty()) if(pScanner->empty())
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW);
Token& token = pScanner->peek(); Token& token = pScanner->peek();
// first check for end // first check for end
if(token.type == TT_FLOW_MAP_END) { if(token.type == TT_FLOW_MAP_END) {
pScanner->pop(); pScanner->pop();
break; break;
} }
// now it better be a key // now it better be a key
if(token.type != TT_KEY) if(token.type != TT_KEY)
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW);
pScanner->pop(); pScanner->pop();
Node *pKey = new Node; Node *pKey = new Node;
Node *pValue = new Node; Node *pValue = new Node;
try { try {
// grab key // grab key
pKey->Parse(pScanner, state); pKey->Parse(pScanner, state);
// now grab value (optional) // now grab value (optional)
if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) { if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) {
pScanner->pop(); pScanner->pop();
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)
Token& nextToken = pScanner->peek(); Token& nextToken = pScanner->peek();
if(nextToken.type == TT_FLOW_ENTRY) if(nextToken.type == TT_FLOW_ENTRY)
pScanner->pop(); pScanner->pop();
else if(nextToken.type != TT_FLOW_MAP_END) else if(nextToken.type != TT_FLOW_MAP_END)
throw ParserException(nextToken.line, nextToken.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) {
// clean up and rethrow // clean up and rethrow
delete pKey; delete pKey;
delete pValue; delete pValue;
throw e; throw e;
} }
} }
} }
void Map::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) void Map::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
{ {
if(startedLine && !onlyOneCharOnLine) if(startedLine && !onlyOneCharOnLine)
out << "\n"; out << "\n";
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) { for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
if((startedLine && !onlyOneCharOnLine) || it != m_data.begin()) { if((startedLine && !onlyOneCharOnLine) || it != m_data.begin()) {
for(int i=0;i<indent;i++) for(int i=0;i<indent;i++)
out << " "; out << " ";
} }
out << "? "; out << "? ";
it->first->Write(out, indent + 1, true, it!= m_data.begin() || !startedLine || onlyOneCharOnLine); it->first->Write(out, indent + 1, true, it!= m_data.begin() || !startedLine || onlyOneCharOnLine);
for(int i=0;i<indent;i++) for(int i=0;i<indent;i++)
out << " "; out << " ";
out << ": "; out << ": ";
it->second->Write(out, indent + 1, true, true); it->second->Write(out, indent + 1, true, true);
} }
if(m_data.empty()) if(m_data.empty())
out << "\n"; out << "\n";
} }
int Map::Compare(Content *pContent) int Map::Compare(Content *pContent)
{ {
return -pContent->Compare(this); return -pContent->Compare(this);
} }
int Map::Compare(Map *pMap) int Map::Compare(Map *pMap)
{ {
node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin(); node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin();
while(1) { while(1) {
if(it == m_data.end()) { if(it == m_data.end()) {
if(jt == pMap->m_data.end()) if(jt == pMap->m_data.end())
return 0; return 0;
else else
return -1; return -1;
} }
if(jt == pMap->m_data.end()) if(jt == pMap->m_data.end())
return 1; return 1;
int cmp = it->first->Compare(*jt->first); int cmp = it->first->Compare(*jt->first);
if(cmp != 0) if(cmp != 0)
return cmp; return cmp;
cmp = it->second->Compare(*jt->second); cmp = it->second->Compare(*jt->second);
if(cmp != 0) if(cmp != 0)
return cmp; return cmp;
} }
return 0; return 0;
} }
} }
+38 -38
View File
@@ -1,38 +1,38 @@
#pragma once #pragma once
#include "content.h" #include "content.h"
#include <map> #include <map>
namespace YAML namespace YAML
{ {
class Node; class Node;
class Map: public Content class Map: public Content
{ {
public: public:
Map(); Map();
virtual ~Map(); virtual ~Map();
void Clear(); void Clear();
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const; virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const; virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
virtual void Parse(Scanner *pScanner, const ParserState& state); virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine); virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine);
virtual bool IsMap() const { return true; } virtual bool IsMap() const { return true; }
// ordering // ordering
virtual int Compare(Content *pContent); virtual int Compare(Content *pContent);
virtual int Compare(Scalar *pScalar) { return 1; } virtual int Compare(Scalar *pScalar) { return 1; }
virtual int Compare(Sequence *pSeq) { return 1; } virtual int Compare(Sequence *pSeq) { return 1; }
virtual int Compare(Map *pMap); virtual int Compare(Map *pMap);
private: private:
void ParseBlock(Scanner *pScanner, const ParserState& state); void ParseBlock(Scanner *pScanner, const ParserState& state);
void ParseFlow(Scanner *pScanner, const ParserState& state); void ParseFlow(Scanner *pScanner, const ParserState& state);
protected: protected:
typedef std::map <Node *, Node *, ltnode> node_map; typedef std::map <Node *, Node *, ltnode> node_map;
node_map m_data; node_map m_data;
}; };
} }
+317 -317
View File
File diff suppressed because it is too large Load Diff
+133 -133
View File
@@ -1,133 +1,133 @@
#include "crt.h" #include "crt.h"
#include "parser.h" #include "parser.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h" #include "exceptions.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML
{ {
Parser::Parser(std::istream& in): m_pScanner(0) Parser::Parser(std::istream& in): m_pScanner(0)
{ {
Load(in); Load(in);
} }
Parser::~Parser() Parser::~Parser()
{ {
delete m_pScanner; delete m_pScanner;
} }
Parser::operator bool() const Parser::operator bool() const
{ {
return !m_pScanner->empty(); return !m_pScanner->empty();
} }
void Parser::Load(std::istream& in) void Parser::Load(std::istream& in)
{ {
delete m_pScanner; delete m_pScanner;
m_pScanner = new Scanner(in); m_pScanner = new Scanner(in);
m_state.Reset(); m_state.Reset();
} }
// GetNextDocument // GetNextDocument
// . Reads the next document in the queue (of tokens). // . Reads the next document in the queue (of tokens).
// . Throws a ParserException on error. // . Throws a ParserException on error.
void Parser::GetNextDocument(Node& document) void Parser::GetNextDocument(Node& document)
{ {
// clear node // clear node
document.Clear(); document.Clear();
// first read directives // first read directives
ParseDirectives(); ParseDirectives();
// we better have some tokens in the queue // we better have some tokens in the queue
if(m_pScanner->empty()) if(m_pScanner->empty())
return; return;
// first eat doc start (optional) // first eat doc start (optional)
if(m_pScanner->peek().type == TT_DOC_START) if(m_pScanner->peek().type == TT_DOC_START)
m_pScanner->pop(); m_pScanner->pop();
// 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->empty() && m_pScanner->peek().type == TT_DOC_END) while(!m_pScanner->empty() && m_pScanner->peek().type == TT_DOC_END)
m_pScanner->pop(); m_pScanner->pop();
} }
// ParseDirectives // ParseDirectives
// . Reads any directives that are next in the queue. // . Reads any directives that are next in the queue.
void Parser::ParseDirectives() void Parser::ParseDirectives()
{ {
bool readDirective = false; bool readDirective = false;
while(1) { while(1) {
if(m_pScanner->empty()) if(m_pScanner->empty())
break; break;
Token& token = m_pScanner->peek(); Token& token = m_pScanner->peek();
if(token.type != TT_DIRECTIVE) 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;
// but if any directives are specific, then we reset them // but if any directives are specific, then we reset them
if(!readDirective) if(!readDirective)
m_state.Reset(); m_state.Reset();
readDirective = true; readDirective = true;
HandleDirective(&token); HandleDirective(&token);
m_pScanner->pop(); m_pScanner->pop();
} }
} }
void Parser::HandleDirective(Token *pToken) void Parser::HandleDirective(Token *pToken)
{ {
if(pToken->value == "YAML") if(pToken->value == "YAML")
HandleYamlDirective(pToken); HandleYamlDirective(pToken);
else if(pToken->value == "TAG") else if(pToken->value == "TAG")
HandleTagDirective(pToken); 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(Token *pToken) void Parser::HandleYamlDirective(Token *pToken)
{ {
if(pToken->params.size() != 1) if(pToken->params.size() != 1)
throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_DIRECTIVE_ARGS); throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_DIRECTIVE_ARGS);
std::stringstream str(pToken->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 || str.peek() != EOF) if(!str || str.peek() != EOF)
throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_VERSION + pToken->params[0]); throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_VERSION + pToken->params[0]);
if(m_state.version.major > 1) if(m_state.version.major > 1)
throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_MAJOR_VERSION); throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_MAJOR_VERSION);
// TODO: warning on major == 1, minor > 2? // TODO: warning on major == 1, minor > 2?
} }
// HandleTagDirective // HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file. // . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
void Parser::HandleTagDirective(Token *pToken) void Parser::HandleTagDirective(Token *pToken)
{ {
if(pToken->params.size() != 2) if(pToken->params.size() != 2)
throw ParserException(pToken->line, pToken->column, ErrorMsg::TAG_DIRECTIVE_ARGS); throw ParserException(pToken->line, pToken->column, ErrorMsg::TAG_DIRECTIVE_ARGS);
std::string handle = pToken->params[0], prefix = pToken->params[1]; std::string handle = pToken->params[0], prefix = pToken->params[1];
m_state.tags[handle] = prefix; m_state.tags[handle] = prefix;
} }
void Parser::PrintTokens(std::ostream& out) void Parser::PrintTokens(std::ostream& out)
{ {
while(1) { while(1) {
if(m_pScanner->empty()) if(m_pScanner->empty())
break; break;
out << m_pScanner->peek() << "\n"; out << m_pScanner->peek() << "\n";
m_pScanner->pop(); m_pScanner->pop();
} }
} }
} }
+26 -26
View File
@@ -1,26 +1,26 @@
#include "crt.h" #include "crt.h"
#include "parserstate.h" #include "parserstate.h"
namespace YAML namespace YAML
{ {
void ParserState::Reset() void ParserState::Reset()
{ {
// version // version
version.major = 1; version.major = 1;
version.minor = 2; version.minor = 2;
// and tags // and tags
tags.clear(); tags.clear();
tags["!"] = "!"; tags["!"] = "!";
tags["!!"] = "tag:yaml.org,2002:"; tags["!!"] = "tag:yaml.org,2002:";
} }
std::string ParserState::TranslateTag(const std::string& handle) const std::string ParserState::TranslateTag(const std::string& handle) const
{ {
std::map <std::string, std::string>::const_iterator it = tags.find(handle); std::map <std::string, std::string>::const_iterator it = tags.find(handle);
if(it == tags.end()) if(it == tags.end())
return handle; return handle;
return it->second; return it->second;
} }
} }
+306 -306
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More