1"""
2 pygments.lexers.devicetree
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for Devicetree language.
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, bygroups, include, default, words
12from pygments.token import Comment, Keyword, Name, Number, Operator, \
13 Punctuation, String, Text, Whitespace
14
15__all__ = ['DevicetreeLexer']
16
17
18class DevicetreeLexer(RegexLexer):
19 """
20 Lexer for Devicetree files.
21 """
22
23 name = 'Devicetree'
24 url = 'https://www.devicetree.org/'
25 aliases = ['devicetree', 'dts']
26 filenames = ['*.dts', '*.dtsi']
27 mimetypes = ['text/x-c']
28 version_added = '2.7'
29
30 #: optional Whitespace or /*...*/ style comment
31 _ws = r'\s*(?:/[*][^*/]*?[*]/\s*)*'
32
33 tokens = {
34 'macro': [
35 # Include preprocessor directives (C style):
36 (r'(#include)(' + _ws + r')([^\n]+)',
37 bygroups(Comment.Preproc, Comment.Multiline, Comment.PreprocFile)),
38 # Define preprocessor directives (C style):
39 (r'(#define)(' + _ws + r')([^\n]+)',
40 bygroups(Comment.Preproc, Comment.Multiline, Comment.Preproc)),
41 # devicetree style with file:
42 (r'(/[^*/{]+/)(' + _ws + r')("[^\n{]+")',
43 bygroups(Comment.Preproc, Comment.Multiline, Comment.PreprocFile)),
44 # devicetree style with property:
45 (r'(/[^*/{]+/)(' + _ws + r')([^\n;{]*)([;]?)',
46 bygroups(Comment.Preproc, Comment.Multiline, Comment.Preproc, Punctuation)),
47 ],
48 'whitespace': [
49 (r'\n', Whitespace),
50 (r'\s+', Whitespace),
51 (r'\\\n', Text), # line continuation
52 (r'//(\n|[\w\W]*?[^\\]\n)', Comment.Single),
53 (r'/(\\\n)?[*][\w\W]*?[*](\\\n)?/', Comment.Multiline),
54 # Open until EOF, so no ending delimiter
55 (r'/(\\\n)?[*][\w\W]*', Comment.Multiline),
56 ],
57 'statements': [
58 (r'(L?)(")', bygroups(String.Affix, String), 'string'),
59 (r'0x[0-9a-fA-F]+', Number.Hex),
60 (r'\d+', Number.Integer),
61 (r'([^\s{}/*]*)(\s*)(:)', bygroups(Name.Label, Text, Punctuation), '#pop'),
62 (words(('compatible', 'model', 'phandle', 'status', '#address-cells',
63 '#size-cells', 'reg', 'virtual-reg', 'ranges', 'dma-ranges',
64 'device_type', 'name'), suffix=r'\b'), Keyword.Reserved),
65 (r'([~!%^&*+=|?:<>/#-])', Operator),
66 (r'[()\[\]{},.]', Punctuation),
67 (r'[a-zA-Z_][\w-]*(?=(?:\s*,\s*[a-zA-Z_][\w-]*|(?:' + _ws + r'))*\s*[=;])',
68 Name),
69 (r'[a-zA-Z_]\w*', Name.Attribute),
70 ],
71 'root': [
72 include('whitespace'),
73 include('macro'),
74
75 # Nodes
76 (r'([^/*@\s&]+|/)(@?)((?:0x)?[0-9a-fA-F,]*)(' + _ws + r')(\{)',
77 bygroups(Name.Function, Operator, Number.Integer,
78 Comment.Multiline, Punctuation), 'node'),
79
80 default('statement'),
81 ],
82 'statement': [
83 include('whitespace'),
84 include('statements'),
85 (';', Punctuation, '#pop'),
86 ],
87 'node': [
88 include('whitespace'),
89 include('macro'),
90
91 (r'([^/*@\s&]+|/)(@?)((?:0x)?[0-9a-fA-F,]*)(' + _ws + r')(\{)',
92 bygroups(Name.Function, Operator, Number.Integer,
93 Comment.Multiline, Punctuation), '#push'),
94
95 include('statements'),
96
97 (r'\};', Punctuation, '#pop'),
98 (';', Punctuation),
99 ],
100 'string': [
101 (r'"', String, '#pop'),
102 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|'
103 r'u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})', String.Escape),
104 (r'[^\\"\n]+', String), # all other characters
105 (r'\\\n', String), # line continuation
106 (r'\\', String), # stray backslash
107 ],
108 }