|
|
|
|
@ -1,3 +1,15 @@
|
|
|
|
|
/**
|
|
|
|
|
* @file JSON grammar for tree-sitter
|
|
|
|
|
* @author Max Brunsfeld
|
|
|
|
|
* @license MIT
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* eslint-disable arrow-parens */
|
|
|
|
|
/* eslint-disable camelcase */
|
|
|
|
|
/* eslint-disable-next-line spaced-comment */
|
|
|
|
|
/// <reference types="tree-sitter-cli/dsl" />
|
|
|
|
|
// @ts-check
|
|
|
|
|
|
|
|
|
|
module.exports = grammar({
|
|
|
|
|
name: 'json',
|
|
|
|
|
|
|
|
|
|
@ -7,7 +19,7 @@ module.exports = grammar({
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
supertypes: $ => [
|
|
|
|
|
$._value
|
|
|
|
|
$._value,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
rules: {
|
|
|
|
|
@ -20,80 +32,96 @@ module.exports = grammar({
|
|
|
|
|
$.string,
|
|
|
|
|
$.true,
|
|
|
|
|
$.false,
|
|
|
|
|
$.null
|
|
|
|
|
$.null,
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
object: $ => seq(
|
|
|
|
|
"{", commaSep($.pair), "}"
|
|
|
|
|
'{', commaSep($.pair), '}',
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
pair: $ => seq(
|
|
|
|
|
field("key", choice($.string, $.number)),
|
|
|
|
|
":",
|
|
|
|
|
field("value", $._value)
|
|
|
|
|
field('key', choice($.string, $.number)),
|
|
|
|
|
':',
|
|
|
|
|
field('value', $._value),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
array: $ => seq(
|
|
|
|
|
"[", commaSep($._value), "]"
|
|
|
|
|
'[', commaSep($._value), ']',
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
string: $ => choice(
|
|
|
|
|
seq('"', '"'),
|
|
|
|
|
seq('"', $.string_content, '"')
|
|
|
|
|
seq('"', $.string_content, '"'),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
string_content: $ => repeat1(choice(
|
|
|
|
|
token.immediate(prec(1, /[^\\"\n]+/)),
|
|
|
|
|
$.escape_sequence
|
|
|
|
|
$.escape_sequence,
|
|
|
|
|
)),
|
|
|
|
|
|
|
|
|
|
escape_sequence: _ => token.immediate(seq(
|
|
|
|
|
'\\',
|
|
|
|
|
/(\"|\\|\/|b|f|n|r|t|u)/
|
|
|
|
|
/(\"|\\|\/|b|f|n|r|t|u)/,
|
|
|
|
|
)),
|
|
|
|
|
|
|
|
|
|
number: _ => {
|
|
|
|
|
const decimal_digits = /\d+/
|
|
|
|
|
const signed_integer = seq(optional('-'), decimal_digits)
|
|
|
|
|
const exponent_part = seq(choice('e', 'E'), signed_integer)
|
|
|
|
|
const decimal_digits = /\d+/;
|
|
|
|
|
const signed_integer = seq(optional('-'), decimal_digits);
|
|
|
|
|
const exponent_part = seq(choice('e', 'E'), signed_integer);
|
|
|
|
|
|
|
|
|
|
const decimal_integer_literal = seq(
|
|
|
|
|
optional('-'),
|
|
|
|
|
choice(
|
|
|
|
|
'0',
|
|
|
|
|
seq(/[1-9]/, optional(decimal_digits))
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
seq(/[1-9]/, optional(decimal_digits)),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const decimal_literal = choice(
|
|
|
|
|
seq(decimal_integer_literal, '.', optional(decimal_digits), optional(exponent_part)),
|
|
|
|
|
seq(decimal_integer_literal, optional(exponent_part))
|
|
|
|
|
)
|
|
|
|
|
seq(decimal_integer_literal, optional(exponent_part)),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return token(decimal_literal)
|
|
|
|
|
return token(decimal_literal);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
true: _ => "true",
|
|
|
|
|
true: _ => 'true',
|
|
|
|
|
|
|
|
|
|
false: _ => "false",
|
|
|
|
|
false: _ => 'false',
|
|
|
|
|
|
|
|
|
|
null: _ => "null",
|
|
|
|
|
null: _ => 'null',
|
|
|
|
|
|
|
|
|
|
comment: _ => token(choice(
|
|
|
|
|
seq('//', /.*/),
|
|
|
|
|
seq(
|
|
|
|
|
'/*',
|
|
|
|
|
/[^*]*\*+([^/*][^*]*\*+)*/,
|
|
|
|
|
'/'
|
|
|
|
|
)
|
|
|
|
|
'/',
|
|
|
|
|
),
|
|
|
|
|
)),
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a rule to match one or more of the rules separated by a comma
|
|
|
|
|
*
|
|
|
|
|
* @param {RuleOrLiteral} rule
|
|
|
|
|
*
|
|
|
|
|
* @return {SeqRule}
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function commaSep1(rule) {
|
|
|
|
|
return seq(rule, repeat(seq(",", rule)))
|
|
|
|
|
return seq(rule, repeat(seq(',', rule)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a rule to optionally match one or more of the rules separated by a comma
|
|
|
|
|
*
|
|
|
|
|
* @param {RuleOrLiteral} rule
|
|
|
|
|
*
|
|
|
|
|
* @return {ChoiceRule}
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
function commaSep(rule) {
|
|
|
|
|
return optional(commaSep1(rule))
|
|
|
|
|
return optional(commaSep1(rule));
|
|
|
|
|
}
|
|
|
|
|
|