difftastic/vendor/tree-sitter-json/grammar.js

115 lines
2.2 KiB
JavaScript

module.exports = grammar({
name: 'json',
extras: $ => [
/\s/,
$.comment,
],
supertypes: $ => [
$._value
],
rules: {
document: $ => $._value,
_value: $ => choice(
$.object,
$.array,
$.number,
$.string,
$.true,
$.false,
$.null
),
object: $ => seq(
"{", commaSep($.pair), "}"
),
pair: $ => seq(
field("key", choice($.string, $.number)),
":",
field("value", $._value)
),
array: $ => seq(
"[", commaSep($._value), "]"
),
string: $ => choice(
seq('"', '"'),
seq('"', $.string_content, '"')
),
string_content: $ => repeat1(choice(
token.immediate(prec(1, /[^\\"\n]+/)),
$.escape_sequence
)),
escape_sequence: $ => token.immediate(seq(
'\\',
/(\"|\\|\/|b|f|n|r|t|u)/
)),
number: $ => {
const hex_literal = seq(
choice('0x', '0X'),
/[\da-fA-F]+/
)
const decimal_digits = /\d+/
const signed_integer = seq(optional(choice('-', '+')), decimal_digits)
const exponent_part = seq(choice('e', 'E'), signed_integer)
const binary_literal = seq(choice('0b', '0B'), /[0-1]+/)
const octal_literal = seq(choice('0o', '0O'), /[0-7]+/)
const decimal_integer_literal = seq(
optional(choice('-', '+')),
choice(
'0',
seq(/[1-9]/, optional(decimal_digits))
)
)
const decimal_literal = choice(
seq(decimal_integer_literal, '.', optional(decimal_digits), optional(exponent_part)),
seq('.', decimal_digits, optional(exponent_part)),
seq(decimal_integer_literal, optional(exponent_part))
)
return token(choice(
hex_literal,
decimal_literal,
binary_literal,
octal_literal
))
},
true: $ => "true",
false: $ => "false",
null: $ => "null",
comment: $ => token(choice(
seq('//', /.*/),
seq(
'/*',
/[^*]*\*+([^/*][^*]*\*+)*/,
'/'
)
)),
}
});
function commaSep1(rule) {
return seq(rule, repeat(seq(",", rule)))
}
function commaSep(rule) {
return optional(commaSep1(rule))
}