Merge pull request #168 from Herringway/appender-stacks
Use Appender for stacks merged-on-behalf-of: BBasile <BBasile@users.noreply.github.com>
This commit is contained in:
commit
2b9f4091a7
|
@ -270,7 +270,7 @@ struct Dumper
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto emitter = new Emitter(stream_, canonical_, indent_, textWidth_, lineBreak_);
|
auto emitter = Emitter(stream_, canonical_, indent_, textWidth_, lineBreak_);
|
||||||
foreach(ref event; events)
|
foreach(ref event; events)
|
||||||
{
|
{
|
||||||
emitter.emit(event);
|
emitter.emit(event);
|
||||||
|
|
|
@ -13,7 +13,6 @@ module dyaml.emitter;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
import std.ascii;
|
import std.ascii;
|
||||||
import std.container;
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.encoding;
|
import std.encoding;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
|
@ -82,7 +81,7 @@ struct Emitter
|
||||||
Encoding encoding_ = Encoding.UTF_8;
|
Encoding encoding_ = Encoding.UTF_8;
|
||||||
|
|
||||||
///Stack of states.
|
///Stack of states.
|
||||||
Array!(void function() @safe) states_;
|
Appender!(void function() @safe[]) states_;
|
||||||
///Current state.
|
///Current state.
|
||||||
//WARNING! DO NOT CALL DIRECTLY! Use callNext() instead!
|
//WARNING! DO NOT CALL DIRECTLY! Use callNext() instead!
|
||||||
void function() @safe state_;
|
void function() @safe state_;
|
||||||
|
@ -93,7 +92,7 @@ struct Emitter
|
||||||
Event event_;
|
Event event_;
|
||||||
|
|
||||||
///Stack of previous indentation levels.
|
///Stack of previous indentation levels.
|
||||||
Array!int indents_;
|
Appender!(int[]) indents_;
|
||||||
///Current indentation level.
|
///Current indentation level.
|
||||||
int indent_ = -1;
|
int indent_ = -1;
|
||||||
|
|
||||||
|
@ -197,12 +196,12 @@ struct Emitter
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///Pop and return the newest state in states_.
|
///Pop and return the newest state in states_.
|
||||||
void function() @safe popState() @trusted
|
void function() @safe popState() @safe
|
||||||
{
|
{
|
||||||
enforce(states_.length > 0,
|
enforce(states_.data.length > 0,
|
||||||
new YAMLException("Emitter: Need to pop a state but there are no states left"));
|
new YAMLException("Emitter: Need to pop a state but there are no states left"));
|
||||||
const result = states_.back;
|
const result = states_.data[$-1];
|
||||||
states_.length = states_.length - 1;
|
states_.shrinkTo(states_.data.length - 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,13 +211,13 @@ struct Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
///Pop and return the newest indent in indents_.
|
///Pop and return the newest indent in indents_.
|
||||||
int popIndent() @trusted
|
int popIndent() @safe
|
||||||
{
|
{
|
||||||
enforce(indents_.length > 0,
|
enforce(indents_.data.length > 0,
|
||||||
new YAMLException("Emitter: Need to pop an indent level but there" ~
|
new YAMLException("Emitter: Need to pop an indent level but there" ~
|
||||||
" are no indent levels left"));
|
" are no indent levels left"));
|
||||||
const result = indents_.back;
|
const result = indents_.data[$-1];
|
||||||
indents_.length = indents_.length - 1;
|
indents_.shrinkTo(indents_.data.length - 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +286,7 @@ struct Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
///Increase indentation level.
|
///Increase indentation level.
|
||||||
void increaseIndent(const Flag!"flow" flow = No.flow, const bool indentless = false) @trusted
|
void increaseIndent(const Flag!"flow" flow = No.flow, const bool indentless = false) @safe
|
||||||
{
|
{
|
||||||
indents_ ~= indent_;
|
indents_ ~= indent_;
|
||||||
if(indent_ == -1)
|
if(indent_ == -1)
|
||||||
|
|
|
@ -13,7 +13,6 @@ module dyaml.parser;
|
||||||
|
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
import std.container;
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
@ -125,16 +124,16 @@ final class Parser
|
||||||
TagDirective[] tagDirectives_;
|
TagDirective[] tagDirectives_;
|
||||||
|
|
||||||
///Stack of states.
|
///Stack of states.
|
||||||
Array!(Event delegate() @safe) states_;
|
Appender!(Event delegate() @safe[]) states_;
|
||||||
///Stack of marks used to keep track of extents of e.g. YAML collections.
|
///Stack of marks used to keep track of extents of e.g. YAML collections.
|
||||||
Array!Mark marks_;
|
Appender!(Mark[]) marks_;
|
||||||
|
|
||||||
///Current state.
|
///Current state.
|
||||||
Event delegate() @safe state_;
|
Event delegate() @safe state_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
///Construct a Parser using specified Scanner.
|
///Construct a Parser using specified Scanner.
|
||||||
this(Scanner scanner) @trusted
|
this(Scanner scanner) @safe
|
||||||
{
|
{
|
||||||
state_ = &parseStreamStart;
|
state_ = &parseStreamStart;
|
||||||
scanner_ = scanner;
|
scanner_ = scanner;
|
||||||
|
@ -216,32 +215,32 @@ final class Parser
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///Pop and return the newest state in states_.
|
///Pop and return the newest state in states_.
|
||||||
Event delegate() @safe popState() @trusted
|
Event delegate() @safe popState() @safe
|
||||||
{
|
{
|
||||||
enforce(states_.length > 0,
|
enforce(states_.data.length > 0,
|
||||||
new YAMLException("Parser: Need to pop state but no states left to pop"));
|
new YAMLException("Parser: Need to pop state but no states left to pop"));
|
||||||
const result = states_.back;
|
const result = states_.data.back;
|
||||||
states_.length = states_.length - 1;
|
states_.shrinkTo(states_.data.length - 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Pop and return the newest mark in marks_.
|
///Pop and return the newest mark in marks_.
|
||||||
Mark popMark() @trusted
|
Mark popMark() @safe
|
||||||
{
|
{
|
||||||
enforce(marks_.length > 0,
|
enforce(marks_.data.length > 0,
|
||||||
new YAMLException("Parser: Need to pop mark but no marks left to pop"));
|
new YAMLException("Parser: Need to pop mark but no marks left to pop"));
|
||||||
const result = marks_.back;
|
const result = marks_.data.back;
|
||||||
marks_.length = marks_.length - 1;
|
marks_.shrinkTo(marks_.data.length - 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a state on the stack
|
/// Push a state on the stack
|
||||||
void pushState(Event delegate() @safe state) @trusted
|
void pushState(Event delegate() @safe state) @safe
|
||||||
{
|
{
|
||||||
states_ ~= state;
|
states_ ~= state;
|
||||||
}
|
}
|
||||||
/// Push a mark on the stack
|
/// Push a mark on the stack
|
||||||
void pushMark(Mark mark) @trusted
|
void pushMark(Mark mark) @safe
|
||||||
{
|
{
|
||||||
marks_ ~= mark;
|
marks_ ~= mark;
|
||||||
}
|
}
|
||||||
|
@ -304,8 +303,8 @@ final class Parser
|
||||||
{
|
{
|
||||||
//Parse the end of the stream.
|
//Parse the end of the stream.
|
||||||
const token = scanner_.getToken();
|
const token = scanner_.getToken();
|
||||||
assert(states_.length == 0);
|
assert(states_.data.length == 0);
|
||||||
assert(marks_.length == 0);
|
assert(marks_.data.length == 0);
|
||||||
state_ = null;
|
state_ = null;
|
||||||
return streamEndEvent(token.startMark, token.endMark);
|
return streamEndEvent(token.startMark, token.endMark);
|
||||||
}
|
}
|
||||||
|
@ -671,7 +670,7 @@ final class Parser
|
||||||
if(!scanner_.checkToken(TokenID.BlockEnd))
|
if(!scanner_.checkToken(TokenID.BlockEnd))
|
||||||
{
|
{
|
||||||
const token = scanner_.peekToken();
|
const token = scanner_.peekToken();
|
||||||
throw new ParserException("While parsing a block collection", marks_.back,
|
throw new ParserException("While parsing a block collection", marks_.data.back,
|
||||||
"expected block end, but found " ~ token.idString,
|
"expected block end, but found " ~ token.idString,
|
||||||
token.startMark);
|
token.startMark);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +735,7 @@ final class Parser
|
||||||
if(!scanner_.checkToken(TokenID.BlockEnd))
|
if(!scanner_.checkToken(TokenID.BlockEnd))
|
||||||
{
|
{
|
||||||
const token = scanner_.peekToken();
|
const token = scanner_.peekToken();
|
||||||
throw new ParserException("While parsing a block mapping", marks_.back,
|
throw new ParserException("While parsing a block mapping", marks_.data.back,
|
||||||
"expected block end, but found: " ~ token.idString,
|
"expected block end, but found: " ~ token.idString,
|
||||||
token.startMark);
|
token.startMark);
|
||||||
}
|
}
|
||||||
|
@ -797,7 +796,7 @@ final class Parser
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const token = scanner_.peekToken();
|
const token = scanner_.peekToken();
|
||||||
throw new ParserException("While parsing a flow sequence", marks_.back,
|
throw new ParserException("While parsing a flow sequence", marks_.data.back,
|
||||||
"expected ',' or ']', but got: " ~
|
"expected ',' or ']', but got: " ~
|
||||||
token.idString, token.startMark);
|
token.idString, token.startMark);
|
||||||
}
|
}
|
||||||
|
@ -905,7 +904,7 @@ final class Parser
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const token = scanner_.peekToken();
|
const token = scanner_.peekToken();
|
||||||
throw new ParserException("While parsing a flow mapping", marks_.back,
|
throw new ParserException("While parsing a flow mapping", marks_.data.back,
|
||||||
"expected ',' or '}', but got: " ~
|
"expected ',' or '}', but got: " ~
|
||||||
token.idString, token.startMark);
|
token.idString, token.startMark);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import core.stdc.string;
|
||||||
|
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.array;
|
import std.array;
|
||||||
import std.container;
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.ascii : isAlphaNum, isDigit, isHexDigit;
|
import std.ascii : isAlphaNum, isDigit, isHexDigit;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
|
@ -131,7 +130,7 @@ final class Scanner
|
||||||
/// Current indentation level.
|
/// Current indentation level.
|
||||||
int indent_ = -1;
|
int indent_ = -1;
|
||||||
/// Past indentation levels. Used as a stack.
|
/// Past indentation levels. Used as a stack.
|
||||||
Array!int indents_;
|
Appender!(int[]) indents_;
|
||||||
|
|
||||||
/// Processed tokens not yet emitted. Used as a queue.
|
/// Processed tokens not yet emitted. Used as a queue.
|
||||||
Queue!Token tokens_;
|
Queue!Token tokens_;
|
||||||
|
@ -440,9 +439,9 @@ final class Scanner
|
||||||
// In block context, we may need to issue the BLOCK-END tokens.
|
// In block context, we may need to issue the BLOCK-END tokens.
|
||||||
while(indent_ > column)
|
while(indent_ > column)
|
||||||
{
|
{
|
||||||
indent_ = indents_.back;
|
indent_ = indents_.data.back;
|
||||||
assert(indents_.length);
|
assert(indents_.data.length);
|
||||||
indents_.length = indents_.length - 1;
|
indents_.shrinkTo(indents_.data.length - 1);
|
||||||
tokens_.push(blockEndToken(reader_.mark, reader_.mark));
|
tokens_.push(blockEndToken(reader_.mark, reader_.mark));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue