Added some parser exceptions.

This commit is contained in:
Jesse Beder 2008-07-02 05:00:32 +00:00
parent 901d16a96f
commit 2ccbfeff47
9 changed files with 201 additions and 30 deletions

View file

@ -6,6 +6,7 @@ namespace YAML
{ {
class Exception: public std::exception {}; class Exception: public std::exception {};
class ScannerException: public Exception {}; class ScannerException: public Exception {};
class ParserException: public Exception {};
class RepresentationException: public Exception {}; class RepresentationException: public Exception {};
// scanner exceptions // scanner exceptions
@ -40,6 +41,12 @@ namespace YAML
unsigned 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 {};

View file

@ -29,6 +29,18 @@ namespace YAML
return *this; return *this;
} }
Node::Iterator Node::Iterator::operator ++ (int)
{
Iterator temp = *this;
if(type == IT_SEQ)
++seqIter;
else if(type == IT_MAP)
++mapIter;
return temp;
}
const Node& Node::Iterator::operator * () const Node& Node::Iterator::operator * ()
{ {
if(type == IT_SEQ) if(type == IT_SEQ)

View file

@ -1,9 +1,71 @@
#include "parser.h" #include "parser.h"
#include "node.h" #include "node.h"
#include "exceptions.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
struct Vec3 {
float x, y, z;
friend std::ostream& operator << (std::ostream& out, const Vec3& v) {
out << v.x << " " << v.y << " " << v.z;
return out;
}
};
void operator >> (const YAML::Node& node, Vec3& v)
{
YAML::Node::Iterator it = node.begin();
*it >> v.x;
++it;
*it >> v.y;
++it;
*it >> v.z;
}
struct Room {
std::string name;
Vec3 pos, size;
float height;
friend std::ostream& operator << (std::ostream& out, const Room& room) {
out << "Name: " << room.name << std::endl;
out << "Pos: " << room.pos << std::endl;
out << "Size: " << room.size << std::endl;
out << "Height: " << room.height << std::endl;
return out;
}
};
void operator >> (const YAML::Node& node, Room& room)
{
node["name"] >> room.name;
node["pos"] >> room.pos;
node["size"] >> room.size;
node["height"] >> room.height;
}
struct Level {
std::vector <Room> rooms;
friend std::ostream& operator << (std::ostream& out, const Level& level) {
for(unsigned i=0;i<level.rooms.size();i++) {
out << level.rooms[i];
out << "---------------------------------------\n";
}
return out;
}
};
void operator >> (const YAML::Node& node, Level& level)
{
const YAML::Node& rooms = node["rooms"];
for(YAML::Node::Iterator it=rooms.begin();it!=rooms.end();++it) {
Room room;
*it >> room;
level.rooms.push_back(room);
}
}
int main() int main()
{ {
std::ifstream fin("test.yaml"); std::ifstream fin("test.yaml");
@ -17,16 +79,10 @@ int main()
parser.GetNextDocument(doc); parser.GetNextDocument(doc);
const YAML::Node& root = doc.GetRoot(); const YAML::Node& root = doc.GetRoot();
for(YAML::Node::Iterator it=root.begin();it!=root.end();++it) { Level level;
std::cout << "Sequence:"; root >> level;
for(YAML::Node::Iterator jt=it->begin();jt!=it->end();++jt) { std::cout << level;
int value; } catch(YAML::Exception&) {
*jt >> value;
std::cout << " " << value;
}
std::cout << std::endl;
}
} catch(YAML::Exception& e) {
std::cout << "Error parsing the yaml!\n"; std::cout << "Error parsing the yaml!\n";
} }

11
map.cpp
View file

@ -2,6 +2,7 @@
#include "node.h" #include "node.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h"
namespace YAML namespace YAML
{ {
@ -56,10 +57,10 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
break; // TODO: throw? throw MapEndNotFound();
if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END) if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END)
break; // TODO: throw? throw MapEndNotFound();
pScanner->PopNextToken(); pScanner->PopNextToken();
if(pToken->type == TT_BLOCK_END) if(pToken->type == TT_BLOCK_END)
@ -88,7 +89,7 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
break; // TODO: throw? throw MapEndNotFound();
// first check for end // first check for end
if(pToken->type == TT_FLOW_MAP_END) { if(pToken->type == TT_FLOW_MAP_END) {
@ -98,7 +99,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)
break; // TODO: throw? throw MapEndNotFound();
pScanner->PopNextToken(); pScanner->PopNextToken();
@ -120,7 +121,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)
break; // TODO: throw? throw MapEndNotFound();
} }
} }

3
node.h
View file

@ -26,6 +26,7 @@ namespace YAML
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);
Iterator& operator ++ (); Iterator& operator ++ ();
Iterator operator ++ (int);
const Node& operator * (); const Node& operator * ();
const Node *operator -> (); const Node *operator -> ();
const Node& first(); const Node& first();
@ -61,7 +62,7 @@ namespace YAML
it.first() >> t; it.first() >> t;
if(key == t) if(key == t)
return it.second(); return it.second();
} catch(InvalidScalar&) { } catch(RepresentationException&) {
} }
} }

View file

@ -1,6 +1,7 @@
#include "parser.h" #include "parser.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "exceptions.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML
@ -62,23 +63,23 @@ namespace YAML
// . 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(const std::vector <std::string>& params)
{ {
if(params.empty()) if(params.size() != 1)
return; // TODO: throw? (or throw on params.size() > 1?) throw BadYAMLDirective();
std::stringstream str(params[0]); std::stringstream str(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)
return; // TODO: throw? (or throw if there are any more characters in the stream?) throw BadYAMLDirective(); // TODO: or throw if there are any more characters in the stream?
// TODO: throw on major > 1? warning on major == 1, minor > 1? // TODO: throw on major > 1? warning on major == 1, minor > 2?
} }
void Parser::HandleTagDirective(const std::vector <std::string>& params) void Parser::HandleTagDirective(const std::vector <std::string>& params)
{ {
if(params.size() != 2) if(params.size() != 2)
return; // TODO: throw? throw BadTAGDirective();
std::string handle = params[0], prefix = params[1]; std::string handle = params[0], prefix = params[1];
m_state.tags[handle] = prefix; m_state.tags[handle] = prefix;

View file

@ -6,7 +6,7 @@ namespace YAML
{ {
// version // version
version.major = 1; version.major = 1;
version.minor = 1; version.minor = 2;
// and tags // and tags
tags.clear(); tags.clear();

View file

@ -56,10 +56,10 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
break; // TODO: throw? throw SeqEndNotFound();
if(pToken->type != TT_BLOCK_ENTRY && pToken->type != TT_BLOCK_END) if(pToken->type != TT_BLOCK_ENTRY && pToken->type != TT_BLOCK_END)
break; // TODO: throw? throw SeqEndNotFound();
pScanner->PopNextToken(); pScanner->PopNextToken();
if(pToken->type == TT_BLOCK_END) if(pToken->type == TT_BLOCK_END)
@ -99,7 +99,7 @@ namespace YAML
while(1) { while(1) {
Token *pToken = pScanner->PeekNextToken(); Token *pToken = pScanner->PeekNextToken();
if(!pToken) if(!pToken)
break; // TODO: throw? throw SeqEndNotFound();
// first check for end // first check for end
if(pToken->type == TT_FLOW_SEQ_END) { if(pToken->type == TT_FLOW_SEQ_END) {
@ -117,7 +117,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)
break; // TODO: throw? throw SeqEndNotFound();
} }
} }

View file

@ -1,4 +1,97 @@
--- ---
- [1, 2, 3] model:
- [2, 4, 6] file: data/models/compound.model
... textures: data/materials/compound
rooms:
- name: "Room #1"
pos: [0, 0, 0]
size: [1000, 1000, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [24, 24]
map: |
-----------------------
-+++++++++++++++++++++-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+---------------------
-+---------------------
-+---------------------
-+---------------------
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+++++++++++++++++++++-
-----------------------
- name: Doorway
pos: [1000, 400, 0]
size: [50, 200, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [5, 9]
map: |
-----
-+++-
-----
-----
-----
-----
-----
-+++-
-----
- name: "Room #2"
pos: [1050, 0, 0]
size: [1000, 1000, 500]
height: 500
stairtype: none
display: []
pathfinding:
tilesize: 50
size: [24, 24]
map: |
-----------------------
-+++++++++++++++++++++-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
---------------------+-
---------------------+-
---------------------+-
---------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+-------------------+-
-+++++++++++++++++++++-
-----------------------
exits:
- room1: "Room #1"
room2: "Room #2"
dir: e
pos: [400, 600]