scanAlphaNumeric and callers now work with slices.

This commit is contained in:
Ferdinand Majerech 2014-07-26 04:20:32 +02:00
parent 8b086caa40
commit f9ede1c409

View file

@ -839,22 +839,21 @@ final class Scanner
} }
/// Scan a string of alphanumeric or "-_" characters. /// Scan a string of alphanumeric or "-_" characters.
dchar[] scanAlphaNumeric(string name)(const Mark startMark) @safe pure ///
/// Assumes that the caller is building a slice in Reader, and puts the scanned
/// characters into that slice.
void scanAlphaNumericToSlice(string name)(const Mark startMark) @system pure
{ {
uint length = 0; size_t length = 0;
dchar c = reader_.peek(); dchar c = reader_.peek();
while(isAlphaNum(c) || "-_"d.canFind(c)) while(c.isAlphaNum || "-_"d.canFind(c)) { c = reader_.peek(++length); }
{
++length;
c = reader_.peek(length);
}
enforce(length > 0, enforce(length > 0,
new Error("While scanning " ~ name, startMark, new Error("While scanning " ~ name, startMark,
"expected alphanumeric, - or _, but found " ~ to!string(c), "expected alphanumeric, - or _, but found " ~ c.to!string,
reader_.mark)); reader_.mark));
return reader_.get(length); reader_.sliceBuilder.write(reader_.get(length));
} }
/// Scan and throw away all characters until next line break. /// Scan and throw away all characters until next line break.
@ -919,16 +918,22 @@ final class Scanner
} }
} }
///Scan directive token. /// Scan directive token.
Token scanDirective() @safe pure Token scanDirective() @trusted pure
{ {
Mark startMark = reader_.mark; Mark startMark = reader_.mark;
//Skip the '%'. //Skip the '%'.
reader_.forward(); reader_.forward();
auto name = scanDirectiveName(startMark);
auto value = name == "YAML" ? scanYAMLDirectiveValue(startMark): reader_.sliceBuilder.begin();
name == "TAG" ? scanTagDirectiveValue(startMark) : ""; {
scope(failure) { reader_.sliceBuilder.finish(); }
scanDirectiveNameToSlice(startMark);
}
const name = reader_.sliceBuilder.finish();
const value = name == "YAML" ? scanYAMLDirectiveValue(startMark):
name == "TAG" ? scanTagDirectiveValue(startMark) : "";
Mark endMark = reader_.mark; Mark endMark = reader_.mark;
@ -939,17 +944,19 @@ final class Scanner
return directiveToken(startMark, endMark, utf32To8(name ~ '\0' ~ value)); return directiveToken(startMark, endMark, utf32To8(name ~ '\0' ~ value));
} }
///Scan name of a directive token. /// Scan name of a directive token.
dchar[] scanDirectiveName(const Mark startMark) @safe pure ///
/// Assumes that the caller is building a slice in Reader, and puts the scanned
/// characters into that slice.
void scanDirectiveNameToSlice(const Mark startMark) @system pure
{ {
//Scan directive name. //Scan directive name.
auto name = scanAlphaNumeric!"a directive"(startMark); scanAlphaNumericToSlice!"a directive"(startMark);
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()), enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()),
new Error("While scanning a directive", startMark, new Error("While scanning a directive", startMark,
"expected alphanumeric, - or _, but found " "expected alphanumeric, - or _, but found "
~ to!string(reader_.peek()), reader_.mark)); ~ reader_.peek().to!string, reader_.mark));
return name;
} }
///Scan value of a YAML directive token. Returns major, minor version separated by '.'. ///Scan value of a YAML directive token. Returns major, minor version separated by '.'.
@ -1045,32 +1052,35 @@ final class Scanner
} }
/** /// Scan an alias or an anchor.
* Scan an alias or an anchor. ///
* /// The specification does not restrict characters for anchors and
* The specification does not restrict characters for anchors and /// aliases. This may lead to problems, for instance, the document:
* aliases. This may lead to problems, for instance, the document: /// [ *alias, value ]
* [ *alias, value ] /// can be interpteted in two ways, as
* can be interpteted in two ways, as /// [ "value" ]
* [ "value" ] /// and
* and /// [ *alias , "value" ]
* [ *alias , "value" ] /// Therefore we restrict aliases to ASCII alphanumeric characters.
* Therefore we restrict aliases to ASCII alphanumeric characters. Token scanAnchor(const TokenID id) @trusted pure
*/
Token scanAnchor(TokenID id) @safe pure
{ {
const startMark = reader_.mark; const startMark = reader_.mark;
const dchar i = reader_.get(); const dchar i = reader_.get();
dchar[] value = i == '*' ? scanAlphaNumeric!("an alias")(startMark) reader_.sliceBuilder.begin();
: scanAlphaNumeric!("an anchor")(startMark); {
scope(failure) { reader_.sliceBuilder.finish(); }
if(i == '*') { scanAlphaNumericToSlice!"an alias"(startMark); }
else { scanAlphaNumericToSlice!"an anchor"(startMark); }
}
const value = reader_.sliceBuilder.finish();
enforce((" \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()) || enforce((" \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()) ||
("?:,]}%@").canFind(reader_.peek())), ("?:,]}%@"d).canFind(reader_.peek())),
new Error("While scanning an " ~ (i == '*') ? "alias" : "anchor", new Error("While scanning an " ~ (i == '*') ? "alias" : "anchor",
startMark, "expected alphanumeric, - or _, but found "~ startMark, "expected alphanumeric, - or _, but found "~
to!string(reader_.peek()), reader_.mark)); reader_.peek().to!string, reader_.mark));
if(id == TokenID.Alias) if(id == TokenID.Alias)
{ {