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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::grammar;
use crate::{Parser, SyntaxKind};
use SyntaxKind::*;
pub fn longvid(p: &mut Parser) {
let _ng = p.start_node(LONG_VID);
while p.is_strid() && p.peek_next_nontrivia(1) == DOT {
strid(p);
p.eat_trivia();
assert!(p.eat(DOT));
p.eat_trivia();
}
vid(p)
}
pub fn vid(p: &mut Parser) {
if p.is_vid() {
p.eat_mapped(VID);
} else {
p.error("expected identifier");
}
}
pub fn longstrid(p: &mut Parser) {
let _ng = p.start_node(LONG_STRID);
grammar::sequential(p, strid, DOT);
}
pub fn strid(p: &mut Parser) {
if p.is_strid() {
p.eat_mapped(STRID);
} else {
p.error("expected structure identifier");
}
}
pub fn label(p: &mut Parser) {
match p.peek() {
IDENT | INT => {
if p.peek_text().starts_with('0') {
p.error("record labels may not start with \'0\'");
}
p.eat_mapped(LAB);
}
_ => p.error("expected label"),
}
}
#[cfg(test)]
mod tests {
use crate::tests::check_with_f;
use expect_test::expect;
#[test]
fn vid_alpha() {
check_with_f(
false,
crate::grammar::declaration,
"fun iamavid123456 x = 0",
expect![[r#"
FUN_DEC@0..23
FUN_KW@0..3 "fun"
WHITESPACE@3..4
FVAL_BIND@4..23
FVAL_BIND_ROW@4..23
VID@4..17 "iamavid123456"
WHITESPACE@17..18
VID_PAT@18..19
LONG_VID@18..19
VID@18..19 "x"
WHITESPACE@19..20
EQ@20..21 "="
WHITESPACE@21..22
SCON_EXP@22..23
INT@22..23 "0"
"#]],
)
}
#[test]
fn longvid() {
check_with_f(
false,
super::longvid,
"A.Long.Vid.StrId.x",
expect![[r#"
LONG_VID@0..18
STRID@0..1 "A"
DOT@1..2 "."
STRID@2..6 "Long"
DOT@6..7 "."
STRID@7..10 "Vid"
DOT@10..11 "."
STRID@11..16 "StrId"
DOT@16..17 "."
VID@17..18 "x"
"#]],
)
}
}