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
|
grammar;
use crate::path::GenericPath;
use crate::path::GenericPathComponent;
pub PathList: Vec<GenericPath> = {
=> {
Vec::new()
},
<mut left:(<PathNoColons> COLON)*> <right:PathNoColons> => {
left.push(right);
left
},
};
pub PathListAllowingEmptyPaths: Vec<GenericPath> = {
=> vec![GenericPath {
components: Vec::new(),
starts_with_slash: false,
ends_with_slash: false,
}],
PathNoColons => vec![<>],
<mut left:PathListAllowingEmptyPaths> COLON => {
left.push(GenericPath {
components: Vec::new(),
starts_with_slash: false,
ends_with_slash: false,
});
left
},
<mut left:PathListAllowingEmptyPaths> COLON <right:PathNoColons> => {
left.push(right);
left
},
}
pub PathNoColons: GenericPath = {
SLASH => GenericPath {
components: Vec::new(),
starts_with_slash: true,
ends_with_slash: true,
},
<PathNoColons2> => GenericPath {
components: <>,
starts_with_slash: false,
ends_with_slash: false,
},
<PathNoColons2> SLASH => GenericPath {
components: <>,
starts_with_slash: false,
ends_with_slash: true,
},
SLASH <PathNoColons2> => GenericPath {
components: <>,
starts_with_slash: true,
ends_with_slash: false,
},
SLASH <PathNoColons2> SLASH => GenericPath {
components: <>,
starts_with_slash: true,
ends_with_slash: true,
},
}
PathNoColons2: Vec<GenericPathComponent> = {
<PathComponent> => vec![<>],
<mut left:PathNoColons2> SLASH <right:PathComponent> => {
left.push(right);
left
}
}
PathComponent: GenericPathComponent = {
DOT => GenericPathComponent::CurrentDirectory,
DOT_DOT => GenericPathComponent::ParentDirectory,
<PATH_COMPONENT_NO_COLONS> =>
GenericPathComponent::FileOrDirectoryName(<>.to_string())
}
// Whitespace is not allowed.
match {
r"[^:/]+" => PATH_COMPONENT_NO_COLONS,
r"/" => SLASH,
":" => COLON,
"." => DOT,
".." => DOT_DOT,
}
|