Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
yaml-cpp
Commits
121c2e57
Commit
121c2e57
authored
Jun 30, 2008
by
Jesse Beder
Browse files
Finished parsing of basic data types (scalar, sequence, map).
parent
c1966ba3
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
434 additions
and
221 deletions
+434
-221
content.h
content.h
+7
-0
document.cpp
document.cpp
+34
-0
document.h
document.h
+6
-0
main.cpp
main.cpp
+7
-3
map.cpp
map.cpp
+104
-0
map.h
map.h
+7
-0
node.cpp
node.cpp
+62
-0
node.h
node.h
+6
-0
parser.cpp
parser.cpp
+5
-15
parser.h
parser.h
+2
-3
reader.cpp
reader.cpp
+0
-21
reader.h
reader.h
+0
-21
scalar.cpp
scalar.cpp
+20
-1
scalar.h
scalar.h
+4
-1
scanner.cpp
scanner.cpp
+14
-0
scanner.h
scanner.h
+2
-0
sequence.cpp
sequence.cpp
+77
-0
sequence.h
sequence.h
+8
-0
test.yaml
test.yaml
+9
-96
yaml-reader.vcproj
yaml-reader.vcproj
+60
-60
No files found.
content.h
View file @
121c2e57
#pragma once
#include <ios>
namespace
YAML
{
class
Scanner
;
class
Content
{
public:
Content
();
virtual
~
Content
();
virtual
void
Parse
(
Scanner
*
pScanner
)
=
0
;
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
)
=
0
;
protected:
};
}
document.cpp
View file @
121c2e57
#include "document.h"
#include "node.h"
#include "token.h"
#include "scanner.h"
namespace
YAML
{
...
...
@@ -17,4 +19,36 @@ namespace YAML
delete
m_pRoot
;
m_pRoot
=
0
;
}
void
Document
::
Parse
(
Scanner
*
pScanner
)
{
Clear
();
// we better have some tokens in the queue
if
(
!
pScanner
->
PeekNextToken
())
return
;
// first eat doc start (optional)
if
(
pScanner
->
PeekNextToken
()
->
type
==
TT_DOC_START
)
pScanner
->
EatNextToken
();
// now create our root node and parse it
m_pRoot
=
new
Node
;
m_pRoot
->
Parse
(
pScanner
);
// and finally eat any doc ends we see
while
(
pScanner
->
PeekNextToken
()
&&
pScanner
->
PeekNextToken
()
->
type
==
TT_DOC_END
)
pScanner
->
EatNextToken
();
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Document
&
doc
)
{
if
(
!
doc
.
m_pRoot
)
{
out
<<
"{empty node}
\n
"
;
return
out
;
}
doc
.
m_pRoot
->
Write
(
out
,
0
);
return
out
;
}
}
document.h
View file @
121c2e57
#pragma once
#include <ios>
namespace
YAML
{
class
Node
;
class
Scanner
;
class
Document
{
...
...
@@ -11,6 +14,9 @@ namespace YAML
~
Document
();
void
Clear
();
void
Parse
(
Scanner
*
pScanner
);
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Document
&
doc
);
private:
Node
*
m_pRoot
;
...
...
main.cpp
View file @
121c2e57
#include "
read
er.h"
#include "
pars
er.h"
#include <fstream>
#include <iostream>
int
main
()
{
std
::
ifstream
fin
(
"test.yaml"
);
YAML
::
Reader
reader
(
fin
);
YAML
::
Parser
parser
(
fin
);
YAML
::
Document
doc
;
reader
.
GetNextDocument
(
doc
);
parser
.
GetNextDocument
(
doc
);
std
::
cout
<<
doc
;
getchar
();
return
0
;
}
\ No newline at end of file
map.cpp
View file @
121c2e57
#include "map.h"
#include "node.h"
#include "scanner.h"
#include "token.h"
namespace
YAML
{
...
...
@@ -14,4 +16,106 @@ namespace YAML
delete
it
->
second
;
}
}
void
Map
::
Parse
(
Scanner
*
pScanner
)
{
// grab start token
Token
*
pToken
=
pScanner
->
GetNextToken
();
switch
(
pToken
->
type
)
{
case
TT_BLOCK_MAP_START
:
ParseBlock
(
pScanner
);
break
;
case
TT_FLOW_MAP_START
:
ParseFlow
(
pScanner
);
break
;
}
delete
pToken
;
}
void
Map
::
ParseBlock
(
Scanner
*
pScanner
)
{
while
(
1
)
{
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
!
pToken
)
break
;
// TODO: throw?
if
(
pToken
->
type
!=
TT_KEY
&&
pToken
->
type
!=
TT_BLOCK_END
)
break
;
// TODO: throw?
pScanner
->
PopNextToken
();
if
(
pToken
->
type
==
TT_BLOCK_END
)
break
;
Node
*
pKey
=
new
Node
;
Node
*
pValue
=
new
Node
;
m_data
[
pKey
]
=
pValue
;
// grab key
pKey
->
Parse
(
pScanner
);
// now grab value (optional)
if
(
pScanner
->
PeekNextToken
()
&&
pScanner
->
PeekNextToken
()
->
type
==
TT_VALUE
)
{
pScanner
->
PopNextToken
();
pValue
->
Parse
(
pScanner
);
}
}
}
void
Map
::
ParseFlow
(
Scanner
*
pScanner
)
{
while
(
1
)
{
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
!
pToken
)
break
;
// TODO: throw?
// first check for end
if
(
pToken
->
type
==
TT_FLOW_MAP_END
)
{
pScanner
->
EatNextToken
();
break
;
}
// now it better be a key
if
(
pToken
->
type
!=
TT_KEY
)
break
;
// TODO: throw?
pScanner
->
PopNextToken
();
Node
*
pKey
=
new
Node
;
Node
*
pValue
=
new
Node
;
m_data
[
pKey
]
=
pValue
;
// grab key
pKey
->
Parse
(
pScanner
);
// now grab value (optional)
if
(
pScanner
->
PeekNextToken
()
&&
pScanner
->
PeekNextToken
()
->
type
==
TT_VALUE
)
{
pScanner
->
PopNextToken
();
pValue
->
Parse
(
pScanner
);
}
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
pToken
=
pScanner
->
PeekNextToken
();
if
(
pToken
->
type
==
TT_FLOW_ENTRY
)
pScanner
->
EatNextToken
();
else
if
(
pToken
->
type
!=
TT_FLOW_MAP_END
)
break
;
// TODO: throw?
}
}
void
Map
::
Write
(
std
::
ostream
&
out
,
int
indent
)
{
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
"{map}
\n
"
;
for
(
node_map
::
const_iterator
it
=
m_data
.
begin
();
it
!=
m_data
.
end
();
++
it
)
{
for
(
int
i
=
0
;
i
<
indent
+
1
;
i
++
)
out
<<
" "
;
out
<<
"{key}
\n
"
;
it
->
first
->
Write
(
out
,
indent
+
2
);
for
(
int
i
=
0
;
i
<
indent
+
1
;
i
++
)
out
<<
" "
;
out
<<
"{value}
\n
"
;
it
->
second
->
Write
(
out
,
indent
+
2
);
}
}
}
map.h
View file @
121c2e57
...
...
@@ -13,6 +13,13 @@ namespace YAML
Map
();
virtual
~
Map
();
virtual
void
Parse
(
Scanner
*
pScanner
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
);
private:
void
ParseBlock
(
Scanner
*
pScanner
);
void
ParseFlow
(
Scanner
*
pScanner
);
protected:
typedef
std
::
map
<
Node
*
,
Node
*>
node_map
;
node_map
m_data
;
...
...
node.cpp
View file @
121c2e57
#include "node.h"
#include "token.h"
#include "scanner.h"
#include "content.h"
#include "parser.h"
#include "scalar.h"
#include "sequence.h"
#include "map.h"
namespace
YAML
{
...
...
@@ -20,4 +23,63 @@ namespace YAML
delete
m_pContent
;
m_pContent
=
0
;
}
void
Node
::
Parse
(
Scanner
*
pScanner
)
{
ParseHeader
(
pScanner
);
// now split based on what kind of node we should be
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
pToken
->
type
==
TT_DOC_END
)
return
;
switch
(
pToken
->
type
)
{
case
TT_SCALAR
:
m_pContent
=
new
Scalar
;
m_pContent
->
Parse
(
pScanner
);
break
;
case
TT_FLOW_SEQ_START
:
case
TT_BLOCK_SEQ_START
:
case
TT_BLOCK_ENTRY
:
m_pContent
=
new
Sequence
;
m_pContent
->
Parse
(
pScanner
);
break
;
case
TT_FLOW_MAP_START
:
case
TT_BLOCK_MAP_START
:
m_pContent
=
new
Map
;
m_pContent
->
Parse
(
pScanner
);
}
}
// ParseHeader
// . Grabs any tag, alias, or anchor tokens and deals with them.
void
Node
::
ParseHeader
(
Scanner
*
pScanner
)
{
while
(
1
)
{
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
!
pToken
||
pToken
->
type
!=
TT_TAG
||
pToken
->
type
!=
TT_ANCHOR
||
pToken
->
type
!=
TT_ALIAS
)
break
;
pScanner
->
PopNextToken
();
switch
(
pToken
->
type
)
{
case
TT_TAG
:
break
;
case
TT_ANCHOR
:
break
;
case
TT_ALIAS
:
break
;
}
delete
pToken
;
}
}
void
Node
::
Write
(
std
::
ostream
&
out
,
int
indent
)
{
if
(
!
m_pContent
)
{
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
"{no content}
\n
"
;
}
else
m_pContent
->
Write
(
out
,
indent
);
}
}
node.h
View file @
121c2e57
...
...
@@ -10,6 +10,7 @@ namespace YAML
const
std
::
string
MapTag
=
"!!map"
;
class
Content
;
class
Scanner
;
class
Node
{
...
...
@@ -18,6 +19,11 @@ namespace YAML
~
Node
();
void
Clear
();
void
Parse
(
Scanner
*
pScanner
);
void
Write
(
std
::
ostream
&
out
,
int
indent
);
private:
void
ParseHeader
(
Scanner
*
pScanner
);
private:
std
::
string
m_tag
;
...
...
parser.cpp
View file @
121c2e57
#include "parser.h"
#include "node.h"
#include "token.h"
#include <iostream>
#include "scanner.h"
namespace
YAML
{
Parser
::
Parser
(
std
::
istream
&
in
)
:
m_
s
canner
(
in
)
Parser
::
Parser
(
std
::
istream
&
in
)
:
m_
pS
canner
(
0
)
{
m_pScanner
=
new
Scanner
(
in
);
}
Parser
::~
Parser
()
{
delete
m_pScanner
;
}
void
Parser
::
GetNextDocument
(
Document
&
document
)
{
// scan and output, for now
while
(
1
)
{
Token
*
pToken
=
m_scanner
.
GetNextToken
();
if
(
!
pToken
)
break
;
std
::
cout
<<
*
pToken
<<
std
::
endl
;
delete
pToken
;
}
getchar
();
document
.
Parse
(
m_pScanner
);
}
}
parser.h
View file @
121c2e57
#pragma once
#include <ios>
#include <string>
#include "scanner.h"
#include "document.h"
namespace
YAML
{
class
Node
;
class
Scanner
;
class
Parser
{
...
...
@@ -18,6 +17,6 @@ namespace YAML
void
GetNextDocument
(
Document
&
document
);
private:
Scanner
m_
s
canner
;
Scanner
*
m_
pS
canner
;
};
}
reader.cpp
deleted
100644 → 0
View file @
c1966ba3
#include "reader.h"
#include "scanner.h"
#include "parser.h"
namespace
YAML
{
Reader
::
Reader
(
std
::
istream
&
in
)
:
m_pParser
(
0
)
{
m_pParser
=
new
Parser
(
in
);
}
Reader
::~
Reader
()
{
delete
m_pParser
;
}
void
Reader
::
GetNextDocument
(
Document
&
document
)
{
m_pParser
->
GetNextDocument
(
document
);
}
}
reader.h
deleted
100644 → 0
View file @
c1966ba3
#pragma once
#include <ios>
#include "document.h"
namespace
YAML
{
class
Parser
;
class
Reader
{
public:
Reader
(
std
::
istream
&
in
);
~
Reader
();
void
GetNextDocument
(
Document
&
document
);
private:
Parser
*
m_pParser
;
};
}
scalar.cpp
View file @
121c2e57
#include "scalar.h"
#include "scanner.h"
#include "token.h"
namespace
YAML
{
Scalar
::
Scalar
(
const
std
::
string
&
data
)
:
m_data
(
data
)
Scalar
::
Scalar
()
{
}
Scalar
::~
Scalar
()
{
}
void
Scalar
::
Parse
(
Scanner
*
pScanner
)
{
Token
*
pToken
=
pScanner
->
GetNextToken
();
m_data
=
pToken
->
value
;
delete
pToken
;
}
void
Scalar
::
Write
(
std
::
ostream
&
out
,
int
indent
)
{
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
"{scalar}
\n
"
;
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
m_data
<<
std
::
endl
;
}
}
scalar.h
View file @
121c2e57
...
...
@@ -8,9 +8,12 @@ namespace YAML
class
Scalar
:
public
Content
{
public:
Scalar
(
const
std
::
string
&
data
);
Scalar
();
virtual
~
Scalar
();
virtual
void
Parse
(
Scanner
*
pScanner
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
);
protected:
std
::
string
m_data
;
};
...
...
scanner.cpp
View file @
121c2e57
...
...
@@ -28,6 +28,20 @@ namespace YAML
return
pToken
;
}
// PopNextToken
// . Simply removes the next token on the queue.
void
Scanner
::
PopNextToken
()
{
GetNextToken
();
}
// EatNextToken
// . Removes and deletes the next token on the queue
void
Scanner
::
EatNextToken
()
{
delete
GetNextToken
();
}
// PeekNextToken
// . Returns (but does not remove) the next token on the queue, and scans if only we need to.
Token
*
Scanner
::
PeekNextToken
()
...
...
scanner.h
View file @
121c2e57
...
...
@@ -18,6 +18,8 @@ namespace YAML
~
Scanner
();
Token
*
GetNextToken
();
void
EatNextToken
();
void
PopNextToken
();
Token
*
PeekNextToken
();
private:
...
...
sequence.cpp
View file @
121c2e57
#include "sequence.h"
#include "node.h"
#include "scanner.h"
#include "token.h"
namespace
YAML
{
...
...
@@ -13,4 +15,79 @@ namespace YAML
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
delete
m_data
[
i
];
}
void
Sequence
::
Parse
(
Scanner
*
pScanner
)
{
// grab start token
Token
*
pToken
=
pScanner
->
GetNextToken
();
switch
(
pToken
->
type
)
{
case
TT_BLOCK_SEQ_START
:
ParseBlock
(
pScanner
);
break
;
case
TT_BLOCK_ENTRY
:
ParseImplicit
(
pScanner
);
break
;
case
TT_FLOW_SEQ_START
:
ParseFlow
(
pScanner
);
break
;
}
delete
pToken
;
}
void
Sequence
::
ParseBlock
(
Scanner
*
pScanner
)
{
while
(
1
)
{
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
!
pToken
)
break
;
// TODO: throw?
if
(
pToken
->
type
!=
TT_BLOCK_ENTRY
&&
pToken
->
type
!=
TT_BLOCK_END
)
break
;
// TODO: throw?
pScanner
->
PopNextToken
();
if
(
pToken
->
type
==
TT_BLOCK_END
)
break
;
Node
*
pNode
=
new
Node
;
m_data
.
push_back
(
pNode
);
pNode
->
Parse
(
pScanner
);
}
}
void
Sequence
::
ParseImplicit
(
Scanner
*
pScanner
)
{
// TODO
}
void
Sequence
::
ParseFlow
(
Scanner
*
pScanner
)
{
while
(
1
)
{
Token
*
pToken
=
pScanner
->
PeekNextToken
();
if
(
!
pToken
)
break
;
// TODO: throw?
// first check for end
if
(
pToken
->
type
==
TT_FLOW_SEQ_END
)
{
pScanner
->
PopNextToken
();
break
;
}
// then read the node
Node
*
pNode
=
new
Node
;
m_data
.
push_back
(
pNode
);
pNode
->
Parse
(
pScanner
);
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
pToken
=
pScanner
->
PeekNextToken
();
if
(
pToken
->
type
==
TT_FLOW_ENTRY
)
pScanner
->
EatNextToken
();
else
if
(
pToken
->
type
!=
TT_FLOW_SEQ_END
)
break
;
// TODO: throw?
}
}
void
Sequence
::
Write
(
std
::
ostream
&
out
,
int
indent
)
{
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
"{sequence}
\n
"
;
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
m_data
[
i
]
->
Write
(
out
,
indent
+
1
);
}
}
sequence.h
View file @
121c2e57
...
...
@@ -13,6 +13,14 @@ namespace YAML
Sequence
();
virtual
~
Sequence
();
virtual
void
Parse
(
Scanner
*
pScanner
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
);
private:
void
ParseBlock
(
Scanner
*
pScanner
);
void
ParseImplicit
(
Scanner
*
pScanner
);
void
ParseFlow
(
Scanner
*
pScanner
);
protected:
std
::
vector
<
Node
*>
m_data
;
};
...
...
test.yaml
View file @
121c2e57
---
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
]
here's a sequence
:
- item
1
-
item
2
now an inline sequence
:
[
1
,
2
,
3
]
and here's a map
:
name
:
Jesse
age
:
23
and here's an inline map
:
{
state
:
Illinois
,
city
:
Urbana-Champaign
}
...
\ No newline at end of file
yaml-reader.vcproj
View file @
121c2e57
...
...
@@ -161,38 +161,10 @@
Filter=
"cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier=
"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=
".\content.cpp"
>
</File>
<File
RelativePath=
".\document.cpp"
>
</File>
<File
RelativePath=
".\main.cpp"
>
</File>
<File
RelativePath=
".\map.cpp"
>
</File>
<File
RelativePath=
".\node.cpp"
>
</File>
<File
RelativePath=
".\reader.cpp"
>
</File>
<File
RelativePath=
".\scalar.cpp"
>
</File>
<File
RelativePath=
".\sequence.cpp"
>
</File>
<Filter
Name=
"Scanner"
>
...
...
@@ -233,48 +205,44 @@
>
</File>
</Filter>
<Filter
Name=
"Representation"
>
<File
RelativePath=
".\content.cpp"
>
</File>
<File
RelativePath=
".\document.cpp"
>
</File>
<File
RelativePath=
".\map.cpp"
>
</File>
<File
RelativePath=
".\node.cpp"
>
</File>
<File
RelativePath=
".\scalar.cpp"
>
</File>
<File
RelativePath=
".\sequence.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name=
"Header Files"
Filter=
"h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier=
"{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=
".\content.h"
>
</File>
<File
RelativePath=
".\document.h"
>
</File>
<File
RelativePath=
".\exceptions.h"
>
</File>
<File
RelativePath=
".\map.h"
>
</File>
<File
RelativePath=
".\node.h"
>
</File>
<File
RelativePath=
".\reader.h"
>
</File>
<File
RelativePath=
".\scalar.h"
>
</File>
<File
RelativePath=
".\sequence.h"
>
</File>
<File
RelativePath=
".\token.h"
>
</File>
<Filter
Name=
"Scanner"
>
...
...
@@ -298,6 +266,10 @@
RelativePath=
".\stream.h"
>
</File>
<File
RelativePath=
".\token.h"
>
</File>
</Filter>
<Filter
Name=
"Parser"
...
...
@@ -307,6 +279,34 @@
>
</File>
</Filter>
<Filter
Name=
"Representation"
>
<File
RelativePath=
".\content.h"
>
</File>
<File
RelativePath=
".\document.h"
>
</File>
<File
RelativePath=
".\map.h"
>
</File>
<File
RelativePath=
".\node.h"
>
</File>
<File
RelativePath=
".\scalar.h"
>
</File>
<File
RelativePath=
".\sequence.h"
>
</File>
</Filter>
</Filter>
<Filter
Name=
"Resource Files"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment