-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.js
121 lines (96 loc) · 2.63 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
const NL = token.immediate(/[\r\n]+/);
const PREC = {
comment: 1,
request: 2,
header: 3,
param: 4,
body: 5,
var: 6,
whitespace: 7,
new_line: 8,
}
module.exports = grammar({
name: "hurl",
word: $ => $.identifier,
extras: $ => [
$.comment,
],
rules: {
source_file: ($) => repeat($._statement),
// statements
_statement: ($) =>
choice($._declaration_statement, NL),
_declaration_statement: ($) => seq(
choice(
$.request_declaration,
$.header_declaration,
alias($.http_response_declaration, $.response),
$.assert_declaration,
alias($.request_body_declaration, $.body),
),
prec.left(PREC.whitespace, optional($._whitespace)),
),
// declarations
request_declaration: ($) =>
prec.left(PREC.request,
seq($._literal, $._whitespace, field("url", $.url)),
),
request_body_declaration: $ => choice(
$.json_request_declaration,
$.text_body_declaration
),
json_request_declaration: $ => prec.left(PREC.body, seq(/\{/, optional(repeat(choice(/\n/))), repeat(seq($._line, NL)), /\}\n\n/)),
text_body_declaration: $ => prec.left(PREC.body, seq(/```/, optional(repeat(choice(/\n/))), repeat(seq($._line, NL)), /```\n\n/)),
header_declaration: ($) =>
seq(
field("header_name", $.header_name),
":",
optional($._whitespace),
field("header_value", $.header_value)
),
http_response_declaration: $ => seq($.scheme_literal, $._whitespace, $.status_code_pattern),
assert_declaration: $ => seq('[', $.assert_literal, ']'),
// literals
_literal: ($) => choice($.request_literal, $.assert_literal),
request_literal: ($) =>
choice(
"GET",
"POST",
"PUT",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE",
"PATCH",
"LINK",
"UNLINK",
"PURGE",
"LOCK",
"UNLOCK",
"PROPFIND",
"VIEW",
$.const_pattern
),
assert_literal: $ => choice(
"QueryStringParams",
"FormParams",
"MultipartFormData",
"Cookies",
"Captures",
"Asserts",
"Options",
),
scheme_literal: $ => "HTTP",
// patterns
const_pattern: $ => /[A-Z_0-9\/\\\d]+/,
comment: _ => prec.left(PREC.comment, token(seq("#", /.*/, NL))),
status_code_pattern: $ => /[\d]{3}/,
header_name: ($) => /[a-zA-Z-_0-9]+/,
header_value: ($) =>
/[a-zA-Z\-_0-9\/\\]+/,
url: ($) => /\S+/,
_line: _ => /[^\n]+/,
identifier: _ => /[A-Za-z_.\d\u00A1-\uFFFF-]+/,
_whitespace: _ => repeat1(/[\t\v ]/),
},
});