rust.py 8.0 KB

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