-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.js
149 lines (120 loc) · 4.26 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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
module.exports = grammar({
name: "surrealql",
extras: $ => [$.comment, /[\s\uFEFF\u2060\u200B\u00A0]/],
rules: {
source_file: $ => repeat($._statement),
comment: _ =>
token(
choice(
seq("--", /.*/),
seq("/*", /.*/, repeat(seq("\n", /.*/)), "*/"),
seq("#", /.*/),
seq("//", /.*/),
),
),
_statement: $ => seq(choice($.select_statement), optional($.semi_colon)),
semi_colon: _ => token(";"),
// Keywords
keyword_select: _ => token("SELECT"),
keyword_from: _ => token("FROM"),
keyword_only: _ => token("ONLY"),
keyword_value: _ => token("VALUE"),
keyword_as: _ => token("AS"),
keyword_omit: _ => token("OMIT"),
keyword_explain: _ => token("EXPLAIN"),
keyword_full: _ => token("FULL"),
keyword_parallel: _ => token("PARALLEL"),
keyword_timeout: _ => token("TIMEOUT"),
keyword_fetch: _ => token("FETCH"),
keyword_start_at: _ => token("START AT"),
keyword_limit: _ => token("LIMIT"),
keyword_by: _ => token("BY"),
keyword_rand: _ => token("RAND()"),
keyword_collate: _ => token("COLLATE"),
keyword_numeric: _ => token("NUMERIC"),
keyword_asc: _ => token("ASC"),
keyword_desc: _ => token("DESC"),
keyword_order_by: _ => token("ORDER BY"),
keyword_with: _ => token("WITH"),
keyword_index: _ => token("INDEX"),
keyword_no_index: _ => token("NOINDEX"),
keyword_where: _ => token("WHERE"),
keyword_split: _ => token("SPLIT"),
keyword_at: _ => token("AT"),
keyword_group_by: _ => token("GROUP BY"),
keyword_true: _ => token("TRUE"),
keyword_false: _ => token("FALSE"),
// Main statements
select_statement: $ => seq($._select_statement),
_select_statement: $ =>
prec.right(
seq(
$.select_clause,
optional($.omit_clause),
$.from_clause,
),
),
select_clause: $ =>
prec.right(seq($.keyword_select, optional($.keyword_value), $.fields)),
fields: $ => prec.right(commaSep1($.field)),
field: $ =>
seq($._aliasable_expression, optional(seq($.keyword_as, $.alias))),
_aliasable_expression: $ => choice($._expression),
from_clause: $ => seq(
$.keyword_from,
commaSep1($._from_targets),
optional($.with_clause),
optional($.where_clause),
optional($.split_clause),
optional($.group_by_clause),
optional($.order_by_clause),
optional($.limit_clause),
optional($.start_clause),
optional($.fetch_clause),
optional($.timeout_clause),
optional($.keyword_parallel),
optional($.explain_clause),
),
_from_targets: $ => seq(optional($.keyword_only), $.target),
target: $ => seq($.table, optional(seq(":", $.record))),
omit_clause: $ => seq($.keyword_omit, $.fields),
with_clause: $ =>
seq(
$.keyword_with,
choice($.keyword_no_index, seq($.keyword_index, commaSep1($.index))),
),
where_clause: $ => seq($.keyword_where),
split_clause: $ =>
seq($.keyword_split, optional($.keyword_at), commaSep1($.fields)),
group_by_clause: $ => seq($.keyword_group_by, commaSep1($.fields)),
order_by_clause: $ => seq($.keyword_order_by, commaSep1($.order_criteria)),
order_criteria: $ =>
seq(
$.fields,
optional(choice($.keyword_rand, $.keyword_collate, $.keyword_numeric)),
optional(choice($.keyword_asc, $.keyword_desc)),
),
limit_clause: $ => seq($.keyword_limit, optional($.keyword_by), $.number),
start_clause: $ => seq($.keyword_start_at, $.number),
fetch_clause: $ => seq($.keyword_fetch, commaSep1($.fields)),
timeout_clause: $ => seq($.keyword_timeout, $.number),
explain_clause: $ => seq($.keyword_explain, optional($.keyword_full)),
number: _ => /\d+/,
table: _ => /[a-zA-Z_][a-zA-Z0-9_]*/,
record: _ => /[\w\-]+/,
index: _ => /[a-zA-Z_][a-zA-Z0-9_]*/,
alias: _ => /[a-zA-Z_][a-zA-Z0-9_]*/,
asterisk_expression: _ => choice("*", seq(/[a-zA-Z_][a-zA-Z0-9_]*/, ".*")),
_expression: $ =>
choice(
/[a-zA-Z_][a-zA-Z0-9_]*/,
$.keyword_true,
$.keyword_false,
$.asterisk_expression,
$.number,
),
},
});
function commaSep1(rule) {
return seq(rule, repeat(seq(",", rule)));
}