rust.py 7.7 KB

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