flux_syntax/parser/
utils.rs1use super::{LAngle, RAngle, lookahead::Peek};
4use crate::{
5 ParseCtxt, ParseResult,
6 lexer::{Delimiter, Token},
7};
8
9pub(crate) fn sep1<R>(
12 cx: &mut ParseCtxt,
13 sep: Token,
14 mut parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
15) -> ParseResult<Vec<R>> {
16 let mut items = vec![parse(cx)?];
17 while cx.advance_if(sep) {
18 items.push(parse(cx)?);
19 }
20 Ok(items)
21}
22
23pub(crate) fn repeat_while<P: Peek, R>(
26 cx: &mut ParseCtxt,
27 next: P,
28 mut parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
29) -> ParseResult<Vec<R>> {
30 let mut items = vec![];
31 while cx.peek(next) {
32 items.push(parse(cx)?);
33 }
34 Ok(items)
35}
36
37pub(crate) fn until<P: Peek, R>(
40 cx: &mut ParseCtxt,
41 end: P,
42 mut parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
43) -> ParseResult<Vec<R>> {
44 let mut items = vec![];
45 while !cx.peek(end) {
46 items.push(parse(cx)?);
47 }
48 Ok(items)
49}
50
51pub(crate) fn punctuated_with_trailing<E: Peek, R>(
57 cx: &mut ParseCtxt,
58 sep: Token,
59 end: E,
60 mut parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
61) -> ParseResult<(Vec<R>, bool)> {
62 let mut items = vec![];
63 let mut trailing = false;
64 while !cx.peek(end) {
65 items.push(parse(cx)?);
66 trailing = cx.advance_if(sep);
67 if !trailing {
68 break;
69 }
70 }
71 Ok((items, trailing))
72}
73
74pub(crate) fn punctuated_until<E: Peek, R>(
78 cx: &mut ParseCtxt,
79 sep: Token,
80 end: E,
81 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
82) -> ParseResult<Vec<R>> {
83 Ok(punctuated_with_trailing(cx, sep, end, parse)?.0)
84}
85
86pub(crate) fn delimited<R>(
88 cx: &mut ParseCtxt,
89 delim: Delimiter,
90 parse: impl FnOnce(&mut ParseCtxt) -> ParseResult<R>,
91) -> ParseResult<R> {
92 cx.expect(Token::OpenDelim(delim))?;
93 let r = parse(cx)?;
94 cx.expect(Token::CloseDelim(delim))?;
95 Ok(r)
96}
97
98pub(crate) fn opt_angle<R>(
99 cx: &mut ParseCtxt,
100 sep: Token,
101 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
102) -> ParseResult<Vec<R>> {
103 if !cx.peek(LAngle) {
104 return Ok(vec![]);
105 }
106 angle(cx, sep, parse)
107}
108
109pub(crate) fn angle<R>(
110 cx: &mut ParseCtxt,
111 sep: Token,
112 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
113) -> ParseResult<Vec<R>> {
114 cx.expect(LAngle)?;
115 let items = punctuated_until(cx, sep, RAngle, parse)?;
116 cx.expect(RAngle)?;
117 Ok(items)
118}
119
120fn punctuated_delimited<R>(
121 cx: &mut ParseCtxt,
122 delim: Delimiter,
123 sep: Token,
124 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
125) -> ParseResult<Vec<R>> {
126 cx.expect(Token::OpenDelim(delim))?;
127 let r = punctuated_until(cx, sep, Token::CloseDelim(delim), parse)?;
128 cx.expect(Token::CloseDelim(delim))?;
129 Ok(r)
130}
131
132pub(crate) fn brackets<R>(
133 cx: &mut ParseCtxt,
134 sep: Token,
135 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
136) -> ParseResult<Vec<R>> {
137 punctuated_delimited(cx, Delimiter::Bracket, sep, parse)
138}
139
140pub(crate) fn parens<R>(
141 cx: &mut ParseCtxt,
142 sep: Token,
143 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
144) -> ParseResult<Vec<R>> {
145 punctuated_delimited(cx, Delimiter::Parenthesis, sep, parse)
146}
147
148pub(crate) fn braces<R>(
149 cx: &mut ParseCtxt,
150 sep: Token,
151 parse: impl FnMut(&mut ParseCtxt) -> ParseResult<R>,
152) -> ParseResult<Vec<R>> {
153 punctuated_delimited(cx, Delimiter::Brace, sep, parse)
154}