1"""
2 pygments.lexers.asn1
3 ~~~~~~~~~~~~~~~~~~~~
4
5 Pygments lexers for ASN.1.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11import re
12
13from pygments.token import Comment, Operator, Keyword, Name, String, \
14 Number, Punctuation, Whitespace
15from pygments.lexer import RegexLexer, words, bygroups
16
17__all__ = ['Asn1Lexer']
18
19SINGLE_WORD_KEYWORDS = [
20 "ENCODED",
21 "ABSTRACT-SYNTAX",
22 "END",
23 "APPLICATION",
24 "EXPLICIT",
25 "IMPLICIT",
26 "AUTOMATIC",
27 "TAGS",
28 "BEGIN",
29 "EXTENSIBILITY",
30 "BY",
31 "FROM",
32 "COMPONENT",
33 "UNIVERSAL",
34 "COMPONENTS",
35 "CONSTRAINED",
36 "IMPLIED",
37 "DEFINITIONS",
38 "INCLUDES",
39 "PRIVATE",
40 "WITH",
41 "OF",
42]
43
44OPERATOR_WORDS = [
45 "EXCEPT",
46 "UNION",
47 "INTERSECTION",
48]
49
50SINGLE_WORD_NAMESPACE_KEYWORDS = [
51 "EXPORTS",
52 "IMPORTS",
53]
54
55MULTI_WORDS_DECLARATIONS = [
56 "SEQUENCE OF",
57 "SET OF",
58 "INSTANCE OF",
59 "WITH SYNTAX",
60]
61
62SINGLE_WORDS_DECLARATIONS = [
63 "SIZE",
64 "SEQUENCE",
65 "SET",
66 "CLASS",
67 "UNIQUE",
68 "DEFAULT",
69 "CHOICE",
70 "PATTERN",
71 "OPTIONAL",
72 "PRESENT",
73 "ABSENT",
74 "CONTAINING",
75 "ENUMERATED",
76 "ALL",
77]
78
79TWO_WORDS_TYPES = [
80 "OBJECT IDENTIFIER",
81 "BIT STRING",
82 "OCTET STRING",
83 "CHARACTER STRING",
84 "EMBEDDED PDV",
85]
86
87SINGLE_WORD_TYPES = [
88 "RELATIVE-OID",
89 "TYPE-IDENTIFIER",
90 "ObjectDescriptor",
91 "IA5String",
92 "INTEGER",
93 "ISO646String",
94 "T61String",
95 "BMPString",
96 "NumericString",
97 "TeletexString",
98 "GeneralizedTime",
99 "REAL",
100 "BOOLEAN",
101 "GeneralString",
102 "GraphicString",
103 "UniversalString",
104 "UTCTime",
105 "VisibleString",
106 "UTF8String",
107 "PrintableString",
108 "VideotexString",
109 "EXTERNAL",
110]
111
112
113def word_sequences(tokens):
114 return "(" + '|'.join(token.replace(' ', r'\s+') for token in tokens) + r')\b'
115
116
117class Asn1Lexer(RegexLexer):
118
119 """
120 Lexer for ASN.1 module definition
121 """
122
123 flags = re.MULTILINE
124
125 name = 'ASN.1'
126 aliases = ['asn1']
127 filenames = ["*.asn1"]
128 url = "https://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf"
129 version_added = '2.16'
130
131 tokens = {
132 'root': [
133 # Whitespace:
134 (r'\s+', Whitespace),
135 # Comments:
136 (r'--.*$', Comment.Single),
137 (r'/\*', Comment.Multiline, 'comment'),
138 # Numbers:
139 (r'\d+\.\d*([eE][-+]?\d+)?', Number.Float),
140 (r'\d+', Number.Integer),
141 # Identifier:
142 (r"&?[a-z][-a-zA-Z0-9]*[a-zA-Z0-9]\b", Name.Variable),
143 # Constants:
144 (words(("TRUE", "FALSE", "NULL", "MINUS-INFINITY", "PLUS-INFINITY", "MIN", "MAX"), suffix=r'\b'), Keyword.Constant),
145 # Builtin types:
146 (word_sequences(TWO_WORDS_TYPES), Keyword.Type),
147 (words(SINGLE_WORD_TYPES, suffix=r'\b'), Keyword.Type),
148 # Other keywords:
149 (r"EXPORTS\s+ALL\b", Keyword.Namespace),
150 (words(SINGLE_WORD_NAMESPACE_KEYWORDS, suffix=r'\b'), Operator.Namespace),
151 (word_sequences(MULTI_WORDS_DECLARATIONS), Keyword.Declaration),
152 (words(SINGLE_WORDS_DECLARATIONS, suffix=r'\b'), Keyword.Declaration),
153 (words(OPERATOR_WORDS, suffix=r'\b'), Operator.Word),
154 (words(SINGLE_WORD_KEYWORDS), Keyword),
155 # Type identifier:
156 (r"&?[A-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\b", Name.Type),
157 # Operators:
158 (r"(::=|\.\.\.|\.\.|\[\[|\]\]|\||\^)", Operator),
159 # Punctuation:
160 (r"(\.|,|\{|\}|\(|\)|\[|\])", Punctuation),
161 # String:
162 (r'"', String, 'string'),
163 # Binary string:
164 (r"('[01 ]*')(B)\b", bygroups(String, String.Affix)),
165 (r"('[0-9A-F ]*')(H)\b",bygroups(String, String.Affix)),
166 ],
167 'comment': [
168 (r'[^*/]+', Comment.Multiline),
169 (r'/\*', Comment.Multiline, '#push'),
170 (r'\*/', Comment.Multiline, '#pop'),
171 (r'[*/]', Comment.Multiline)
172 ],
173 'string': [
174 (r'""', String),
175 (r'"', String, "#pop"),
176 (r'[^"]', String),
177 ]
178 }