|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.clean |
|
4 ~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexer for the Clean language. |
|
7 |
|
8 :copyright: Copyright 2006-2015 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 from pygments.lexer import ExtendedRegexLexer, words, include, bygroups |
|
13 from pygments.token import Comment, Error, Keyword, Literal, Name, Number, \ |
|
14 Operator, Punctuation, String, Whitespace |
|
15 |
|
16 __all__ = ['CleanLexer'] |
|
17 |
|
18 |
|
19 class CleanLexer(ExtendedRegexLexer): |
|
20 """ |
|
21 Lexer for the general purpose, state-of-the-art, pure and lazy functional |
|
22 programming language Clean (http://clean.cs.ru.nl/Clean). |
|
23 |
|
24 .. versionadded: 2.2 |
|
25 """ |
|
26 name = 'Clean' |
|
27 aliases = ['clean'] |
|
28 filenames = ['*.icl', '*.dcl'] |
|
29 |
|
30 keywords = ( |
|
31 'case', 'ccall', 'class', 'code', 'code inline', 'derive', 'export', |
|
32 'foreign', 'generic', 'if', 'in', 'infix', 'infixl', 'infixr', |
|
33 'instance', 'let', 'of', 'otherwise', 'special', 'stdcall', 'where', |
|
34 'with') |
|
35 |
|
36 modulewords = ('implementation', 'definition', 'system') |
|
37 |
|
38 lowerId = r'[a-z`][\w\d`]*' |
|
39 upperId = r'[A-Z`][\w\d`]*' |
|
40 funnyId = r'[~@#\$%\^?!+\-*<>\\/|&=:]+' |
|
41 scoreUpperId = r'_' + upperId |
|
42 scoreLowerId = r'_' + lowerId |
|
43 moduleId = r'[a-zA-Z_][a-zA-Z0-9_.`]+' |
|
44 classId = '|'.join([lowerId, upperId, funnyId]) |
|
45 |
|
46 tokens = { |
|
47 'root': [ |
|
48 include('comments'), |
|
49 include('keywords'), |
|
50 include('module'), |
|
51 include('import'), |
|
52 include('whitespace'), |
|
53 include('literals'), |
|
54 include('operators'), |
|
55 include('delimiters'), |
|
56 include('names'), |
|
57 ], |
|
58 'whitespace': [ |
|
59 (r'\s+', Whitespace), |
|
60 ], |
|
61 'comments': [ |
|
62 (r'//.*\n', Comment.Single), |
|
63 (r'/\*', Comment.Multi, 'comments.in'), |
|
64 (r'/\*\*', Comment.Special, 'comments.in'), |
|
65 ], |
|
66 'comments.in': [ |
|
67 (r'\*\/', Comment.Multi, '#pop'), |
|
68 (r'/\*', Comment.Multi, '#push'), |
|
69 (r'[^*/]+', Comment.Multi), |
|
70 (r'\*(?!/)', Comment.Multi), |
|
71 (r'/', Comment.Multi), |
|
72 ], |
|
73 'keywords': [ |
|
74 (words(keywords, prefix=r'\b', suffix=r'\b'), Keyword), |
|
75 ], |
|
76 'module': [ |
|
77 (words(modulewords, prefix=r'\b', suffix=r'\b'), Keyword.Namespace), |
|
78 (r'\bmodule\b', Keyword.Namespace, 'module.name'), |
|
79 ], |
|
80 'module.name': [ |
|
81 include('whitespace'), |
|
82 (moduleId, Name.Class, '#pop'), |
|
83 ], |
|
84 'import': [ |
|
85 (r'\b(import)\b(\s*)', bygroups(Keyword, Whitespace), 'import.module'), |
|
86 (r'\b(from)\b(\s*)\b(' + moduleId + r')\b(\s*)\b(import)\b', |
|
87 bygroups(Keyword, Whitespace, Name.Class, Whitespace, Keyword), |
|
88 'import.what'), |
|
89 ], |
|
90 'import.module': [ |
|
91 (r'\b(qualified)\b(\s*)', bygroups(Keyword, Whitespace)), |
|
92 (r'(\s*)\b(as)\b', bygroups(Whitespace, Keyword), ('#pop', 'import.module.as')), |
|
93 (moduleId, Name.Class), |
|
94 (r'(\s*)(,)(\s*)', bygroups(Whitespace, Punctuation, Whitespace)), |
|
95 (r'\s*', Whitespace, '#pop'), |
|
96 ], |
|
97 'import.module.as': [ |
|
98 include('whitespace'), |
|
99 (lowerId, Name.Class, '#pop'), |
|
100 (upperId, Name.Class, '#pop'), |
|
101 ], |
|
102 'import.what': [ |
|
103 (r'\b(class)\b(\s+)(' + classId + r')', |
|
104 bygroups(Keyword, Whitespace, Name.Class), 'import.what.class'), |
|
105 (r'\b(instance)(\s+)(' + classId + r')(\s+)', |
|
106 bygroups(Keyword, Whitespace, Name.Class, Whitespace), 'import.what.instance'), |
|
107 (r'(::)(\s*)\b(' + upperId + r')\b', |
|
108 bygroups(Punctuation, Whitespace, Name.Class), 'import.what.type'), |
|
109 (r'\b(generic)\b(\s+)\b(' + lowerId + '|' + upperId + r')\b', |
|
110 bygroups(Keyword, Whitespace, Name)), |
|
111 include('names'), |
|
112 (r'(,)(\s+)', bygroups(Punctuation, Whitespace)), |
|
113 (r'$', Whitespace, '#pop'), |
|
114 include('whitespace'), |
|
115 ], |
|
116 'import.what.class': [ |
|
117 (r',', Punctuation, '#pop'), |
|
118 (r'\(', Punctuation, 'import.what.class.members'), |
|
119 (r'$', Whitespace, '#pop:2'), |
|
120 include('whitespace'), |
|
121 ], |
|
122 'import.what.class.members': [ |
|
123 (r',', Punctuation), |
|
124 (r'\.\.', Punctuation), |
|
125 (r'\)', Punctuation, '#pop'), |
|
126 include('names'), |
|
127 ], |
|
128 'import.what.instance': [ |
|
129 (r'[,)]', Punctuation, '#pop'), |
|
130 (r'\(', Punctuation, 'import.what.instance'), |
|
131 (r'$', Whitespace, '#pop:2'), |
|
132 include('whitespace'), |
|
133 include('names'), |
|
134 ], |
|
135 'import.what.type': [ |
|
136 (r',', Punctuation, '#pop'), |
|
137 (r'[({]', Punctuation, 'import.what.type.consesandfields'), |
|
138 (r'$', Whitespace, '#pop:2'), |
|
139 include('whitespace'), |
|
140 ], |
|
141 'import.what.type.consesandfields': [ |
|
142 (r',', Punctuation), |
|
143 (r'\.\.', Punctuation), |
|
144 (r'[)}]', Punctuation, '#pop'), |
|
145 include('names'), |
|
146 ], |
|
147 'literals': [ |
|
148 (r'\'([^\'\\]|\\(x[\da-fA-F]+|\d+|.))\'', Literal.Char), |
|
149 (r'[+~-]?0[0-7]+\b', Number.Oct), |
|
150 (r'[+~-]?\d+\.\d+(E[+-]?\d+)?', Number.Float), |
|
151 (r'[+~-]?\d+\b', Number.Integer), |
|
152 (r'[+~-]?0x[\da-fA-F]+\b', Number.Hex), |
|
153 (r'True|False', Literal), |
|
154 (r'"', String.Double, 'literals.stringd'), |
|
155 ], |
|
156 'literals.stringd': [ |
|
157 (r'[^\\"\n]+', String.Double), |
|
158 (r'"', String.Double, '#pop'), |
|
159 (r'\\.', String.Double), |
|
160 (r'[$\n]', Error, '#pop'), |
|
161 ], |
|
162 'operators': [ |
|
163 (r'[-~@#\$%\^?!+*<>\\/|&=:\.]+', Operator), |
|
164 (r'\b_+\b', Operator), |
|
165 ], |
|
166 'delimiters': [ |
|
167 (r'[,;(){}\[\]]', Punctuation), |
|
168 (r'(\')([\w`.]+)(\')', |
|
169 bygroups(Punctuation, Name.Class, Punctuation)), |
|
170 ], |
|
171 'names': [ |
|
172 (lowerId, Name), |
|
173 (scoreLowerId, Name), |
|
174 (funnyId, Name.Function), |
|
175 (upperId, Name.Class), |
|
176 (scoreUpperId, Name.Class), |
|
177 ] |
|
178 } |