blob: ac6776ee23a9ff6597a39eb14a942207e87a215a (
plain)
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
|
WHITESPACE = _{ " "|"\t"|"\n"|"\r" }
keywords = { "as" | "else" }
escape = @{ ("\\" ~ "{{" ~ "{{"?) | ("\\" ~ "\\"+ ~ &"{{") }
raw_text = ${ ( escape | (!"{{" ~ ANY) )+ }
raw_block_text = ${ ( escape | (!"{{{{" ~ ANY) )* }
literal = { string_literal |
array_literal |
object_literal |
number_literal |
null_literal |
boolean_literal }
null_literal = @{ "null" ~ !symbol_char }
boolean_literal = @{ ("true"|"false") ~ !symbol_char }
number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? ~ !symbol_char }
json_char_double_quote = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
json_char_single_quote = {
!("'" | "\\") ~ ANY
| "\\" ~ ("'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
string_inner_double_quote = @{ json_char_double_quote* }
string_inner_single_quote = @{ json_char_single_quote* }
string_literal = ${ ("\"" ~ string_inner_double_quote ~ "\"") | ("'" ~ string_inner_single_quote ~ "'") }
array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" }
object_literal = { "{" ~ (string_literal ~ ":" ~ literal)?
~ ("," ~ string_literal ~ ":" ~ literal)* ~ "}" }
symbol_char = _{ASCII_ALPHANUMERIC|"-"|"_"|"$"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'}
partial_symbol_char = _{ASCII_ALPHANUMERIC|"-"|"_"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'|"/"|"."}
path_char = _{ "/" }
identifier = @{ symbol_char+ }
partial_identifier = @{ partial_symbol_char+ | ("[" ~ ANY+ ~ "]") | ("'" ~ (!"'" ~ ("\\'" | ANY))+ ~ "'") }
reference = ${ path_inline }
name = _{ subexpression | reference }
param = { !(keywords ~ !symbol_char) ~ (literal | reference | subexpression) }
hash = { identifier ~ "=" ~ param }
block_param = { "as" ~ "|" ~ identifier ~ identifier? ~ "|"}
exp_line = _{ identifier ~ (hash|param)* ~ block_param?}
partial_exp_line = _{ ((partial_identifier|name) ~ (hash|param)*) }
subexpression = { "(" ~ ((identifier ~ (hash|param)+) | reference) ~ ")" }
pre_whitespace_omitter = { "~" }
pro_whitespace_omitter = { "~" }
expression = { !invert_tag ~ "{{" ~ pre_whitespace_omitter? ~
((identifier ~ (hash|param)+) | name )
~ pro_whitespace_omitter? ~ "}}" }
html_expression_triple_bracket_legacy = _{ "{{{" ~ pre_whitespace_omitter? ~
((identifier ~ (hash|param)+) | name ) ~
pro_whitespace_omitter? ~ "}}}" }
html_expression_triple_bracket = _{ "{{" ~ pre_whitespace_omitter? ~ "{" ~
((identifier ~ (hash|param)+) | name ) ~
"}" ~ pro_whitespace_omitter? ~ "}}" }
amp_expression = _{ "{{" ~ pre_whitespace_omitter? ~ "&" ~ name ~
pro_whitespace_omitter? ~ "}}" }
html_expression = { (html_expression_triple_bracket_legacy | html_expression_triple_bracket)
| amp_expression }
decorator_expression = { "{{" ~ pre_whitespace_omitter? ~ "*" ~ exp_line ~
pro_whitespace_omitter? ~ "}}" }
partial_expression = { "{{" ~ pre_whitespace_omitter? ~ ">" ~ partial_exp_line
~ pro_whitespace_omitter? ~ "}}" }
invert_tag_item = { "else"|"^" }
invert_tag = { !escape ~ "{{" ~ pre_whitespace_omitter? ~ invert_tag_item
~ pro_whitespace_omitter? ~ "}}" }
helper_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ exp_line ~
pro_whitespace_omitter? ~ "}}" }
helper_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}" }
helper_block = _{ helper_block_start ~ template ~
(invert_tag ~ template)? ~ helper_block_end }
decorator_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ "*"
~ exp_line ~ pro_whitespace_omitter? ~ "}}" }
decorator_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}" }
decorator_block = _{ decorator_block_start ~ template ~
decorator_block_end }
partial_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ ">"
~ partial_exp_line ~ pro_whitespace_omitter? ~ "}}" }
partial_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ partial_identifier ~
pro_whitespace_omitter? ~ "}}" }
partial_block = _{ partial_block_start ~ template ~ partial_block_end }
raw_block_start = { "{{{{" ~ pre_whitespace_omitter? ~ exp_line ~
pro_whitespace_omitter? ~ "}}}}" }
raw_block_end = { "{{{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}}}" }
raw_block = _{ raw_block_start ~ raw_block_text ~ raw_block_end }
hbs_comment = { "{{!" ~ "--" ~ (!"--}}" ~ ANY)* ~ "--" ~ "}}" }
hbs_comment_compact = { "{{!" ~ (!"}}" ~ ANY)* ~ "}}" }
template = { (
raw_text |
expression |
html_expression |
helper_block |
raw_block |
hbs_comment |
hbs_comment_compact |
decorator_expression |
decorator_block |
partial_expression |
partial_block )* }
parameter = _{ param ~ EOI }
handlebars = _{ template ~ EOI }
// json path visitor
// Disallowed chars: Whitespace ! " # % & ' ( ) * + , . / ; < = > @ [ \ ] ^ ` { | } ~
path_id = @{ symbol_char+ }
path_raw_id = { (!"]" ~ ANY)* }
path_sep = _{ "/" | "." }
path_up = { ".." }
path_key = _{ "[" ~ path_raw_id ~ "]" }
path_root = { "@root" }
path_current = _{ "this" ~ path_sep | "./" }
path_item = _{ path_id|path_key }
path_local = { "@" }
path_inline = ${ path_current? ~ (path_root ~ path_sep)? ~ path_local? ~ (path_up ~ path_sep)* ~ path_item ~ (path_sep ~ path_item)* }
path = _{ path_inline ~ EOI }
|