Skip to content

Commit 00697d9

Browse files
committed
command_filter: clarify language spec ambiguities
- Define <string> as excluding leading dash, <string:-> as allowing it - Allow pipe alternation inside both () and [] groups - Restrict modifiers to built-in types only - Add 1-unambiguous rule: reject patterns where argument ownership is undecidable - Clarify multi-element alternatives each consume one argument per element
1 parent 4f2888e commit 00697d9

1 file changed

Lines changed: 45 additions & 12 deletions

File tree

command_filter/LANGUAGE.md

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ act as alternatives — a command is permitted if it matches any one of them.
3333
### `define`
3434

3535
Binds a name to a sub-pattern that can be referenced elsewhere. The name must
36-
be wrapped in angle brackets and must not collide with built-in types
37-
(`string`, `path`).
36+
be wrapped in angle brackets and must not collide with the built-in type names
37+
`string` or `path`.
3838

3939
Definitions may reference other definitions. The reference graph must be
4040
acyclic (no recursion).
@@ -55,31 +55,41 @@ allow rg --help
5555

5656
Angle-bracketed names that match a single argument:
5757

58-
| Placeholder | Matches |
59-
|----------------|--------------------------------------|
60-
| `<string>` | Any argument |
61-
| `<string:->` | Any argument (dash-allowed modifier) |
62-
| `<path:r>` | A path the user can read |
63-
| `<path:w>` | A path the user can write |
64-
| `<name>` | Expands a `define`d sub-pattern |
58+
| Placeholder | Matches |
59+
|----------------|--------------------------------------------------|
60+
| `<string>` | Any argument that does not start with `-` |
61+
| `<string:->` | Any argument, including those starting with `-` |
62+
| `<path:r>` | A path the user can read |
63+
| `<path:w>` | A path the user can write |
64+
| `<name>` | Expands a `define`d sub-pattern |
65+
66+
Modifiers (the `:` suffix, e.g. `:-`, `:r`, `:w`) are only valid on built-in
67+
types. User-defined names must be plain `<name>` with no modifier.
6568

6669
User-defined names are distinguished from built-in types by their presence in
6770
a `define` statement.
6871

6972
### Groups and alternatives
7073

71-
Parentheses group elements. Pipe separates alternatives within a group:
74+
Parentheses `()` and square brackets `[]` both group elements. Pipe `|`
75+
separates alternatives within the closest enclosing group:
7276

7377
```
7478
(-g | -F)
7579
(-name <string:-> | -type <string:->)
80+
[-l | -t | -h]
7681
```
7782

78-
A group matches exactly one of its alternatives.
83+
A group matches exactly one of its alternatives. Each alternative may be a
84+
sequence of multiple elements, where each element consumes one argument:
85+
86+
```
87+
(-name <string:-> | -type <string:->) # each branch is two arguments
88+
```
7989

8090
### Optional
8191

82-
Square brackets mark an element or group as optional (zero or one):
92+
Square brackets mark a group as optional (zero or one):
8393

8494
```
8595
[<string>]
@@ -105,6 +115,29 @@ repetition of `...`:
105115
[-r | -f]... # zero or more of these flags
106116
```
107117

118+
## Ambiguity
119+
120+
Patterns must be **1-unambiguous**: at every point where matching could follow
121+
two paths (continue a repetition vs. advance to the next element, or choose
122+
between alternatives), the sets of arguments each path accepts must be
123+
disjoint. The matcher decides where each argument belongs by inspecting that
124+
argument alone, with no lookahead or backtracking.
125+
126+
A pattern that violates this property is rejected at parse time:
127+
128+
```
129+
<path:r>... <path:w> # error: both sides accept paths
130+
[<string>]... <string> # error: same type on both sides
131+
[<string:->]... <string> # error: <string:-> is a superset of <string>
132+
```
133+
134+
Valid patterns keep choice points disjoint:
135+
136+
```
137+
[-v | -r]... <string> # ok: literals are disjoint from <string>
138+
[<options>]... <string> # ok: options expand to dash-prefixed flags
139+
```
140+
108141
## Future extensions
109142

110143
The keyword-prefixed design reserves space for future statement types (e.g.

0 commit comments

Comments
 (0)