-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgrammar.js
41 lines (32 loc) · 1.34 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
/**
* @file Email parser
* @author Steven Xu <[email protected]>
* @license MIT
*/
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
const SPECIAL = /[()<>@,;:\\".\[\]]/
const CTL = /[\x00-\x1f\x7f]/
export default grammar({
name: 'mail',
extras: (_$) => [' '],
rules: {
source_file: ($) => seq($._headers, optional(seq($.body_separator, $.body))),
_headers: ($) => repeat1(seq($._header, '\n')),
_header: ($) => choice(prec(1, $.header_email), prec(1, $.header_subject), $.header_other),
header_email: ($) =>
seq($.header_field_email, $.header_separator, repeat(choice($.atom, $.quoted_string)), optional($.email)),
header_other: ($) => seq($.header_field, $.header_separator, $.header_unstructured),
header_subject: ($) => seq($.header_field_subject, $.header_separator, $.header_unstructured),
header_separator: (_$) => ':',
header_field: (_$) => new RegExp(`[^${CTL.source.slice(1, -1)}\\s:]+`),
header_field_email: (_$) => choice('From', 'To', 'Cc', 'Bcc', 'Reply-To'),
header_field_subject: (_$) => 'Subject',
header_unstructured: (_$) => /.*/,
atom: (_$) => new RegExp(`[^${SPECIAL.source.slice(1, -1)}\\s${CTL.source.slice(1, -1)}]+`),
quoted_string: (_$) => /"[^"\\\n]+"/,
email: (_$) => /<[^<>]+>/,
body_separator: (_$) => /\n/,
body: (_$) => /(.|\n)*/,
},
})