Skip to content

Commit 9e2bc15

Browse files
committed
Extend the ppx_tyre part.
1 parent 1f6ced2 commit 9e2bc15

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

README.md

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,72 @@ end
6666

6767
## `ppx_tyre` - Syntax Support for Tyre Routes
6868

69+
### Typed regular expressions
70+
6971
This PPX compiles
7072
```ocaml
71-
[%tyre {|re|}]
73+
[%tyre {|re|}]
74+
```
75+
into `'a Tyre.t`.
76+
77+
For instance, We can define a pattern that recognize strings of the form "dim:3x5" like so:
78+
79+
```ocaml
80+
# open Tyre ;;
81+
# let dim = [%tyre "dim:(?&int)x(?&int)"] ;;
82+
val dim : (int * int) Tyre.t
7283
```
73-
into `'a Tyre.t` and
84+
85+
The syntax `(?&id)` allows to call a typed regular expression named `id` of type `'a Tyre.t`, such as `Tyre.int`.
86+
87+
For convenience, you can also use *named* capture groups to name the captured elements.
88+
```ocaml
89+
# let dim = [%tyre "dim:(?<x>(?&int))x(?&y:int)"] ;;
90+
val dim : < x : int; y : int > Tyre.t
91+
```
92+
93+
Names given using the syntax `(?<foo>re)` will be used for the fields
94+
of the results. `(?&y:int)` is a shortcut for `(?<x>(?&int))`.
95+
This can also be used for alternatives, for instance:
96+
97+
```ocaml
98+
# let id_or_name = [%tyre "id:(?&id:int)|name:(?<name>[:alpha:]+)"] ;;
99+
val id_or_name : [ `id of int | `name of string ] Tyre.t
100+
```
101+
102+
Expressions of type `Tyre.t` can then be composed as part of bigger regular
103+
expressions, or compiled with `Tyre.compile`.
104+
See [tyre][]'s documentation for details.
105+
106+
### Routes
107+
108+
`ppx_tyre` can also be used for routing, in the style of `ppx_regexp`:
109+
74110
```ocaml
75111
function%tyre
76-
| {|re1|} as x1 -> e1
112+
| {|re1|} -> e1
77113
...
78-
| {|reN|} as x2 -> eN
114+
| {|reN|} -> eN
79115
```
80-
into `'a Type.route`, where `re`, `re1`, ... are regular expressions
81-
expressed in a slightly extended subset of PCRE. The interpretations are:
116+
117+
is turned into a `'a Type.route`, where `re`, `re1`, ... are regular expressions
118+
using the same syntax as above. `"re" as v` is considered like `(?<v>re)` and
119+
`"re1" | "re2"` is turned into a regular expression alternative.
120+
121+
Once routes are defined, matching is done with `Tyre.exec`.
122+
123+
### Details
124+
125+
The syntax follow Perl's syntax:
82126

83127
- `re?` extracts an option of what `re` extracts.
84128
- `re+`, `re*`, `re{n,m}` extracts a list of what `re` extracts.
85-
- `(?@qname)` refers to any identifier bound to a typed regular expression
129+
- `(?&qname)` refers to any identifier bound to a typed regular expression
86130
of type `'a Tyre.t`.
131+
- Normal parens are *non-capturing*.
132+
- There are two ways to capture:
133+
- Anonymous capture `(+re)`
134+
- Named capture `(?<v>re)`
87135
- One or more `(?<v>re)` at the top level can be used to bind variables
88136
instead of `as ...`.
89137
- One or more `(?<v>re)` in a sequence extracts an object where each method

0 commit comments

Comments
 (0)