rust.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. """
  2. pygments.lexers.rust
  3. ~~~~~~~~~~~~~~~~~~~~
  4. Lexers for the Rust language.
  5. :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. from pygments.lexer import RegexLexer, include, bygroups, words, default
  9. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  10. Number, Punctuation, Whitespace
  11. __all__ = ['RustLexer']
  12. class RustLexer(RegexLexer):
  13. """
  14. Lexer for the Rust programming language (version 1.47).
  15. .. versionadded:: 1.6
  16. """
  17. name = 'Rust'
  18. filenames = ['*.rs', '*.rs.in']
  19. aliases = ['rust', 'rs']
  20. mimetypes = ['text/rust', 'text/x-rust']
  21. keyword_types = (words((
  22. 'u8', 'u16', 'u32', 'u64', 'u128', 'i8', 'i16', 'i32', 'i64', 'i128',
  23. 'usize', 'isize', 'f32', 'f64', 'char', 'str', 'bool',
  24. ), suffix=r'\b'), Keyword.Type)
  25. builtin_funcs_types = (words((
  26. 'Copy', 'Send', 'Sized', 'Sync', 'Unpin',
  27. 'Drop', 'Fn', 'FnMut', 'FnOnce', 'drop',
  28. 'Box', 'ToOwned', 'Clone',
  29. 'PartialEq', 'PartialOrd', 'Eq', 'Ord',
  30. 'AsRef', 'AsMut', 'Into', 'From', 'Default',
  31. 'Iterator', 'Extend', 'IntoIterator', 'DoubleEndedIterator',
  32. 'ExactSizeIterator',
  33. 'Option', 'Some', 'None',
  34. 'Result', 'Ok', 'Err',
  35. 'String', 'ToString', 'Vec',
  36. ), suffix=r'\b'), Name.Builtin)
  37. builtin_macros = (words((
  38. 'asm', 'assert', 'assert_eq', 'assert_ne', 'cfg', 'column',
  39. 'compile_error', 'concat', 'concat_idents', 'dbg', 'debug_assert',
  40. 'debug_assert_eq', 'debug_assert_ne', 'env', 'eprint', 'eprintln',
  41. 'file', 'format', 'format_args', 'format_args_nl', 'global_asm',
  42. 'include', 'include_bytes', 'include_str',
  43. 'is_aarch64_feature_detected',
  44. 'is_arm_feature_detected',
  45. 'is_mips64_feature_detected',
  46. 'is_mips_feature_detected',
  47. 'is_powerpc64_feature_detected',
  48. 'is_powerpc_feature_detected',
  49. 'is_x86_feature_detected',
  50. 'line', 'llvm_asm', 'log_syntax', 'macro_rules', 'matches',
  51. 'module_path', 'option_env', 'panic', 'print', 'println', 'stringify',
  52. 'thread_local', 'todo', 'trace_macros', 'unimplemented', 'unreachable',
  53. 'vec', 'write', 'writeln',
  54. ), suffix=r'!'), Name.Function.Magic)
  55. tokens = {
  56. 'root': [
  57. # rust allows a file to start with a shebang, but if the first line
  58. # starts with #![ then it's not a shebang but a crate attribute.
  59. (r'#![^[\r\n].*$', Comment.Preproc),
  60. default('base'),
  61. ],
  62. 'base': [
  63. # Whitespace and Comments
  64. (r'\n', Whitespace),
  65. (r'\s+', Whitespace),
  66. (r'//!.*?\n', String.Doc),
  67. (r'///(\n|[^/].*?\n)', String.Doc),
  68. (r'//(.*?)\n', Comment.Single),
  69. (r'/\*\*(\n|[^/*])', String.Doc, 'doccomment'),
  70. (r'/\*!', String.Doc, 'doccomment'),
  71. (r'/\*', Comment.Multiline, 'comment'),
  72. # Macro parameters
  73. (r"""\$([a-zA-Z_]\w*|\(,?|\),?|,?)""", Comment.Preproc),
  74. # Keywords
  75. (words(('as', 'async', 'await', 'box', 'const', 'crate', 'dyn',
  76. 'else', 'extern', 'for', 'if', 'impl', 'in', 'loop',
  77. 'match', 'move', 'mut', 'pub', 'ref', 'return', 'static',
  78. 'super', 'trait', 'unsafe', 'use', 'where', 'while'),
  79. suffix=r'\b'), Keyword),
  80. (words(('abstract', 'become', 'do', 'final', 'macro', 'override',
  81. 'priv', 'typeof', 'try', 'unsized', 'virtual', 'yield'),
  82. suffix=r'\b'), Keyword.Reserved),
  83. (r'(true|false)\b', Keyword.Constant),
  84. (r'self\b', Name.Builtin.Pseudo),
  85. (r'mod\b', Keyword, 'modname'),
  86. (r'let\b', Keyword.Declaration),
  87. (r'fn\b', Keyword, 'funcname'),
  88. (r'(struct|enum|type|union)\b', Keyword, 'typename'),
  89. (r'(default)(\s+)(type|fn)\b', bygroups(Keyword, Text, Keyword)),
  90. keyword_types,
  91. (r'[sS]elf\b', Name.Builtin.Pseudo),
  92. # Prelude (taken from Rust's src/libstd/prelude.rs)
  93. builtin_funcs_types,
  94. builtin_macros,
  95. # Path seperators, so types don't catch them.
  96. (r'::\b', Text),
  97. # Types in positions.
  98. (r'(?::|->)', Text, 'typename'),
  99. # Labels
  100. (r'(break|continue)(\s*)(\'[A-Za-z_]\w*)?',
  101. bygroups(Keyword, Text.Whitespace, Name.Label)),
  102. # Character literals
  103. (r"""'(\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0"""
  104. r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""",
  105. String.Char),
  106. (r"""b'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0"""
  107. r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""",
  108. String.Char),
  109. # Binary literals
  110. (r'0b[01_]+', Number.Bin, 'number_lit'),
  111. # Octal literals
  112. (r'0o[0-7_]+', Number.Oct, 'number_lit'),
  113. # Hexadecimal literals
  114. (r'0[xX][0-9a-fA-F_]+', Number.Hex, 'number_lit'),
  115. # Decimal literals
  116. (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|'
  117. r'\.[0-9_]*(?!\.)|[eE][+\-]?[0-9_]+)', Number.Float,
  118. 'number_lit'),
  119. (r'[0-9][0-9_]*', Number.Integer, 'number_lit'),
  120. # String literals
  121. (r'b"', String, 'bytestring'),
  122. (r'"', String, 'string'),
  123. (r'(?s)b?r(#*)".*?"\1', String),
  124. # Lifetime names
  125. (r"'", Operator, 'lifetime'),
  126. # Operators and Punctuation
  127. (r'\.\.=?', Operator),
  128. (r'[{}()\[\],.;]', Punctuation),
  129. (r'[+\-*/%&|<>^!~@=:?]', Operator),
  130. # Identifiers
  131. (r'[a-zA-Z_]\w*', Name),
  132. # Raw identifiers
  133. (r'r#[a-zA-Z_]\w*', Name),
  134. # Attributes
  135. (r'#!?\[', Comment.Preproc, 'attribute['),
  136. # Misc
  137. # Lone hashes: not used in Rust syntax, but allowed in macro
  138. # arguments, most famously for quote::quote!()
  139. (r'#', Text),
  140. ],
  141. 'comment': [
  142. (r'[^*/]+', Comment.Multiline),
  143. (r'/\*', Comment.Multiline, '#push'),
  144. (r'\*/', Comment.Multiline, '#pop'),
  145. (r'[*/]', Comment.Multiline),
  146. ],
  147. 'doccomment': [
  148. (r'[^*/]+', String.Doc),
  149. (r'/\*', String.Doc, '#push'),
  150. (r'\*/', String.Doc, '#pop'),
  151. (r'[*/]', String.Doc),
  152. ],
  153. 'modname': [
  154. (r'\s+', Text),
  155. (r'[a-zA-Z_]\w*', Name.Namespace, '#pop'),
  156. default('#pop'),
  157. ],
  158. 'funcname': [
  159. (r'\s+', Text),
  160. (r'[a-zA-Z_]\w*', Name.Function, '#pop'),
  161. default('#pop'),
  162. ],
  163. 'typename': [
  164. (r'\s+', Text),
  165. (r'&', Keyword.Pseudo),
  166. (r"'", Operator, 'lifetime'),
  167. builtin_funcs_types,
  168. keyword_types,
  169. (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
  170. default('#pop'),
  171. ],
  172. 'lifetime': [
  173. (r"(static|_)", Name.Builtin),
  174. (r"[a-zA-Z_]+\w*", Name.Attribute),
  175. default('#pop'),
  176. ],
  177. 'number_lit': [
  178. (r'[ui](8|16|32|64|size)', Keyword, '#pop'),
  179. (r'f(32|64)', Keyword, '#pop'),
  180. default('#pop'),
  181. ],
  182. 'string': [
  183. (r'"', String, '#pop'),
  184. (r"""\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0"""
  185. r"""|\\u\{[0-9a-fA-F]{1,6}\}""", String.Escape),
  186. (r'[^\\"]+', String),
  187. (r'\\', String),
  188. ],
  189. 'bytestring': [
  190. (r"""\\x[89a-fA-F][0-9a-fA-F]""", String.Escape),
  191. include('string'),
  192. ],
  193. 'attribute_common': [
  194. (r'"', String, 'string'),
  195. (r'\[', Comment.Preproc, 'attribute['),
  196. (r'\(', Comment.Preproc, 'attribute('),
  197. ],
  198. 'attribute[': [
  199. include('attribute_common'),
  200. (r'\];?', Comment.Preproc, '#pop'),
  201. (r'[^"\]]+', Comment.Preproc),
  202. ],
  203. 'attribute(': [
  204. include('attribute_common'),
  205. (r'\);?', Comment.Preproc, '#pop'),
  206. (r'[^")]+', Comment.Preproc),
  207. ],
  208. }