diff options
Diffstat (limited to 'crates/mbe/src/parser.rs')
-rw-r--r-- | crates/mbe/src/parser.rs | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index f3047972d..b90ae7015 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs | |||
@@ -4,7 +4,7 @@ | |||
4 | use smallvec::SmallVec; | 4 | use smallvec::SmallVec; |
5 | use syntax::SmolStr; | 5 | use syntax::SmolStr; |
6 | 6 | ||
7 | use crate::{tt_iter::TtIter, ExpandError, MetaTemplate}; | 7 | use crate::{tt_iter::TtIter, MetaTemplate, ParseError}; |
8 | 8 | ||
9 | #[derive(Clone, Debug, PartialEq, Eq)] | 9 | #[derive(Clone, Debug, PartialEq, Eq)] |
10 | pub(crate) enum Op { | 10 | pub(crate) enum Op { |
@@ -46,12 +46,12 @@ impl PartialEq for Separator { | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | pub(crate) fn parse_template(template: &tt::Subtree) -> Vec<Result<Op, ExpandError>> { | 49 | pub(crate) fn parse_template(template: &tt::Subtree) -> Result<Vec<Op>, ParseError> { |
50 | parse_inner(&template, Mode::Template) | 50 | parse_inner(&template, Mode::Template).into_iter().collect() |
51 | } | 51 | } |
52 | 52 | ||
53 | pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Vec<Result<Op, ExpandError>> { | 53 | pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<Vec<Op>, ParseError> { |
54 | parse_inner(&pattern, Mode::Pattern) | 54 | parse_inner(&pattern, Mode::Pattern).into_iter().collect() |
55 | } | 55 | } |
56 | 56 | ||
57 | #[derive(Clone, Copy)] | 57 | #[derive(Clone, Copy)] |
@@ -60,7 +60,7 @@ enum Mode { | |||
60 | Template, | 60 | Template, |
61 | } | 61 | } |
62 | 62 | ||
63 | fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ExpandError>> { | 63 | fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ParseError>> { |
64 | let mut src = TtIter::new(&tt); | 64 | let mut src = TtIter::new(&tt); |
65 | std::iter::from_fn(move || { | 65 | std::iter::from_fn(move || { |
66 | let first = src.next()?; | 66 | let first = src.next()?; |
@@ -71,7 +71,7 @@ fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ExpandError>> { | |||
71 | 71 | ||
72 | macro_rules! err { | 72 | macro_rules! err { |
73 | ($($tt:tt)*) => { | 73 | ($($tt:tt)*) => { |
74 | ExpandError::UnexpectedToken | 74 | ParseError::UnexpectedToken(($($tt)*).to_string()) |
75 | }; | 75 | }; |
76 | } | 76 | } |
77 | 77 | ||
@@ -81,7 +81,7 @@ macro_rules! bail { | |||
81 | }; | 81 | }; |
82 | } | 82 | } |
83 | 83 | ||
84 | fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Result<Op, ExpandError> { | 84 | fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Result<Op, ParseError> { |
85 | let res = match first { | 85 | let res = match first { |
86 | tt::TokenTree::Leaf(leaf @ tt::Leaf::Punct(tt::Punct { char: '$', .. })) => { | 86 | tt::TokenTree::Leaf(leaf @ tt::Leaf::Punct(tt::Punct { char: '$', .. })) => { |
87 | // Note that the '$' itself is a valid token inside macro_rules. | 87 | // Note that the '$' itself is a valid token inside macro_rules. |
@@ -93,7 +93,9 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
93 | tt::TokenTree::Subtree(subtree) => { | 93 | tt::TokenTree::Subtree(subtree) => { |
94 | let (separator, kind) = parse_repeat(src)?; | 94 | let (separator, kind) = parse_repeat(src)?; |
95 | let delimiter = subtree.delimiter; | 95 | let delimiter = subtree.delimiter; |
96 | let tokens = parse_inner(&subtree, mode); | 96 | let tokens = parse_inner(&subtree, mode) |
97 | .into_iter() | ||
98 | .collect::<Result<Vec<Op>, ParseError>>()?; | ||
97 | let subtree = MetaTemplate { tokens, delimiter }; | 99 | let subtree = MetaTemplate { tokens, delimiter }; |
98 | Op::Repeat { subtree, separator, kind } | 100 | Op::Repeat { subtree, separator, kind } |
99 | } | 101 | } |
@@ -102,7 +104,7 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
102 | static UNDERSCORE: SmolStr = SmolStr::new_inline("_"); | 104 | static UNDERSCORE: SmolStr = SmolStr::new_inline("_"); |
103 | 105 | ||
104 | if punct.char != '_' { | 106 | if punct.char != '_' { |
105 | return Err(ExpandError::UnexpectedToken); | 107 | return Err(ParseError::Expected("_".to_string())); |
106 | } | 108 | } |
107 | let name = UNDERSCORE.clone(); | 109 | let name = UNDERSCORE.clone(); |
108 | let kind = eat_fragment_kind(src, mode)?; | 110 | let kind = eat_fragment_kind(src, mode)?; |
@@ -135,7 +137,9 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
135 | tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()), | 137 | tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()), |
136 | tt::TokenTree::Subtree(subtree) => { | 138 | tt::TokenTree::Subtree(subtree) => { |
137 | let delimiter = subtree.delimiter; | 139 | let delimiter = subtree.delimiter; |
138 | let tokens = parse_inner(&subtree, mode); | 140 | let tokens = |
141 | parse_inner(&subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?; | ||
142 | |||
139 | let subtree = MetaTemplate { tokens, delimiter }; | 143 | let subtree = MetaTemplate { tokens, delimiter }; |
140 | Op::Subtree(subtree) | 144 | Op::Subtree(subtree) |
141 | } | 145 | } |
@@ -143,7 +147,7 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
143 | Ok(res) | 147 | Ok(res) |
144 | } | 148 | } |
145 | 149 | ||
146 | fn eat_fragment_kind<'a>(src: &mut TtIter<'a>, mode: Mode) -> Result<Option<SmolStr>, ExpandError> { | 150 | fn eat_fragment_kind<'a>(src: &mut TtIter<'a>, mode: Mode) -> Result<Option<SmolStr>, ParseError> { |
147 | if let Mode::Pattern = mode { | 151 | if let Mode::Pattern = mode { |
148 | src.expect_char(':').map_err(|()| err!("bad fragment specifier 1"))?; | 152 | src.expect_char(':').map_err(|()| err!("bad fragment specifier 1"))?; |
149 | let ident = src.expect_ident().map_err(|()| err!("bad fragment specifier 1"))?; | 153 | let ident = src.expect_ident().map_err(|()| err!("bad fragment specifier 1"))?; |
@@ -156,12 +160,12 @@ fn is_boolean_literal(lit: &tt::Literal) -> bool { | |||
156 | matches!(lit.text.as_str(), "true" | "false") | 160 | matches!(lit.text.as_str(), "true" | "false") |
157 | } | 161 | } |
158 | 162 | ||
159 | fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), ExpandError> { | 163 | fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), ParseError> { |
160 | let mut separator = Separator::Puncts(SmallVec::new()); | 164 | let mut separator = Separator::Puncts(SmallVec::new()); |
161 | for tt in src { | 165 | for tt in src { |
162 | let tt = match tt { | 166 | let tt = match tt { |
163 | tt::TokenTree::Leaf(leaf) => leaf, | 167 | tt::TokenTree::Leaf(leaf) => leaf, |
164 | tt::TokenTree::Subtree(_) => return Err(ExpandError::InvalidRepeat), | 168 | tt::TokenTree::Subtree(_) => return Err(ParseError::InvalidRepeat), |
165 | }; | 169 | }; |
166 | let has_sep = match &separator { | 170 | let has_sep = match &separator { |
167 | Separator::Puncts(puncts) => !puncts.is_empty(), | 171 | Separator::Puncts(puncts) => !puncts.is_empty(), |
@@ -169,7 +173,7 @@ fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), Exp | |||
169 | }; | 173 | }; |
170 | match tt { | 174 | match tt { |
171 | tt::Leaf::Ident(_) | tt::Leaf::Literal(_) if has_sep => { | 175 | tt::Leaf::Ident(_) | tt::Leaf::Literal(_) if has_sep => { |
172 | return Err(ExpandError::InvalidRepeat) | 176 | return Err(ParseError::InvalidRepeat) |
173 | } | 177 | } |
174 | tt::Leaf::Ident(ident) => separator = Separator::Ident(ident.clone()), | 178 | tt::Leaf::Ident(ident) => separator = Separator::Ident(ident.clone()), |
175 | tt::Leaf::Literal(lit) => separator = Separator::Literal(lit.clone()), | 179 | tt::Leaf::Literal(lit) => separator = Separator::Literal(lit.clone()), |
@@ -182,11 +186,11 @@ fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), Exp | |||
182 | match &mut separator { | 186 | match &mut separator { |
183 | Separator::Puncts(puncts) => { | 187 | Separator::Puncts(puncts) => { |
184 | if puncts.len() == 3 { | 188 | if puncts.len() == 3 { |
185 | return Err(ExpandError::InvalidRepeat); | 189 | return Err(ParseError::InvalidRepeat); |
186 | } | 190 | } |
187 | puncts.push(punct.clone()) | 191 | puncts.push(punct.clone()) |
188 | } | 192 | } |
189 | _ => return Err(ExpandError::InvalidRepeat), | 193 | _ => return Err(ParseError::InvalidRepeat), |
190 | } | 194 | } |
191 | continue; | 195 | continue; |
192 | } | 196 | } |
@@ -196,5 +200,5 @@ fn parse_repeat(src: &mut TtIter) -> Result<(Option<Separator>, RepeatKind), Exp | |||
196 | } | 200 | } |
197 | } | 201 | } |
198 | } | 202 | } |
199 | Err(ExpandError::InvalidRepeat) | 203 | Err(ParseError::InvalidRepeat) |
200 | } | 204 | } |