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
43ea59a4
Commit
43ea59a4
authored
Jun 28, 2008
by
Jesse Beder
Browse files
Added folded and literal scalars.
parent
01ef70a6
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
153 additions
and
23 deletions
+153
-23
exceptions.h
exceptions.h
+2
-0
exp.h
exp.h
+3
-0
scanner.cpp
scanner.cpp
+4
-7
scanner.h
scanner.h
+6
-1
scantoken.cpp
scantoken.cpp
+134
-11
test.yaml
test.yaml
+3
-4
token.h
token.h
+1
-0
No files found.
exceptions.h
View file @
43ea59a4
...
@@ -15,6 +15,8 @@ namespace YAML
...
@@ -15,6 +15,8 @@ namespace YAML
class
DocIndicatorInQuote
:
public
Exception
{};
class
DocIndicatorInQuote
:
public
Exception
{};
class
EOFInQuote
:
public
Exception
{};
class
EOFInQuote
:
public
Exception
{};
class
RequiredSimpleKeyNotFound
:
public
Exception
{};
class
RequiredSimpleKeyNotFound
:
public
Exception
{};
class
ZeroIndentationInBlockScalar
:
public
Exception
{};
class
UnexpectedCharacterInBlockScalar
:
public
Exception
{};
class
UnknownEscapeSequence
:
public
Exception
{
class
UnknownEscapeSequence
:
public
Exception
{
public:
public:
...
...
exp.h
View file @
43ea59a4
...
@@ -43,6 +43,9 @@ namespace YAML
...
@@ -43,6 +43,9 @@ namespace YAML
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
Chomp
=
(
ChompIndicator
+
Digit
)
||
(
Digit
+
ChompIndicator
)
||
ChompIndicator
||
Digit
;
// and some functions
// and some functions
std
::
string
Escape
(
std
::
istream
&
in
,
int
&
length
);
std
::
string
Escape
(
std
::
istream
&
in
,
int
&
length
);
}
}
...
...
scanner.cpp
View file @
43ea59a4
...
@@ -31,8 +31,8 @@ namespace YAML
...
@@ -31,8 +31,8 @@ namespace YAML
// . Extracts a character from the stream and updates our position
// . Extracts a character from the stream and updates our position
char
Scanner
::
GetChar
()
char
Scanner
::
GetChar
()
{
{
m_column
++
;
char
ch
=
INPUT
.
get
();
char
ch
=
INPUT
.
get
();
m_column
++
;
if
(
ch
==
'\n'
)
{
if
(
ch
==
'\n'
)
{
m_column
=
0
;
m_column
=
0
;
m_line
++
;
m_line
++
;
...
@@ -201,12 +201,9 @@ namespace YAML
...
@@ -201,12 +201,9 @@ namespace YAML
// TODO: alias/anchor/tag
// TODO: alias/anchor/tag
// TODO: special scalars
// special scalars
if
(
INPUT
.
peek
()
==
Keys
::
LiteralScalar
&&
m_flowLevel
==
0
)
if
(
m_flowLevel
==
0
&&
(
INPUT
.
peek
()
==
Keys
::
LiteralScalar
||
INPUT
.
peek
()
==
Keys
::
FoldedScalar
))
return
;
return
ScanAndEnqueue
(
new
BlockScalarToken
);
if
(
INPUT
.
peek
()
==
Keys
::
FoldedScalar
&&
m_flowLevel
==
0
)
return
;
if
(
INPUT
.
peek
()
==
'\''
||
INPUT
.
peek
()
==
'\"'
)
if
(
INPUT
.
peek
()
==
'\''
||
INPUT
.
peek
()
==
'\"'
)
return
ScanAndEnqueue
(
new
QuotedScalarToken
);
return
ScanAndEnqueue
(
new
QuotedScalarToken
);
...
...
scanner.h
View file @
43ea59a4
...
@@ -45,15 +45,20 @@ namespace YAML
...
@@ -45,15 +45,20 @@ namespace YAML
bool
IsValue
();
bool
IsValue
();
bool
IsPlainScalar
();
bool
IsPlainScalar
();
void
GetBlockIndentation
(
int
&
indent
,
std
::
string
&
breaks
);
struct
WhitespaceInfo
{
struct
WhitespaceInfo
{
WhitespaceInfo
();
WhitespaceInfo
();
void
SetChompers
(
char
ch
);
void
AddBlank
(
char
ch
);
void
AddBlank
(
char
ch
);
void
AddBreak
(
const
std
::
string
&
line
);
void
AddBreak
(
const
std
::
string
&
line
);
std
::
string
Join
();
std
::
string
Join
(
bool
lastline
=
false
);
bool
leadingBlanks
;
bool
leadingBlanks
;
bool
fold
;
std
::
string
whitespace
,
leadingBreaks
,
trailingBreaks
;
std
::
string
whitespace
,
leadingBreaks
,
trailingBreaks
;
int
chomp
,
increment
;
};
};
struct
SimpleKey
{
struct
SimpleKey
{
...
...
scantoken.cpp
View file @
43ea59a4
...
@@ -358,13 +358,137 @@ namespace YAML
...
@@ -358,13 +358,137 @@ namespace YAML
return
pToken
;
return
pToken
;
}
}
// BlockScalarToken
template
<
>
BlockScalarToken
*
Scanner
::
ScanToken
(
BlockScalarToken
*
pToken
)
{
// simple keys always ok after block scalars (since we're gonna start a new line anyways)
m_simpleKeyAllowed
=
true
;
WhitespaceInfo
info
;
// eat block indicator ('|' or '>')
char
indicator
=
GetChar
();
info
.
fold
=
(
indicator
==
Keys
::
FoldedScalar
);
// eat chomping/indentation indicators
int
n
=
Exp
::
Chomp
.
Match
(
INPUT
);
for
(
int
i
=
0
;
i
<
n
;
i
++
)
info
.
SetChompers
(
GetChar
());
// first eat whitespace
while
(
Exp
::
Blank
.
Matches
(
INPUT
))
Eat
(
1
);
// and comments to the end of the line
if
(
Exp
::
Comment
.
Matches
(
INPUT
))
while
(
INPUT
&&
!
Exp
::
Break
.
Matches
(
INPUT
))
Eat
(
1
);
// if it's not a line break, then we ran into a bad character inline
if
(
INPUT
&&
!
Exp
::
Break
.
Matches
(
INPUT
))
throw
UnexpectedCharacterInBlockScalar
();
// and eat that baby
EatLineBreak
();
// set the initial indentation
int
indent
=
info
.
increment
;
if
(
info
.
increment
&&
m_indents
.
top
()
>=
0
)
indent
+=
m_indents
.
top
();
// finally, grab that scalar
std
::
string
scalar
;
while
(
INPUT
)
{
// initialize indentation
GetBlockIndentation
(
indent
,
info
.
trailingBreaks
);
// are we done with this guy (i.e. at a lower indentation?)
if
(
m_column
!=
indent
)
break
;
bool
trailingBlank
=
Exp
::
Blank
.
Matches
(
INPUT
);
scalar
+=
info
.
Join
();
bool
leadingBlank
=
Exp
::
Blank
.
Matches
(
INPUT
);
// now eat and save the line
while
(
INPUT
.
peek
()
!=
EOF
&&
!
Exp
::
Break
.
Matches
(
INPUT
))
scalar
+=
GetChar
();
// we know it's a line break; see how many characters to read
int
n
=
Exp
::
Break
.
Match
(
INPUT
);
std
::
string
line
=
GetChar
(
n
);
info
.
AddBreak
(
line
);
}
// one last whitespace join (with chompers this time)
scalar
+=
info
.
Join
(
true
);
// finally set the scalar
pToken
->
value
=
scalar
;
return
pToken
;
}
// GetBlockIndentation
// . Helper to scanning a block scalar.
// . Eats leading *indentation* zeros (i.e., those that come before 'indent'),
// and updates 'indent' (if it hasn't been set yet).
void
Scanner
::
GetBlockIndentation
(
int
&
indent
,
std
::
string
&
breaks
)
{
int
maxIndent
=
0
;
while
(
1
)
{
// eat as many indentation spaces as we can
while
((
indent
==
0
||
m_column
<
indent
)
&&
INPUT
.
peek
()
==
' '
)
Eat
(
1
);
if
(
m_column
>
maxIndent
)
maxIndent
=
m_column
;
// do we need more indentation, but we've got a tab?
if
((
indent
==
0
||
m_column
<
indent
)
&&
INPUT
.
peek
()
==
'\t'
)
throw
IllegalTabInScalar
();
// TODO: are literal scalar lines allowed to have tabs here?
// is this a non-empty line?
if
(
!
Exp
::
Break
.
Matches
(
INPUT
))
break
;
// otherwise, eat the line break and move on
int
n
=
Exp
::
Break
.
Match
(
INPUT
);
breaks
+=
GetChar
(
n
);
}
// finally, set the indentation
if
(
indent
==
0
)
{
indent
=
maxIndent
;
if
(
indent
<
m_indents
.
top
()
+
1
)
indent
=
m_indents
.
top
()
+
1
;
if
(
indent
<
1
)
indent
=
1
;
}
}
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// WhitespaceInfo stuff
// WhitespaceInfo stuff
Scanner
::
WhitespaceInfo
::
WhitespaceInfo
()
:
leadingBlanks
(
false
)
Scanner
::
WhitespaceInfo
::
WhitespaceInfo
()
:
leadingBlanks
(
false
)
,
fold
(
true
),
chomp
(
0
),
increment
(
0
)
{
{
}
}
void
Scanner
::
WhitespaceInfo
::
SetChompers
(
char
ch
)
{
if
(
ch
==
'+'
)
chomp
=
1
;
else
if
(
ch
==
'-'
)
chomp
=
-
1
;
else
if
(
Exp
::
Digit
.
Matches
(
ch
))
{
increment
=
ch
-
'0'
;
if
(
increment
==
0
)
throw
ZeroIndentationInBlockScalar
();
}
}
void
Scanner
::
WhitespaceInfo
::
AddBlank
(
char
ch
)
void
Scanner
::
WhitespaceInfo
::
AddBlank
(
char
ch
)
{
{
if
(
!
leadingBlanks
)
if
(
!
leadingBlanks
)
...
@@ -382,20 +506,19 @@ namespace YAML
...
@@ -382,20 +506,19 @@ namespace YAML
trailingBreaks
+=
line
;
trailingBreaks
+=
line
;
}
}
std
::
string
Scanner
::
WhitespaceInfo
::
Join
()
std
::
string
Scanner
::
WhitespaceInfo
::
Join
(
bool
lastLine
)
{
{
std
::
string
ret
;
std
::
string
ret
;
if
(
leadingBlanks
)
{
if
(
leadingBlanks
)
{
if
(
Exp
::
Break
.
Matches
(
leadingBreaks
))
{
// fold line break?
// fold line break?
if
(
fold
&&
Exp
::
Break
.
Matches
(
leadingBreaks
)
&&
trailingBreaks
.
empty
()
&&
!
lastLine
)
if
(
trailingBreaks
.
empty
())
ret
=
" "
;
ret
=
" "
;
else
if
(
!
lastLine
||
chomp
!=
-
1
)
else
ret
=
leadingBreaks
;
ret
=
trailingBreaks
;
}
else
{
if
(
!
lastLine
||
chomp
==
1
)
ret
=
leadingBreaks
+
trailingBreaks
;
ret
+=
trailingBreaks
;
}
leadingBlanks
=
false
;
leadingBlanks
=
false
;
leadingBreaks
=
""
;
leadingBreaks
=
""
;
...
...
test.yaml
View file @
43ea59a4
{
-
sun
:
yellow
a simple key
:
a value
,
-
?
earth
:
blue
?
a complex key
:
another value
,
:
moon
:
white
}
\ No newline at end of file
\ No newline at end of file
token.h
View file @
43ea59a4
...
@@ -39,4 +39,5 @@ namespace YAML
...
@@ -39,4 +39,5 @@ namespace YAML
struct
PlainScalarToken
:
public
ScalarToken
{};
struct
PlainScalarToken
:
public
ScalarToken
{};
struct
QuotedScalarToken
:
public
ScalarToken
{};
struct
QuotedScalarToken
:
public
ScalarToken
{};
struct
BlockScalarToken
:
public
ScalarToken
{};
}
}
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