1"""
2 pygments.lexers.d
3 ~~~~~~~~~~~~~~~~~
4
5 Lexers for D languages.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, include, words, bygroups
12from pygments.token import Comment, Keyword, Name, String, Number, \
13 Punctuation, Whitespace
14
15__all__ = ['DLexer', 'CrocLexer', 'MiniDLexer']
16
17
18class DLexer(RegexLexer):
19 """
20 For D source.
21 """
22 name = 'D'
23 url = 'https://dlang.org/'
24 filenames = ['*.d', '*.di']
25 aliases = ['d']
26 mimetypes = ['text/x-dsrc']
27 version_added = '1.2'
28
29 tokens = {
30 'root': [
31 (r'\n', Whitespace),
32 (r'\s+', Whitespace),
33 # (r'\\\n', Text), # line continuations
34 # Comments
35 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)),
36 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
37 (r'/\+', Comment.Multiline, 'nested_comment'),
38 # Keywords
39 (words((
40 'abstract', 'alias', 'align', 'asm', 'assert', 'auto', 'body',
41 'break', 'case', 'cast', 'catch', 'class', 'const', 'continue',
42 'debug', 'default', 'delegate', 'delete', 'deprecated', 'do', 'else',
43 'enum', 'export', 'extern', 'finally', 'final', 'foreach_reverse',
44 'foreach', 'for', 'function', 'goto', 'if', 'immutable', 'import',
45 'interface', 'invariant', 'inout', 'in', 'is', 'lazy', 'mixin',
46 'module', 'new', 'nothrow', 'out', 'override', 'package', 'pragma',
47 'private', 'protected', 'public', 'pure', 'ref', 'return', 'scope',
48 'shared', 'static', 'struct', 'super', 'switch', 'synchronized',
49 'template', 'this', 'throw', 'try', 'typeid', 'typeof',
50 'union', 'unittest', 'version', 'volatile', 'while', 'with',
51 '__gshared', '__traits', '__vector', '__parameters'),
52 suffix=r'\b'),
53 Keyword),
54 (words((
55 # Removed in 2.072
56 'typedef', ),
57 suffix=r'\b'),
58 Keyword.Removed),
59 (words((
60 'bool', 'byte', 'cdouble', 'cent', 'cfloat', 'char', 'creal',
61 'dchar', 'double', 'float', 'idouble', 'ifloat', 'int', 'ireal',
62 'long', 'real', 'short', 'ubyte', 'ucent', 'uint', 'ulong',
63 'ushort', 'void', 'wchar'), suffix=r'\b'),
64 Keyword.Type),
65 (r'(false|true|null)\b', Keyword.Constant),
66 (words((
67 '__FILE__', '__FILE_FULL_PATH__', '__MODULE__', '__LINE__', '__FUNCTION__',
68 '__PRETTY_FUNCTION__', '__DATE__', '__EOF__', '__TIME__', '__TIMESTAMP__',
69 '__VENDOR__', '__VERSION__'), suffix=r'\b'),
70 Keyword.Pseudo),
71 (r'macro\b', Keyword.Reserved),
72 (r'(string|wstring|dstring|size_t|ptrdiff_t)\b', Name.Builtin),
73 # FloatLiteral
74 # -- HexFloat
75 (r'0[xX]([0-9a-fA-F_]*\.[0-9a-fA-F_]+|[0-9a-fA-F_]+)'
76 r'[pP][+\-]?[0-9_]+[fFL]?[i]?', Number.Float),
77 # -- DecimalFloat
78 (r'[0-9_]+(\.[0-9_]+[eE][+\-]?[0-9_]+|'
79 r'\.[0-9_]*|[eE][+\-]?[0-9_]+)[fFL]?[i]?', Number.Float),
80 (r'\.(0|[1-9][0-9_]*)([eE][+\-]?[0-9_]+)?[fFL]?[i]?', Number.Float),
81 # IntegerLiteral
82 # -- Binary
83 (r'0[Bb][01_]+', Number.Bin),
84 # -- Octal
85 (r'0[0-7_]+', Number.Oct),
86 # -- Hexadecimal
87 (r'0[xX][0-9a-fA-F_]+', Number.Hex),
88 # -- Decimal
89 (r'(0|[1-9][0-9_]*)([LUu]|Lu|LU|uL|UL)?', Number.Integer),
90 # CharacterLiteral
91 (r"""'(\\['"?\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}"""
92 r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\&\w+;|.)'""",
93 String.Char),
94 # StringLiteral
95 # -- WysiwygString
96 (r'r"[^"]*"[cwd]?', String),
97 # -- AlternateWysiwygString
98 (r'`[^`]*`[cwd]?', String),
99 # -- DoubleQuotedString
100 (r'"(\\\\|\\[^\\]|[^"\\])*"[cwd]?', String),
101 # -- EscapeSequence
102 (r"\\(['\"?\\abfnrtv]|x[0-9a-fA-F]{2}|[0-7]{1,3}"
103 r"|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|&\w+;)",
104 String),
105 # -- HexString
106 (r'x"[0-9a-fA-F_\s]*"[cwd]?', String),
107 # -- DelimitedString
108 (r'q"\[', String, 'delimited_bracket'),
109 (r'q"\(', String, 'delimited_parenthesis'),
110 (r'q"<', String, 'delimited_angle'),
111 (r'q"\{', String, 'delimited_curly'),
112 (r'q"([a-zA-Z_]\w*)\n.*?\n\1"', String),
113 (r'q"(.).*?\1"', String),
114 # -- TokenString
115 (r'q\{', String, 'token_string'),
116 # Attributes
117 (r'@([a-zA-Z_]\w*)?', Name.Decorator),
118 # Tokens
119 (r'(~=|\^=|%=|\*=|==|!>=|!<=|!<>=|!<>|!<|!>|!=|>>>=|>>>|>>=|>>|>='
120 r'|<>=|<>|<<=|<<|<=|\+\+|\+=|--|-=|\|\||\|=|&&|&=|\.\.\.|\.\.|/=)'
121 r'|[/.&|\-+<>!()\[\]{}?,;:$=*%^~]', Punctuation),
122 # Identifier
123 (r'[a-zA-Z_]\w*', Name),
124 # Line
125 (r'(#line)(\s)(.*)(\n)', bygroups(Comment.Special, Whitespace,
126 Comment.Special, Whitespace)),
127 ],
128 'nested_comment': [
129 (r'[^+/]+', Comment.Multiline),
130 (r'/\+', Comment.Multiline, '#push'),
131 (r'\+/', Comment.Multiline, '#pop'),
132 (r'[+/]', Comment.Multiline),
133 ],
134 'token_string': [
135 (r'\{', Punctuation, 'token_string_nest'),
136 (r'\}', String, '#pop'),
137 include('root'),
138 ],
139 'token_string_nest': [
140 (r'\{', Punctuation, '#push'),
141 (r'\}', Punctuation, '#pop'),
142 include('root'),
143 ],
144 'delimited_bracket': [
145 (r'[^\[\]]+', String),
146 (r'\[', String, 'delimited_inside_bracket'),
147 (r'\]"', String, '#pop'),
148 ],
149 'delimited_inside_bracket': [
150 (r'[^\[\]]+', String),
151 (r'\[', String, '#push'),
152 (r'\]', String, '#pop'),
153 ],
154 'delimited_parenthesis': [
155 (r'[^()]+', String),
156 (r'\(', String, 'delimited_inside_parenthesis'),
157 (r'\)"', String, '#pop'),
158 ],
159 'delimited_inside_parenthesis': [
160 (r'[^()]+', String),
161 (r'\(', String, '#push'),
162 (r'\)', String, '#pop'),
163 ],
164 'delimited_angle': [
165 (r'[^<>]+', String),
166 (r'<', String, 'delimited_inside_angle'),
167 (r'>"', String, '#pop'),
168 ],
169 'delimited_inside_angle': [
170 (r'[^<>]+', String),
171 (r'<', String, '#push'),
172 (r'>', String, '#pop'),
173 ],
174 'delimited_curly': [
175 (r'[^{}]+', String),
176 (r'\{', String, 'delimited_inside_curly'),
177 (r'\}"', String, '#pop'),
178 ],
179 'delimited_inside_curly': [
180 (r'[^{}]+', String),
181 (r'\{', String, '#push'),
182 (r'\}', String, '#pop'),
183 ],
184 }
185
186
187class CrocLexer(RegexLexer):
188 """
189 For Croc source.
190 """
191 name = 'Croc'
192 url = 'http://jfbillingsley.com/croc'
193 filenames = ['*.croc']
194 aliases = ['croc']
195 mimetypes = ['text/x-crocsrc']
196 version_added = ''
197
198 tokens = {
199 'root': [
200 (r'\n', Whitespace),
201 (r'\s+', Whitespace),
202 # Comments
203 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)),
204 (r'/\*', Comment.Multiline, 'nestedcomment'),
205 # Keywords
206 (words((
207 'as', 'assert', 'break', 'case', 'catch', 'class', 'continue',
208 'default', 'do', 'else', 'finally', 'for', 'foreach', 'function',
209 'global', 'namespace', 'if', 'import', 'in', 'is', 'local',
210 'module', 'return', 'scope', 'super', 'switch', 'this', 'throw',
211 'try', 'vararg', 'while', 'with', 'yield'), suffix=r'\b'),
212 Keyword),
213 (r'(false|true|null)\b', Keyword.Constant),
214 # FloatLiteral
215 (r'([0-9][0-9_]*)(?=[.eE])(\.[0-9][0-9_]*)?([eE][+\-]?[0-9_]+)?',
216 Number.Float),
217 # IntegerLiteral
218 # -- Binary
219 (r'0[bB][01][01_]*', Number.Bin),
220 # -- Hexadecimal
221 (r'0[xX][0-9a-fA-F][0-9a-fA-F_]*', Number.Hex),
222 # -- Decimal
223 (r'([0-9][0-9_]*)(?![.eE])', Number.Integer),
224 # CharacterLiteral
225 (r"""'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-9]{1,3}"""
226 r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|.)'""",
227 String.Char),
228 # StringLiteral
229 # -- WysiwygString
230 (r'@"(""|[^"])*"', String),
231 (r'@`(``|[^`])*`', String),
232 (r"@'(''|[^'])*'", String),
233 # -- DoubleQuotedString
234 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
235 # Tokens
236 (r'(~=|\^=|%=|\*=|==|!=|>>>=|>>>|>>=|>>|>=|<=>|\?=|-\>'
237 r'|<<=|<<|<=|\+\+|\+=|--|-=|\|\||\|=|&&|&=|\.\.|/=)'
238 r'|[-/.&$@|\+<>!()\[\]{}?,;:=*%^~#\\]', Punctuation),
239 # Identifier
240 (r'[a-zA-Z_]\w*', Name),
241 ],
242 'nestedcomment': [
243 (r'[^*/]+', Comment.Multiline),
244 (r'/\*', Comment.Multiline, '#push'),
245 (r'\*/', Comment.Multiline, '#pop'),
246 (r'[*/]', Comment.Multiline),
247 ],
248 }
249
250
251class MiniDLexer(CrocLexer):
252 """
253 For MiniD source. MiniD is now known as Croc.
254 """
255 name = 'MiniD'
256 filenames = [] # don't lex .md as MiniD, reserve for Markdown
257 aliases = ['minid']
258 mimetypes = ['text/x-minidsrc']
259 version_added = ''