Newer
Older
dub_jkp / source / dyaml / token.d
  1.  
  2. // Copyright Ferdinand Majerech 2011-2014.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6.  
  7. /// YAML tokens.
  8. /// Code based on PyYAML: http://www.pyyaml.org
  9. module dyaml.token;
  10.  
  11.  
  12. import std.conv;
  13.  
  14. import dyaml.encoding;
  15. import dyaml.exception;
  16. import dyaml.reader;
  17. import dyaml.style;
  18.  
  19.  
  20. package:
  21.  
  22. /// Token types.
  23. enum TokenID : ubyte
  24. {
  25. // Invalid (uninitialized) token
  26. invalid = 0,
  27. directive,
  28. documentStart,
  29. documentEnd,
  30. streamStart,
  31. streamEnd,
  32. blockSequenceStart,
  33. blockMappingStart,
  34. blockEnd,
  35. flowSequenceStart,
  36. flowMappingStart,
  37. flowSequenceEnd,
  38. flowMappingEnd,
  39. key,
  40. value,
  41. blockEntry,
  42. flowEntry,
  43. alias_,
  44. anchor,
  45. tag,
  46. scalar
  47. }
  48.  
  49. /// Specifies the type of a tag directive token.
  50. enum DirectiveType : ubyte
  51. {
  52. // YAML version directive.
  53. yaml,
  54. // Tag directive.
  55. tag,
  56. // Any other directive is "reserved" for future YAML versions.
  57. reserved
  58. }
  59.  
  60. /// Token produced by scanner.
  61. ///
  62. /// 32 bytes on 64-bit.
  63. struct Token
  64. {
  65. @disable int opCmp(ref Token);
  66.  
  67. // 16B
  68. /// Value of the token, if any.
  69. ///
  70. /// Values are char[] instead of string, as Parser may still change them in a few
  71. /// cases. Parser casts values to strings when producing Events.
  72. char[] value;
  73. // 4B
  74. /// Start position of the token in file/stream.
  75. Mark startMark;
  76. // 4B
  77. /// End position of the token in file/stream.
  78. Mark endMark;
  79. // 1B
  80. /// Token type.
  81. TokenID id;
  82. // 1B
  83. /// Style of scalar token, if this is a scalar token.
  84. ScalarStyle style;
  85. // 1B
  86. /// Encoding, if this is a stream start token.
  87. Encoding encoding;
  88. // 1B
  89. /// Type of directive for directiveToken.
  90. DirectiveType directive;
  91. // 4B
  92. /// Used to split value into 2 substrings for tokens that need 2 values (tagToken)
  93. uint valueDivider;
  94.  
  95. /// Get string representation of the token ID.
  96. @property string idString() @safe pure const {return id.to!string;}
  97. }
  98.  
  99. /// Construct a directive token.
  100. ///
  101. /// Params: start = Start position of the token.
  102. /// end = End position of the token.
  103. /// value = Value of the token.
  104. /// directive = Directive type (YAML or TAG in YAML 1.1).
  105. /// nameEnd = Position of the end of the name
  106. Token directiveToken(const Mark start, const Mark end, char[] value,
  107. DirectiveType directive, const uint nameEnd) @safe pure nothrow @nogc
  108. {
  109. return Token(value, start, end, TokenID.directive, ScalarStyle.init, Encoding.init,
  110. directive, nameEnd);
  111. }
  112.  
  113. /// Construct a simple (no value) token with specified type.
  114. ///
  115. /// Params: id = Type of the token.
  116. /// start = Start position of the token.
  117. /// end = End position of the token.
  118. Token simpleToken(TokenID id)(const Mark start, const Mark end)
  119. {
  120. return Token(null, start, end, id);
  121. }
  122.  
  123. /// Construct a stream start token.
  124. ///
  125. /// Params: start = Start position of the token.
  126. /// end = End position of the token.
  127. /// encoding = Encoding of the stream.
  128. Token streamStartToken(const Mark start, const Mark end, const Encoding encoding) @safe pure nothrow @nogc
  129. {
  130. return Token(null, start, end, TokenID.streamStart, ScalarStyle.invalid, encoding);
  131. }
  132.  
  133. /// Aliases for construction of simple token types.
  134. alias streamEndToken = simpleToken!(TokenID.streamEnd);
  135. alias blockSequenceStartToken = simpleToken!(TokenID.blockSequenceStart);
  136. alias blockMappingStartToken = simpleToken!(TokenID.blockMappingStart);
  137. alias blockEndToken = simpleToken!(TokenID.blockEnd);
  138. alias keyToken = simpleToken!(TokenID.key);
  139. alias valueToken = simpleToken!(TokenID.value);
  140. alias blockEntryToken = simpleToken!(TokenID.blockEntry);
  141. alias flowEntryToken = simpleToken!(TokenID.flowEntry);
  142.  
  143. /// Construct a simple token with value with specified type.
  144. ///
  145. /// Params: id = Type of the token.
  146. /// start = Start position of the token.
  147. /// end = End position of the token.
  148. /// value = Value of the token.
  149. /// valueDivider = A hack for TagToken to store 2 values in value; the first
  150. /// value goes up to valueDivider, the second after it.
  151. Token simpleValueToken(TokenID id)(const Mark start, const Mark end, char[] value,
  152. const uint valueDivider = uint.max)
  153. {
  154. return Token(value, start, end, id, ScalarStyle.invalid, Encoding.init,
  155. DirectiveType.init, valueDivider);
  156. }
  157.  
  158. /// Alias for construction of tag token.
  159. alias tagToken = simpleValueToken!(TokenID.tag);
  160. alias aliasToken = simpleValueToken!(TokenID.alias_);
  161. alias anchorToken = simpleValueToken!(TokenID.anchor);
  162.  
  163. /// Construct a scalar token.
  164. ///
  165. /// Params: start = Start position of the token.
  166. /// end = End position of the token.
  167. /// value = Value of the token.
  168. /// style = Style of the token.
  169. Token scalarToken(const Mark start, const Mark end, char[] value, const ScalarStyle style) @safe pure nothrow @nogc
  170. {
  171. return Token(value, start, end, TokenID.scalar, style);
  172. }