Scanner style.

This commit is contained in:
Ferdinand Majerech 2014-07-26 23:29:55 +02:00
parent f76e4cfd02
commit d5663b1e57

View file

@ -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();