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 ScannerException: public Exception {};
class ParserException: public Exception {};
class RepresentationException: public Exception {};
// scanner exceptions
@ -40,6 +41,12 @@ namespace YAML
unsigned value;
};
// parser exceptions
class MapEndNotFound: public ParserException {};
class SeqEndNotFound: public ParserException {};
class BadYAMLDirective: public ParserException {};
class BadTAGDirective: public ParserException {};
// representation exceptions
class InvalidScalar: public RepresentationException {};
class BadDereference: public RepresentationException {};

View file

@ -29,6 +29,18 @@ namespace YAML
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 * ()
{
if(type == IT_SEQ)

View file

@ -1,9 +1,71 @@
#include "parser.h"
#include "node.h"
#include "exceptions.h"
#include <fstream>
#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()
{
std::ifstream fin("test.yaml");
@ -17,16 +79,10 @@ int main()
parser.GetNextDocument(doc);
const YAML::Node& root = doc.GetRoot();
for(YAML::Node::Iterator it=root.begin();it!=root.end();++it) {
std::cout << "Sequence:";
for(YAML::Node::Iterator jt=it->begin();jt!=it->end();++jt) {
int value;
*jt >> value;
std::cout << " " << value;
}
std::cout << std::endl;
}
} catch(YAML::Exception& e) {
Level level;
root >> level;
std::cout << level;
} catch(YAML::Exception&) {
std::cout << "Error parsing the yaml!\n";
}

11
map.cpp
View file

@ -2,6 +2,7 @@
#include "node.h"
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
namespace YAML
{
@ -56,10 +57,10 @@ namespace YAML
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)
break; // TODO: throw?
throw MapEndNotFound();
if(pToken->type != TT_KEY && pToken->type != TT_BLOCK_END)
break; // TODO: throw?
throw MapEndNotFound();
pScanner->PopNextToken();
if(pToken->type == TT_BLOCK_END)
@ -88,7 +89,7 @@ namespace YAML
while(1) {
Token *pToken = pScanner->PeekNextToken();
if(!pToken)
break; // TODO: throw?
throw MapEndNotFound();
// first check for end
if(pToken->type == TT_FLOW_MAP_END) {
@ -98,7 +99,7 @@ namespace YAML
// now it better be a key
if(pToken->type != TT_KEY)
break; // TODO: throw?
throw MapEndNotFound();
pScanner->PopNextToken();
@ -120,7 +121,7 @@ namespace YAML
if(pToken->type == TT_FLOW_ENTRY)
pScanner->EatNextToken();
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);
Iterator& operator ++ ();
Iterator operator ++ (int);
const Node& operator * ();
const Node *operator -> ();
const Node& first();
@ -61,7 +62,7 @@ namespace YAML
it.first() >> t;
if(key == t)
return it.second();
} catch(InvalidScalar&) {
} catch(RepresentationException&) {
}
}

View file

@ -1,6 +1,7 @@
#include "parser.h"
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
#include <sstream>
namespace YAML
@ -62,23 +63,23 @@ namespace YAML
// . Should be of the form 'major.minor' (like a version number)
void Parser::HandleYamlDirective(const std::vector <std::string>& params)
{
if(params.empty())
return; // TODO: throw? (or throw on params.size() > 1?)
if(params.size() != 1)
throw BadYAMLDirective();
std::stringstream str(params[0]);
str >> m_state.version.major;
str.get();
str >> m_state.version.minor;
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)
{
if(params.size() != 2)
return; // TODO: throw?
throw BadTAGDirective();
std::string handle = params[0], prefix = params[1];
m_state.tags[handle] = prefix;

View file

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

View file

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

View file

@ -1,4 +1,97 @@
---
- [1, 2, 3]
- [2, 4, 6]
...
model:
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]