-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.js
87 lines (78 loc) · 1.88 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
var str = ($, delim) => {
var not_delim = new RegExp('[^' + delim + ']');
return seq(
delim,
repeat(choice($.escape_char, not_delim)),
delim,
)
};
module.exports = grammar({
name: 'alv',
rules: {
source_file: $ => seq(
optional($._sp),
repeat(seq($._expression, $._sp)),
),
// wc: white-space character
// sp: whitespace
_wc: $ => /[ \t\r\n]/,
_sp: $ => seq(
repeat1(choice($.comment, $._wc)),
),
// comment_nested: pair of braces
_comment_contents: $ => seq(
'(',
repeat(choice($._comment_contents, /[^)]/)),
')',
),
comment: $ => seq('#', $._comment_contents),
// pieces for atom definitions
_first: $ => /[a-zA-Z-_+*\/\.=~!?%]/,
_digit: $ => /[0-9]/,
_int: $ => prec(2, repeat1($._digit)),
_float: $ => choice(
seq(repeat1($._digit), '.', repeat($._digit)),
seq(repeat($._digit), '.', repeat1($._digit)),
),
escape_char: $ => /\\["'\\]/,
// atoms
sym: $ => seq(
$._first,
repeat(choice($._first, $._digit)),
),
num: $ => seq(
optional('-'),
choice($._float, $._int),
),
str: $ => choice(
str($, '"'),
str($, '\''),
),
_atom: $ => choice($.sym, $.num, $.str),
// expression: anything that has a value
// exp_list: list of expressions (potentially empty)
// with optional leading and trailing whitespace
// and required whitespace between expressions
_expression: $ => choice($._atom, $.cell),
tag: $ => seq(
'[',
repeat1($._digit),
']',
),
// wrap head for highlghting
head: $ => $._expression,
cell: $ => seq(
'(',
optional($.tag),
seq(
optional($._sp),
optional(seq(
$.head,
repeat(seq($._sp, $._expression)),
optional($._sp),
)),
),
')',
),
}
});