Scanner style.
This commit is contained in:
parent
f76e4cfd02
commit
d5663b1e57
|
@ -4,10 +4,8 @@
|
|||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* YAML scanner.
|
||||
* Code based on PyYAML: http://www.pyyaml.org
|
||||
*/
|
||||
/// YAML scanner.
|
||||
/// Code based on PyYAML: http://www.pyyaml.org
|
||||
module dyaml.scanner;
|
||||
|
||||
|
||||
|
@ -34,36 +32,32 @@ import dyaml.style;
|
|||
import dyaml.token;
|
||||
|
||||
package:
|
||||
/**
|
||||
* Scanner produces tokens of the following types:
|
||||
* STREAM-START
|
||||
* STREAM-END
|
||||
* DIRECTIVE(name, value)
|
||||
* DOCUMENT-START
|
||||
* DOCUMENT-END
|
||||
* BLOCK-SEQUENCE-START
|
||||
* BLOCK-MAPPING-START
|
||||
* BLOCK-END
|
||||
* FLOW-SEQUENCE-START
|
||||
* FLOW-MAPPING-START
|
||||
* FLOW-SEQUENCE-END
|
||||
* FLOW-MAPPING-END
|
||||
* BLOCK-ENTRY
|
||||
* FLOW-ENTRY
|
||||
* KEY
|
||||
* VALUE
|
||||
* ALIAS(value)
|
||||
* ANCHOR(value)
|
||||
* TAG(value)
|
||||
* SCALAR(value, plain, style)
|
||||
*/
|
||||
/// Scanner produces tokens of the following types:
|
||||
/// STREAM-START
|
||||
/// STREAM-END
|
||||
/// DIRECTIVE(name, value)
|
||||
/// DOCUMENT-START
|
||||
/// DOCUMENT-END
|
||||
/// BLOCK-SEQUENCE-START
|
||||
/// BLOCK-MAPPING-START
|
||||
/// BLOCK-END
|
||||
/// FLOW-SEQUENCE-START
|
||||
/// FLOW-MAPPING-START
|
||||
/// FLOW-SEQUENCE-END
|
||||
/// FLOW-MAPPING-END
|
||||
/// BLOCK-ENTRY
|
||||
/// FLOW-ENTRY
|
||||
/// KEY
|
||||
/// VALUE
|
||||
/// ALIAS(value)
|
||||
/// ANCHOR(value)
|
||||
/// TAG(value)
|
||||
/// SCALAR(value, plain, style)
|
||||
|
||||
|
||||
/**
|
||||
* Marked exception thrown at scanner errors.
|
||||
*
|
||||
* See_Also: MarkedYAMLException
|
||||
*/
|
||||
/// Marked exception thrown at scanner errors.
|
||||
///
|
||||
/// See_Also: MarkedYAMLException
|
||||
class ScannerException : MarkedYAMLException
|
||||
{
|
||||
mixin MarkedExceptionCtors;
|
||||
|
@ -182,17 +176,14 @@ final class Scanner
|
|||
reader_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the next token is one of specified types.
|
||||
*
|
||||
* If no types are specified, checks if any tokens are left.
|
||||
*
|
||||
* Params: ids = Token IDs to check for.
|
||||
*
|
||||
* Returns: true if the next token is one of specified types,
|
||||
* or if there are any tokens left if no types specified.
|
||||
* false otherwise.
|
||||
*/
|
||||
/// Check if the next token is one of specified types.
|
||||
///
|
||||
/// If no types are specified, checks if any tokens are left.
|
||||
///
|
||||
/// Params: ids = Token IDs to check for.
|
||||
///
|
||||
/// Returns: true if the next token is one of specified types, or if there are
|
||||
/// any tokens left if no types specified, false otherwise.
|
||||
bool checkToken(const TokenID[] ids ...) @safe
|
||||
{
|
||||
//Check if the next token is one of specified types.
|
||||
|
@ -212,11 +203,9 @@ final class Scanner
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next token, but keep it in the queue.
|
||||
*
|
||||
* Must not be called if there are no tokens left.
|
||||
*/
|
||||
/// Return the next token, but keep it in the queue.
|
||||
///
|
||||
/// Must not be called if there are no tokens left.
|
||||
ref const(Token) peekToken() @safe
|
||||
{
|
||||
while(needMoreTokens) { fetchToken(); }
|
||||
|
@ -224,11 +213,9 @@ final class Scanner
|
|||
assert(false, "No token left to peek");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next token, removing it from the queue.
|
||||
*
|
||||
* Must not be called if there are no tokens left.
|
||||
*/
|
||||
/// Return the next token, removing it from the queue.
|
||||
///
|
||||
/// Must not be called if there are no tokens left.
|
||||
Token getToken() @safe
|
||||
{
|
||||
while(needMoreTokens){fetchToken();}
|
||||
|
@ -290,7 +277,7 @@ final class Scanner
|
|||
/// Fetch at token, adding it to tokens_.
|
||||
void fetchToken() @safe
|
||||
{
|
||||
///Eat whitespaces and comments until we reach the next token.
|
||||
// Eat whitespaces and comments until we reach the next token.
|
||||
scanToNextToken();
|
||||
|
||||
// Remove obsolete possible simple keys.
|
||||
|
@ -326,9 +313,9 @@ final class Scanner
|
|||
if(c == '\"') { return fetchDouble(); }
|
||||
if(checkPlain()) { return fetchPlain(); }
|
||||
|
||||
throw new Error(format("While scanning for the next token, found "
|
||||
"character \'%s\', index %s that cannot start any token"
|
||||
, c, to!int(c)), reader_.mark);
|
||||
throw new ScannerException("While scanning for the next token, found character "
|
||||
"\'%s\', index %s that cannot start any token"
|
||||
.format(c, to!int(c)), reader_.mark);
|
||||
}
|
||||
|
||||
|
||||
|
@ -344,15 +331,13 @@ final class Scanner
|
|||
return minTokenNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove entries that are no longer possible simple keys.
|
||||
*
|
||||
* According to the YAML specification, simple keys
|
||||
* - should be limited to a single line,
|
||||
* - should be no longer than 1024 characters.
|
||||
* Disabling this will allow simple keys of any length and
|
||||
* height (may cause problems if indentation is broken though).
|
||||
*/
|
||||
/// Remove entries that are no longer possible simple keys.
|
||||
///
|
||||
/// According to the YAML specification, simple keys
|
||||
/// - should be limited to a single line,
|
||||
/// - should be no longer than 1024 characters.
|
||||
/// Disabling this will allow simple keys of any length and
|
||||
/// height (may cause problems if indentation is broken though).
|
||||
void stalePossibleSimpleKeys() @safe pure
|
||||
{
|
||||
foreach(level, ref key; possibleSimpleKeys_)
|
||||
|
@ -361,7 +346,7 @@ final class Scanner
|
|||
if(key.line != reader_.line || reader_.charIndex - key.charIndex > 1024)
|
||||
{
|
||||
enforce(!key.required,
|
||||
new Error("While scanning a simple key",
|
||||
new ScannerException("While scanning a simple key",
|
||||
Mark(key.line, key.column),
|
||||
"could not find expected ':'", reader_.mark));
|
||||
key.isNull = true;
|
||||
|
@ -369,11 +354,9 @@ final class Scanner
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the next token starts a possible simple key and if so, save its position.
|
||||
*
|
||||
* This function is called for ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
|
||||
*/
|
||||
/// Check if the next token starts a possible simple key and if so, save its position.
|
||||
///
|
||||
/// This function is called for ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
|
||||
void savePossibleSimpleKey() @safe pure
|
||||
{
|
||||
// Check if a simple key is required at the current position.
|
||||
|
@ -389,11 +372,8 @@ final class Scanner
|
|||
|
||||
const line = reader_.line;
|
||||
const column = reader_.column;
|
||||
const key = SimpleKey(cast(uint)reader_.charIndex,
|
||||
tokenCount,
|
||||
line,
|
||||
column < ushort.max ? cast(ushort)column : ushort.max,
|
||||
required);
|
||||
const key = SimpleKey(cast(uint)reader_.charIndex, tokenCount, line,
|
||||
cast(ushort)min(column, ushort.max), required);
|
||||
|
||||
if(possibleSimpleKeys_.length <= flowLevel_)
|
||||
{
|
||||
|
@ -420,11 +400,9 @@ final class Scanner
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease indentation, removing entries in indents_.
|
||||
*
|
||||
* Params: column = Current column in the file/stream.
|
||||
*/
|
||||
/// Decrease indentation, removing entries in indents_.
|
||||
///
|
||||
/// Params: column = Current column in the file/stream.
|
||||
void unwindIndent(const int column) @trusted
|
||||
{
|
||||
if(flowLevel_ > 0)
|
||||
|
@ -455,13 +433,11 @@ final class Scanner
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase indentation if needed.
|
||||
*
|
||||
* Params: column = Current column in the file/stream.
|
||||
*
|
||||
* Returns: true if the indentation was increased, false otherwise.
|
||||
*/
|
||||
/// Increase indentation if needed.
|
||||
///
|
||||
/// Params: column = Current column in the file/stream.
|
||||
///
|
||||
/// Returns: true if the indentation was increased, false otherwise.
|
||||
bool addIndent(int column) @trusted
|
||||
{
|
||||
if(indent_ >= column){return false;}
|
||||
|
@ -572,12 +548,10 @@ final class Scanner
|
|||
tokens_.push(flowEntryToken(startMark, reader_.mark));
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional checks used in block context in fetchBlockEntry and fetchKey.
|
||||
*
|
||||
* Params: type = String representing the token type we might need to add.
|
||||
* id = Token type we might need to add.
|
||||
*/
|
||||
/// Additional checks used in block context in fetchBlockEntry and fetchKey.
|
||||
///
|
||||
/// Params: type = String representing the token type we might need to add.
|
||||
/// id = Token type we might need to add.
|
||||
void blockChecks(string type, TokenID id)() @safe
|
||||
{
|
||||
//Are we allowed to start a key (not neccesarily a simple one)?
|
||||
|
@ -1912,7 +1886,8 @@ final class Scanner
|
|||
/// characters into that slice.
|
||||
///
|
||||
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
||||
void scanTagURIToSlice(string name)(const Mark startMark) @trusted pure nothrow
|
||||
void scanTagURIToSlice(string name)(const Mark startMark)
|
||||
@trusted pure nothrow // @nogc
|
||||
{
|
||||
// Note: we do not check if URI is well-formed.
|
||||
dchar c = reader_.peek();
|
||||
|
|
Loading…
Reference in a new issue