@@ -33,8 +33,8 @@ act as alternatives — a command is permitted if it matches any one of them.
3333### ` define `
3434
3535Binds 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
3939Definitions may reference other definitions. The reference graph must be
4040acyclic (no recursion).
@@ -55,31 +55,41 @@ allow rg --help
5555
5656Angle-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
6669User-defined names are distinguished from built-in types by their presence in
6770a ` 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
110143The keyword-prefixed design reserves space for future statement types (e.g.
0 commit comments