Skip to content

Commit

Permalink
Rework of initialization functions; closes #30
Browse files Browse the repository at this point in the history
  • Loading branch information
lodo1995 committed Sep 7, 2016
1 parent ac10c65 commit 66ad7ea
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 110 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -6,12 +6,12 @@ matrix:
include:
- d: dmd
env: PRIMARY="true"
- d: dmd-2.071.2-b2
- d: dmd-2.071.2-b3
env: PRIMARY="false"
- d: ldc-1.1.0-beta2
env: PRIMARY="false"
allow_failures:
- d: dmd-2.071.2-b2
- d: dmd-2.071.2-b3
- d: ldc-1.1.0-beta2

script:
Expand Down
3 changes: 2 additions & 1 deletion source/random_benchmark/random_benchmark.d
Expand Up @@ -169,7 +169,8 @@ void buildOldDOM(string data)
void buildDOM(string data)
{
auto builder =
chooseParser!data
data
.parser
.cursor
.domBuilder;
builder.setSource(data);
Expand Down
2 changes: 1 addition & 1 deletion source/std/experimental/xml/appender.d
Expand Up @@ -14,7 +14,7 @@ module std.experimental.xml.appender;
/*
* Appender implementation that uses a custom allocator. Meant for internal usage.
*/
struct Appender(T, Alloc)
package struct Appender(T, Alloc)
{
import std.experimental.allocator;
import std.array;
Expand Down
53 changes: 33 additions & 20 deletions source/std/experimental/xml/cursor.d
Expand Up @@ -55,7 +55,6 @@ package struct Attribute(StringType)
}
@property void name(StringType _name)
{
import std.experimental.xml.faststrings;
this._name = _name;
auto i = _name.fastIndexOf(':');
if (i > 0)
Expand Down Expand Up @@ -87,12 +86,6 @@ package struct Attribute(StringType)
struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA, ErrorHandler = void delegate(CursorError))
if (isLowLevelParser!P)
{
/++
+ The type of input accepted by this parser,
+ i.e., the one accepted by the underlying low level parser.
+/
alias InputType = P.InputType;

/++ The type of characters in the input, as returned by the underlying low level parser. +/
alias CharacterType = P.CharacterType;

Expand All @@ -101,7 +94,7 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA, ErrorHa

private P parser;
private ElementType!P currentNode;
private bool starting, _documentEnd, nextFailed;
private bool starting, _documentEnd = true, nextFailed;
private ptrdiff_t colon;
private size_t nameEnd;
private ErrorHandler handler;
Expand Down Expand Up @@ -160,18 +153,31 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA, ErrorHa
this.handler = handler;
}

/++
+ Initializes this cursor (and the underlying low level parser) with the given input.
+/
void setSource(InputType input)
static if (needSource!P)
{
/++
+ The type of input accepted by this parser,
+ i.e., the one accepted by the underlying low level parser.
+/
alias InputType = P.InputType;

/++
+ Initializes this cursor (and the underlying low level parser) with the given input.
+/
void setSource(InputType input)
{
parser.setSource(input);
initialize();
}
}

private void initialize()
{
// reset private fields
nextFailed = false;
_documentEnd = false;
colon = colon.max;
nameEnd = 0;

parser.setSource(input);
if (!parser.empty)
{
if (parser.front.kind == XMLKind.processingInstruction &&
Expand All @@ -188,7 +194,10 @@ struct Cursor(P, Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA, ErrorHa
currentNode.content = "xml version = \"1.0\"";
}
starting = true;
_documentEnd = false;
}
else
_documentEnd = true;
}

/++ Returns whether the cursor is at the end of the document. +/
Expand Down Expand Up @@ -529,6 +538,10 @@ template cursor(Flag!"conflateCDATA" conflateCDATA = Yes.conflateCDATA)
auto cursor = Cursor!(T, conflateCDATA, EH)();
cursor.parser = parser;
cursor.handler = errorHandler;
if (!cursor.parser.empty)
{
cursor.initialize;
}
return cursor;
}
}
Expand Down Expand Up @@ -561,8 +574,7 @@ unittest
</aaa>
};

auto cursor = chooseLexer!xml.parse.cursor;
cursor.setSource(xml);
auto cursor = xml.lexer.parser.cursor;

assert(cursor.atBeginning);

Expand Down Expand Up @@ -727,7 +739,8 @@ auto children(T)(ref T cursor)
auto handler = () { assert(0, "Some problem here..."); };
auto lexer = RangeLexer!(string, typeof(handler), shared(Mallocator))(Mallocator.instance);
lexer.errorHandler = handler;
auto cursor = lexer.parse.cursor!(Yes.conflateCDATA)((){});
auto cursor = lexer.parser.cursor!(Yes.conflateCDATA)((){});
assert(cursor.documentEnd);
cursor.setSource(xml);

// <?xml encoding = "utf-8" ?>
Expand Down Expand Up @@ -963,11 +976,11 @@ unittest
};

auto cursor =
chooseLexer!xml
.parse
xml
.lexer
.parser
.cursor!(Yes.conflateCDATA)
.copyingCursor!(Yes.intern)(Mallocator.instance);
cursor.setSource(xml);

assert(cursor.enter);
auto a1 = cursor.name;
Expand Down
5 changes: 3 additions & 2 deletions source/std/experimental/xml/domimpl.d
Expand Up @@ -1294,7 +1294,7 @@ class DOMImplementation(DOMString, Alloc = shared(GCAllocator), ErrorHandler = b

void setQualifiedName(DOMString name)
{
import std.experimental.xml.faststrings;
import std.experimental.xml.faststrings : fastIndexOf;

_name = name;
ptrdiff_t i = name.fastIndexOf(':');
Expand Down Expand Up @@ -2514,7 +2514,8 @@ unittest
}";

auto builder =
chooseParser!xml
xml
.parser
.cursor
.domBuilder;

Expand Down
5 changes: 3 additions & 2 deletions source/std/experimental/xml/domparser.d
Expand Up @@ -241,8 +241,9 @@ unittest
};

auto builder =
chooseLexer!xml
.parse
xml
.lexer
.parser
.cursor
.copyingCursor
.domBuilder(new DOMImplType());
Expand Down
3 changes: 2 additions & 1 deletion source/std/experimental/xml/dtd.d
Expand Up @@ -359,7 +359,8 @@ unittest
};

auto cursor =
chooseParser!xml
xml
.parser
.cursor
.dtdChecker;

Expand Down
2 changes: 1 addition & 1 deletion source/std/experimental/xml/faststrings.d
Expand Up @@ -15,7 +15,7 @@
module std.experimental.xml.faststrings;

/++ Compares for equality; input slices must have equal length. +/
bool fastEqual(T, S)(T[] t, S[] s) pure @nogc nothrow
package bool fastEqual(T, S)(T[] t, S[] s) pure @nogc nothrow
in
{
assert(t.length == s.length);
Expand Down
33 changes: 17 additions & 16 deletions source/std/experimental/xml/interfaces.d
Expand Up @@ -134,16 +134,13 @@ template isLexer(L)
(inout int = 0)
{
alias C = L.CharacterType;
alias T = L.InputType;

L lexer;
T source;
char c;
bool b;
string s;
C[] cs;

lexer.setSource(source);
b = lexer.empty;
lexer.start();
cs = lexer.get();
Expand Down Expand Up @@ -277,16 +274,7 @@ enum XMLKind
template isLowLevelParser(P)
{
enum bool isLowLevelParser = isInputRange!P && is(typeof(ElementType!P.kind) == XMLKind)
&& is(typeof(ElementType!P.content) == P.CharacterType[]) && is(typeof(
(inout int = 0)
{
alias InputType = P.InputType;

P parser;
InputType input;

parser.setSource(input);
}));
&& is(typeof(ElementType!P.content) == P.CharacterType[]);
}

/++
Expand Down Expand Up @@ -431,14 +419,11 @@ template isCursor(CursorType)
enum bool isCursor = is(typeof(
(inout int = 0)
{
alias T = CursorType.InputType;
alias S = CursorType.StringType;

CursorType cursor;
T input;
bool b;

cursor.setSource(input);
b = cursor.atBeginning;
b = cursor.documentEnd;
b = cursor.next;
Expand Down Expand Up @@ -515,6 +500,22 @@ template isWriter(WriterType)
}));
}

// COMMON

template needSource(T)
{
enum bool needSource = is(typeof(
(inout int = 0)
{
alias InputType = T.InputType;

T component;
InputType input;

component.setSource(input);
}));
}

/++
+ Generic XML exception; thrown whenever a component experiences an error, unless
+ the user provided a custom error handler.
Expand Down
7 changes: 4 additions & 3 deletions source/std/experimental/xml/legacy.d
Expand Up @@ -18,7 +18,7 @@ import std.experimental.xml.interfaces;
class ElementParser
{
import std.typecons : No;
private alias CursorType = typeof(chooseLexer!string.parse.cursor!(No.conflateCDATA));
private alias CursorType = typeof("".lexer.parser.cursor!(No.conflateCDATA));

alias ParserHandler = void delegate(ElementParser);
alias ElementHandler = void delegate(in Element);
Expand Down Expand Up @@ -114,8 +114,9 @@ class DocumentParser: ElementParser
{
cursor = cursor.init;
cursor =
chooseLexer!text
.parse
text
.lexer
.parser
.cursor!(No.conflateCDATA);
cursor.setSource(text);
super(&cursor);
Expand Down
36 changes: 24 additions & 12 deletions source/std/experimental/xml/lexers.d
Expand Up @@ -29,7 +29,7 @@ import std.experimental.xml.interfaces;
import std.experimental.xml.faststrings;

import std.range.primitives;
import std.traits : isArray;
import std.traits : isArray, isSomeFunction;

import std.experimental.allocator;
import std.experimental.allocator.gc_allocator;
Expand Down Expand Up @@ -725,7 +725,7 @@ struct BufferedLexer(T, ErrorHandler, Alloc = shared(GCAllocator), Flag!"reuseBu
+ used. If no allocator type is specified, defaults to `shared(GCAllocator)`.
+/
auto chooseLexer(Input, Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Alloc, Handler)
(ref Alloc alloc, Handler handler = () { assert(0, "Unexpected input end while lexing"); })
(ref Alloc alloc, Handler handler)
{
static if (is(SliceLexer!(Input, Handler, Alloc, reuseBuffer)))
{
Expand All @@ -748,24 +748,35 @@ auto chooseLexer(Input, Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Alloc,
else static assert(0);
}
/// ditto
auto chooseLexer(alias Input, Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Alloc, Handler)
(ref Alloc alloc, Handler handler = () { assert(0, "Unexpected input end while lexing"); })
auto chooseLexer(Input, Alloc = shared(GCAllocator), Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Handler)
(Handler handler)
if (is(typeof(Alloc.instance)) && isSomeFunction!handler)
{
return chooseLexer!(typeof(Input), reuseBuffer, Alloc, Handler)(alloc, handler);
return chooseLexer!(Input, reuseBuffer, Alloc, Handler)(Alloc.instance, handler);
}
/// ditto
auto chooseLexer(Input, Alloc = shared(GCAllocator), Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Handler)
(Handler handler = () { assert(0, "Unexpected input end while lexing"); })
if (is(typeof(Alloc.instance)))
auto chooseLexer(Input, Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Alloc)(ref Alloc alloc)
if (!isSomeFunction!alloc)
{
return chooseLexer!(Input, reuseBuffer, Alloc, Handler)(Alloc.instance, handler);
return chooseLexer!(Input, reuseBuffer)
(alloc, (){ throw new XMLException("Unexpected end of input while lexing"); });
}
/// ditto
auto chooseLexer(alias Input, Alloc = shared(GCAllocator), Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer, Handler)
(Handler handler = () { assert(0, "Unexpected input end while lexing"); })
auto chooseLexer(Input, Alloc = shared(GCAllocator), Flag!"reuseBuffer" reuseBuffer = Yes.reuseBuffer)()
if (is(typeof(Alloc.instance)))
{
return chooseLexer!(typeof(Input), reuseBuffer, Alloc, Handler)(Alloc.instance, handler);
return chooseLexer!(Input, reuseBuffer, Alloc)
(Alloc.instance, (){ throw new XMLException("Unexpected end of input while lexing"); });
}

template lexer(Params...)
{
auto lexer(Input, Args...)(auto ref Input input, auto ref Args args)
{
auto res = chooseLexer!(Input, Params)(args);
res.setSource(input);
return res;
}
}

version(unittest)
Expand Down Expand Up @@ -816,6 +827,7 @@ unittest
};

T lexer;
assert(lexer.empty);
lexer.setSource(conv(xml));
lexer.errorHandler = handler;

Expand Down
7 changes: 3 additions & 4 deletions source/std/experimental/xml/package.d
Expand Up @@ -262,12 +262,11 @@ public import dom = std.experimental.xml.dom;
};

auto cursor =
chooseLexer!xml
.parse!(No.preserveWhitespace)
xml
.lexer((){})
.parser!(No.preserveWhitespace)
.cursor!(Yes.conflateCDATA)((){})
.checkXMLNames;

cursor.setSource(xml);

assert(cursor.kind == XMLKind.document);
}

0 comments on commit 66ad7ea

Please sign in to comment.