-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.js
78 lines (77 loc) · 2.2 KB
/
grammar.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/// <reference types="tree-sitter-cli/dsl" />
module.exports = grammar({
name: "mdx",
conflicts: ($) => [],
precedences: ($) => [
[$.jsx_section, $.markdown_section],
[$.escaped_char, $.interpolation, $.markdown_word],
[$.new_line, $.interpolation_start],
],
externals: ($) => [
$.import_start,
$.interpolation_start,
$.interpolation_content,
$.eof,
$.jsx_string,
$.error,
],
// any non-newline whitespace
extras: ($) => [/[^/S/r/n]+/],
rules: {
document: ($) =>
repeat(seq(choice($.jsx_section, $.markdown_section), $.new_line)),
jsx_section: ($) =>
repeat1(
seq(
choice($.import_statement, $.html_component, $.jsx_component),
$.new_line,
),
),
// 1 or more non-empty lines
markdown_section: ($) =>
repeat1(
seq(
repeat1(choice($.escaped_char, $.interpolation, $.markdown_word)),
$.new_line,
),
),
interpolation: ($) =>
seq(
$.interpolation_start,
optional($.interpolation_content), // let the scanner determine everything
alias(/\}/, $.interpolation_end),
),
markdown_word: ($) => /[^\\\{\s\r\n]+/,
escaped_char: ($) => seq($.escape, token.immediate(/[^\s]/)),
escape: ($) => token.immediate(/\\/),
import_statement: ($) =>
seq(
// import at the start of the line
$.import_start,
optional(
seq(
choice(
// either {foo, possible_bar} or just foo
seq(
alias(/\{/, $.left_brace),
repeat(choice($.jsx_identifier, ",")),
alias(/\}/, $.right_brace),
),
$.jsx_identifier,
),
/from/,
),
),
$.jsx_string,
optional(alias(/;/, $.semicolon)),
),
// TODO
html_component: ($) => choice(),
jsx_component: ($) => seq(/[^\\]</, /.+/, /[^\\]\/>/),
jsx_identifier: ($) => /[$a-zA-z_][A-Za-z_0-9$]*/,
// taken from markdown
new_line: ($) => choice(token.immediate(/\n|\r\n/), $.eof),
// fallback: (_) => prec.dynamic(-100, "_"),
_whitespace: ($) => token.immediate(/[^/S/r/n]+/),
},
});