-
Notifications
You must be signed in to change notification settings - Fork 1
/
template.pest
57 lines (56 loc) · 3.6 KB
/
template.pest
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
// WHITESPACE = _{ " " | NEWLINE }
linear_whitespace = _{ " " | "\t" }
vertical_whitespace = _{ "\n" | "\r" }
whitespace = _{ linear_whitespace | vertical_whitespace }
start_marker = _{ "{%" }
end_marker = _{ "%}" }
comment_start_marker = _{ "{#" }
comment_end_marker = _{ "#}" }
keyword_if = { "if" }
keyword_unless = { "unless" }
keyword_elif = _{ "elif" }
keyword_else = _{ "else" }
keyword_end = _{ "end" }
keyword_for = _{ "for" }
keyword_with = _{ "with" }
keyword_debug = _{ "debug" }
keywords = _{
keyword_if |
keyword_unless |
keyword_elif |
keyword_else |
keyword_end |
keyword_for |
keyword_with |
keyword_debug
}
property = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" | "-")* }
properties = { property ~ ("." ~ property)* }
function = { ASCII_ALPHA+ }
boolean = { "true" | "false" }
floating_point_number = { "-"? ~ ((ASCII_DIGIT* ~ "." ~ ASCII_DIGIT+) | (ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT*)) ~ (("e" | "E") ~ "-"? ~ ASCII_DIGIT+)? }
integer_number = { "-"? ~ ASCII_DIGIT+ }
number = { floating_point_number | integer_number }
string = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
null = { "null" }
array = { "[" ~ whitespace* ~ (expression ~ whitespace* ~ ("," ~ whitespace* ~ expression)* ~ whitespace* ~ ","?)? ~ whitespace* ~ "]" }
key_value_pair = { (property | string) ~ whitespace* ~ ":" ~ whitespace* ~ expression }
dictionary = { "{" ~ whitespace* ~ (key_value_pair ~ whitespace* ~ ("," ~ whitespace* ~ key_value_pair)* ~ whitespace* ~ ","?)? ~ whitespace* ~ "}" }
literal = { boolean | number | string | null | array | dictionary }
function_call = { function ~ whitespace* ~ ("(" ~ whitespace* ~ (expression ~ whitespace* ~ ("," ~ whitespace* ~ expression)*)? ~ whitespace* ~ ")")? }
expression = { !keywords ~ (literal | properties) ~ whitespace* ~ ("|" ~ whitespace* ~ function_call)* }
expression_template = { start_marker ~ whitespace* ~ expression ~ whitespace* ~ end_marker }
if_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ (keyword_unless | keyword_if) ~ whitespace+ ~ expression ~ whitespace* ~ end_marker ~ vertical_whitespace? }
elif_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ keyword_elif ~ whitespace+ ~ expression ~ whitespace* ~ end_marker ~ vertical_whitespace? }
else_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ keyword_else ~ whitespace* ~ end_marker ~ vertical_whitespace? }
end_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ keyword_end ~ whitespace* ~ end_marker ~ vertical_whitespace? }
if_elif_else_template = { if_template ~ sub_template ~ (elif_template ~ sub_template)* ~ (else_template ~ sub_template)? ~ end_template }
for_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ keyword_for ~ whitespace+ ~ property ~ whitespace+ ~ "in" ~ whitespace+ ~ expression ~ whitespace* ~ end_marker ~ vertical_whitespace? }
with_template = { linear_whitespace* ~ start_marker ~ whitespace* ~ keyword_with ~ whitespace+ ~ property ~ whitespace+ ~ "=" ~ whitespace+ ~ expression ~ whitespace* ~ end_marker ~ vertical_whitespace? ~ sub_template ~ end_template }
for_else_template = { for_template ~ sub_template ~ (else_template ~ sub_template)? ~ end_template }
comment = { comment_start_marker ~ (!comment_end_marker ~ ANY)+ ~ comment_end_marker ~ vertical_whitespace? }
debug_template = { start_marker ~ whitespace* ~ keyword_debug ~ whitespace+ ~ expression ~ whitespace* ~ end_marker ~ vertical_whitespace? }
template = { comment | debug_template | if_elif_else_template | for_else_template | with_template | expression_template }
character = @{ !start_marker ~ ANY }
sub_template = _{ (template | character)* }
file = { SOI ~ sub_template ~ EOI }