85 lines
1.7 KiB
JavaScript
85 lines
1.7 KiB
JavaScript
module.exports = grammar({
|
|
name: 'minizinc',
|
|
|
|
extras: $ => [/\s/, $.line_comment, $.block_comment],
|
|
|
|
word: $ => $.identifier,
|
|
|
|
rules: {
|
|
source_file: $ => seq(sepBy(';', $._items), optional(';')),
|
|
|
|
_items: $ => choice(
|
|
$.assignment_item,
|
|
// TODO: Other statements types
|
|
),
|
|
|
|
assignment_item: $ => seq(
|
|
field('name', $.identifier),
|
|
'=',
|
|
field('expr', $._expression)
|
|
),
|
|
|
|
_expression: $ => choice(
|
|
$._literal,
|
|
$.identifier,
|
|
// TODO: Other expression types
|
|
),
|
|
|
|
|
|
_literal: $ => choice(
|
|
$.absent,
|
|
$.boolean_literal,
|
|
$.float_literal,
|
|
$.integer_literal,
|
|
$.string_literal,
|
|
),
|
|
|
|
absent: $ => '<>',
|
|
boolean_literal: $ => choice('true', 'false'),
|
|
float_literal: $ => token(choice(
|
|
/\d+\.\d+/,
|
|
/\d+(\.\d+)?[Ee][+-]?\d+/,
|
|
// TODO: Hexadecimal floating point numbers
|
|
)),
|
|
integer_literal: $ => token(choice(
|
|
/[0-9]+/,
|
|
/0x[0-9a-fA-F]+/,
|
|
/0b[01]+/,
|
|
/0o[0-7]+/
|
|
)),
|
|
|
|
string_literal: $ => seq(
|
|
'"',
|
|
repeat(choice(
|
|
token.immediate(prec(1, /[^"\n\\]+/)),
|
|
$.escape_sequence
|
|
)),
|
|
'"'
|
|
),
|
|
escape_sequence: $ => token.immediate(seq(
|
|
'\\',
|
|
choice(
|
|
/[^xuU]/,
|
|
/\d{2,3}/,
|
|
/x[0-9a-fA-F]{2,}/,
|
|
/u[0-9a-fA-F]{4}/,
|
|
/U[0-9a-fA-F]{8}/
|
|
)
|
|
)),
|
|
|
|
identifier: $ => /[A-Za-z][A-Za-z0-9_]*/,
|
|
|
|
line_comment: $ => token(seq('%', /.*/)),
|
|
block_comment: $ => token(seq('/*', /([^*]|\*[^\/]|\n)*?\*?/, '*/')),
|
|
|
|
}
|
|
});
|
|
|
|
function sepBy1(sep, rule) {
|
|
return seq(rule, repeat(seq(sep, rule)))
|
|
}
|
|
|
|
function sepBy(sep, rule) {
|
|
return optional(sepBy1(sep, rule))
|
|
}
|