just playing with tangled
1// Copyright 2021 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15whitespace = _{ " " | "\t" | "\r" | "\n" | "\x0c" }
16
17// XID_CONTINUE: https://www.unicode.org/reports/tr31/#Default_Identifier_Syntax
18// +, -, .: often included in tag/bookmark name or version number
19// /: sometimes used as a tag/bookmark namespace separator
20identifier_part = @{ (XID_CONTINUE | "_" | "/")+ }
21identifier = @{
22 identifier_part ~ (("." | "-" | "+") ~ identifier_part)*
23}
24// TODO: remove "/", ".", "+" for consistency with fileset?
25strict_identifier_part = @{ (ASCII_ALPHANUMERIC | "_" | "/")+ }
26strict_identifier = @{
27 strict_identifier_part ~ (("." | "-" | "+") ~ strict_identifier_part)*
28}
29
30symbol = _{
31 identifier
32 | string_literal
33 | raw_string_literal
34}
35
36string_escape = @{
37 "\\"
38 ~ ("t" | "r" | "n" | "0" | "e" | ("x" ~ ASCII_HEX_DIGIT{2}) | "\"" | "\\")
39}
40string_content_char = @{ !("\"" | "\\") ~ ANY }
41string_content = @{ string_content_char+ }
42string_literal = ${ "\"" ~ (string_content | string_escape)* ~ "\"" }
43
44raw_string_content = @{ (!"'" ~ ANY)* }
45raw_string_literal = ${ "'" ~ raw_string_content ~ "'" }
46
47at_op = { "@" }
48pattern_kind_op = { ":" }
49
50parents_op = { "-" }
51children_op = { "+" }
52compat_parents_op = { "^" }
53
54dag_range_op = { "::" }
55dag_range_pre_op = { "::" }
56dag_range_post_op = { "::" }
57dag_range_all_op = { "::" }
58compat_dag_range_op = { ":" }
59compat_dag_range_pre_op = { ":" }
60compat_dag_range_post_op = { ":" }
61range_op = { ".." }
62range_pre_op = { ".." }
63range_post_op = { ".." }
64range_all_op = { ".." }
65range_ops = _{ dag_range_op | compat_dag_range_op | range_op }
66range_pre_ops = _{ dag_range_pre_op | compat_dag_range_pre_op | range_pre_op }
67range_post_ops = _{ dag_range_post_op | compat_dag_range_post_op | range_post_op }
68range_all_ops = _{ dag_range_all_op | range_all_op }
69
70negate_op = { "~" }
71union_op = { "|" }
72intersection_op = { "&" }
73difference_op = { "~" }
74compat_add_op = { "+" }
75compat_sub_op = { "-" }
76infix_op = _{ union_op | intersection_op | difference_op | compat_add_op | compat_sub_op }
77
78function = { function_name ~ "(" ~ whitespace* ~ function_arguments ~ whitespace* ~ ")" }
79function_name = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
80keyword_argument = { strict_identifier ~ whitespace* ~ "=" ~ whitespace* ~ expression }
81argument = _{ keyword_argument | expression }
82function_arguments = {
83 argument ~ (whitespace* ~ "," ~ whitespace* ~ argument)* ~ (whitespace* ~ ",")?
84 | ""
85}
86formal_parameters = {
87 strict_identifier ~ (whitespace* ~ "," ~ whitespace* ~ strict_identifier)* ~ (whitespace* ~ ",")?
88 | ""
89}
90
91string_pattern = { strict_identifier ~ pattern_kind_op ~ symbol }
92
93primary = {
94 "(" ~ whitespace* ~ expression ~ whitespace* ~ ")"
95 | function
96 | string_pattern
97 // "@" operator cannot be nested
98 | symbol ~ at_op ~ symbol
99 | symbol ~ at_op
100 | symbol
101 | at_op
102}
103
104neighbors_expression = _{ primary ~ (parents_op | children_op | compat_parents_op)* }
105
106range_expression = _{
107 neighbors_expression ~ range_ops ~ neighbors_expression
108 | neighbors_expression ~ range_post_ops
109 | range_pre_ops ~ neighbors_expression
110 | neighbors_expression
111 | range_all_ops
112}
113
114expression = {
115 (negate_op ~ whitespace*)* ~ range_expression
116 ~ (whitespace* ~ infix_op ~ whitespace* ~ (negate_op ~ whitespace*)* ~ range_expression)*
117}
118
119program_modifier = { strict_identifier ~ pattern_kind_op ~ !":" }
120program = _{
121 SOI ~ whitespace* ~ (program_modifier ~ whitespace*)? ~ expression ~ whitespace* ~ EOI
122}
123
124symbol_name = _{ SOI ~ symbol ~ EOI }
125
126function_alias_declaration = {
127 function_name ~ "(" ~ whitespace* ~ formal_parameters ~ whitespace* ~ ")"
128}
129alias_declaration = _{
130 SOI ~ (function_alias_declaration | strict_identifier) ~ EOI
131}