Use Iro to generate MiniZinc syntax highlighters
1#################################################################
2## MiniZinc
3################################################################
4##
5## TODO: Add description
6##
7################################################################
8
9name = MiniZinc
10file_extensions [] = mzn, fzn, dzn;
11
12################################################################
13## Constants
14################################################################
15
16__id \= (\b[A-Za-z][A-Za-z0-9_]*|'[^']*')
17
18################################################################
19## Styles
20################################################################
21
22# TODO: Better colors for debugging purposes
23styles [] {
24
25 .builtin : style {
26 color = light_green
27 ace_scope = support.function
28 textmate_scope = support.function
29 pygments_scope = Name.Builtin
30 }
31
32 .comment : style {
33 color = yellow
34 italic = true
35 ace_scope = comment
36 textmate_scope = comment
37 pygments_scope = Comment
38 }
39
40 .constant : style {
41 color = white
42 ace_scope = constant.language
43 textmate_scope = constant.language
44 pygments_scope = Literal
45 }
46
47 .escape_char : style {
48 color = red
49 ace_scope = constant.character.escape
50 textmate_scope = constant.character.escape
51 pygments_scope = String.Escape
52 }
53
54 .escaped : style {
55 color = brown
56 ace_scope = text
57 textmate_scope = text
58 pygments_scope = Generic.Inserted
59 }
60
61 .function : style {
62 color = green
63 ace_scope = entity.name.function
64 textmate_scope = entity.name.function
65 pygments_scope = Name.Function
66 }
67
68 .global : style {
69 color = light_green
70 ace_scope = support.function
71 textmate_scope = support.function
72 pygments_scope = Name.Builtin.Pseudo
73 }
74
75 .illegal : style {
76 color = white
77 background_color = red
78 ace_scope = invalid.illegal
79 textmate_scope = invalid.illegal
80 pygments_scope = Generic.Error
81 }
82
83 .keyword : style {
84 color = cyan
85 ace_scope = keyword.control
86 textmate_scope = keyword.control
87 pygments_scope = Keyword
88 }
89
90 .numeric : style {
91 color = gold
92 ace_scope = constant.numeric
93 textmate_scope = constant.numeric
94 pygments_scope = Number
95 }
96
97 .operator : style {
98 color = orange
99 ace_scope = keyword.operator
100 textmate_scope = keyword.operator
101 pygments_scope = Operator
102 }
103
104 .punctuation : style {
105 color = light_yellow
106 ace_scope = punctuation
107 textmate_scope = punctuation
108 pygments_scope = Punctuation
109 }
110
111 .string : style {
112 color = white
113 ace_scope = string
114 textmate_scope = string
115 pygments_scope = String
116 }
117
118 .type : style {
119 color = blue
120 ace_scope = storage.type
121 textmate_scope = storage.type
122 pygments_scope = Keyword.Type
123 }
124
125 .variable : style {
126 color = violet
127 ace_scope = variable
128 textmate_scope = variable
129 pygments_scope = Name.Variable
130 }
131
132}
133
134#################################################
135## Parse contexts
136#################################################
137
138contexts [] {
139
140##############################################
141## Main Context - Entry point context
142##############################################
143
144main : context {
145 #######################################
146 ## Comment Patterns
147 #######################################
148 : include "multi_line_comment";
149
150 : pattern {
151 description = line comment
152 regex \= (%.*)
153 styles [] = .comment;
154 }
155
156 # Escape to non-MiniZinc code or comments
157 : inline_push {
158 regex \= (@)
159 styles [] = .escaped;
160 default_style = .escaped
161 : pop {
162 regex \= (@)
163 styles [] = .escaped;
164 }
165 }
166
167 #######################################
168 ## Literal Patterns
169 #######################################
170 : include "numeric";
171 : include "string";
172
173 : pattern {
174 description = Boolean literal
175 regex \= (\b(?:true|false)\b)
176 styles [] = .constant;
177 }
178
179 #######################################
180 ## Operator Patterns
181 #######################################
182
183 : pattern {
184 description = logical operator
185 regex \= (\bnot\b|<->|->|<-|\\/|\bxor\b|/\\)
186 styles [] = .operator;
187 }
188
189 : pattern {
190 description = equality operator
191 regex \= (<|>|<=|>=|==|=|!=)
192 styles [] = .operator;
193 }
194
195 : pattern {
196 description = linear operator
197 regex \= (\+|-|\*|/|\bdiv\b|\bmod\b)
198 styles [] = .operator;
199 }
200
201 : pattern {
202 description = set operator
203 regex \= (\b(?:in|subset|superset|union|diff|symdiff|intersect|\.\.)\b)
204 styles [] = .operator;
205 }
206
207 #######################################
208 ## Punctuation Patterns
209 #######################################
210
211 : pattern {
212 description = terminator
213 regex \= (;)
214 styles [] = .punctuation;
215 }
216
217 : pattern {
218 regex \= (:)
219 styles [] = .punctuation;
220 }
221
222 : pattern {
223 regex \= (,)
224 styles [] = .punctuation;
225 }
226
227 : inline_push {
228 regex \= (\{)
229 styles [] = .punctuation;
230 : pop {
231 regex \= (\})
232 styles [] = .punctuation;
233 }
234 : pattern {
235 regex \= (\|)
236 styles [] = .punctuation;
237 }
238 : include "main";
239 }
240
241 : inline_push {
242 regex \= (\[)
243 styles [] = .punctuation;
244 : pop {
245 regex \= (\])
246 styles [] = .punctuation;
247 }
248 : pattern {
249 regex \= (\|)
250 styles [] = .punctuation;
251 }
252 : include "main";
253 }
254
255 : inline_push {
256 regex \= (\()
257 styles [] = .punctuation;
258 : pop {
259 regex \= (\))
260 styles [] = .punctuation;
261 }
262 : include "main";
263 }
264
265 : pattern {
266 description = unmatched bracket
267 regex \= (\}|\]|\))
268 styles[] = .illegal;
269 }
270
271 : pattern {
272 description = illegal pipe character
273 regex \= (\|)
274 styles[] = .illegal;
275 }
276
277 #######################################
278 ## Keyword Patterns
279 #######################################
280
281 : pattern {
282 description = item keyword
283 regex \= (\b(?:annotation|constraint|function|include|op|output|minimize|maximize|predicate|satisfy|solve|test|type)\b)
284 styles [] = .keyword;
285 }
286
287 : pattern {
288 description = type keyword
289 regex \= (\b(?:ann|array|bool|enum|float|int|list|of|par|set|string|tuple|var|record|any|opt)\b)
290 styles [] = .type;
291 }
292
293 : pattern {
294 description = expression keyword
295 regex \= (\b(?:for|forall|exists|if|then|elseif|else|endif|where|let|in)\b)
296 styles [] = .keyword;
297 }
298
299 : pattern {
300 description = reserved identifiers
301 regex \= (\b(?:case|op)\b)
302 styles [] = .illegal;
303 }
304
305 #######################################
306 ## Library Patterns
307 #######################################
308
309 : pattern {
310 description = builtin function (stdlib)
311 regex \= (\b(?:abort|abs|acosh|array_intersect|array_union|array1d|array2d|array3d|array4d|array5d|array6d|asin|assert|atan|bool2int|card|ceil|concat|cos|cosh|dom|dom_array|dom_size|fix|exp|floor|index_set|index_set_1of2|index_set_2of2|index_set_1of3|index_set_2of3|index_set_3of3|int2float|is_fixed|join|lb|lb_array|length|ln|log|log2|log10|min|max|pow|product|round|set2array|show|show_int|show_float|sin|sinh|sqrt|sum|tan|tanh|trace|ub|ub_array)\b)
312 styles [] = .builtin;
313 }
314
315 : pattern {
316 description = general predicates (globals)
317 regex \= (\b(?:circuit|disjoint|maximum|maximum_arg|member|minimum|minimum_arg|network_flow|network_flow_cost|partition_set|range|roots|sliding_sum|subcircuit|sum_pred)\b)
318 styles [] = .global;
319 }
320
321 : pattern {
322 description = all different and related constraints (globals)
323 regex \= (\b(?:alldifferent|all_different|all_disjoint|all_equal|alldifferent_except_0|nvalue|symmetric_all_different)\b)
324 styles [] = .global;
325 }
326
327 : pattern {
328 description = lexicographic constraints (globals)
329 regex \= (\b(?:lex2|lex_greater|lex_greatereq|lex_less|lex_lesseq|strict_lex2|value_precede|value_precede_chain)\b)
330 styles [] = .global;
331 }
332
333 : pattern {
334 description = sorting constraints (globals)
335 regex \= (\b(?:arg_sort|decreasing|increasing|sort)\b)
336 styles [] = .global;
337 }
338
339 : pattern {
340 description = channeling constraints (globals)
341 regex \= (\b(?:int_set_channel|inverse|inverse_set|link_set_to_booleans)\b)
342 styles [] = .global;
343 }
344
345 : pattern {
346 description = counting constraints (globals)
347 regex \= (\b(?:among|at_least|at_most|at_most1|count|count_eq|count_geq|count_gt|count_leq|count_lt|count_neq|distribute|exactly|global_cardinality|global_cardinality_closed|global_cardinality_low_up|global_cardinality_low_up_closed)\b)
348 styles [] = .global;
349 }
350
351 : pattern {
352 description = packing constraints (globals)
353 regex \= (\b(?:bin_packing|bin_packing_capa|bin_packing_load|diffn|diffn_k|diffn_nonstrict|diffn_nonstrict_k|geost|geost_bb|geost_smallest_bb|knapsack)\b)
354 styles [] = .global;
355 }
356
357 : pattern {
358 description = scheduling constraints (globals)
359 regex \= (\b(?:alternative|cumulative|disjunctive|disjunctive_strict|span)\b)
360 styles [] = .global;
361 }
362
363 : pattern {
364 description = extensional constraints (globals)
365 regex \= (\b(?:regular|regular_nfa|table)\b)
366 styles [] = .global;
367 }
368
369 #######################################
370 ## Identifier Patterns
371 #######################################
372
373 : inline_push {
374 description = function
375 regex \= $${__id}(\()
376 styles [] = .function, .punctuation;
377 : pop {
378 regex \= (\))
379 styles [] = .punctuation;
380 }
381 :include "main";
382 }
383
384 : pattern {
385 description = variable
386 regex \= $${__id}
387 styles [] = .variable;
388 }
389}
390
391#################################################
392## End of Contexts
393#################################################
394
395###########################################
396## Multi Line Comment Context
397###########################################
398
399multi_line_comment : context {
400 description = multi line comment
401 : inline_push {
402 regex \= (/\*)
403 styles [] = .comment;
404 default_style = .comment
405 : pop {
406 regex \= (\*/)
407 styles [] = .comment;
408 }
409 }
410}
411
412###########################################
413## Numeric Context
414###########################################
415
416numeric : context {
417 : pattern {
418 description = octal integer number
419 regex \= (\b0o[0-7]+)
420 styles [] = .numeric;
421 }
422 : pattern {
423 description = hexadecimal number
424 regex \= (\b0x[0-9A-Fa-f]+)
425 styles [] = .numeric;
426 }
427 : pattern {
428 description = hexadecimal number
429 regex \= (\b0x[0-9A-Fa-f]+)
430 styles [] = .numeric;
431 }
432 : pattern {
433 description = floating point number
434 regex \= (\b\d+(?:(?:.\d+)?[Ee][-+]?\d+|.\d+))
435 styles [] = .numeric;
436 }
437 : pattern {
438 description = integer number
439 regex \= (\b\d+)
440 styles [] = .numeric;
441 }
442}
443
444###########################################
445## String Context
446###########################################
447
448string : context {
449 : inline_push {
450 regex \= (\")
451 styles [] = .string;
452 : pop {
453 regex \= (\")
454 styles [] = .string;
455 }
456 : inline_push {
457 regex \= (\\\()
458 styles [] = .punctuation;
459 : pop {
460 regex \= (\))
461 styles [] = .punctuation;
462 }
463 : include "main";
464 }
465 : pattern {
466 regex \= (\\["'\\nrvt])
467 styles [] = .escape_char;
468 }
469 : pattern {
470 regex \= ([^\"\\]+)
471 styles [] = .string;
472 }
473 }
474}
475
476}