diff options
author | Edwin Cheng <[email protected]> | 2021-01-29 16:21:43 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2021-01-29 16:21:43 +0000 |
commit | 706ac8256d878626126756969b48b262d2e187b5 (patch) | |
tree | 8adb77484d4563ad61fc76ed9796d38a42a161e8 /crates/mbe/src/lib.rs | |
parent | 3ecd5112bbc2cc1a45f423e0256230507f159162 (diff) |
Simplify mbe match error.
Handle parse error in rule parsing instead of match in mbe
Diffstat (limited to 'crates/mbe/src/lib.rs')
-rw-r--r-- | crates/mbe/src/lib.rs | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs index bbe71ce3e..56c632665 100644 --- a/crates/mbe/src/lib.rs +++ b/crates/mbe/src/lib.rs | |||
@@ -24,7 +24,9 @@ use crate::{ | |||
24 | 24 | ||
25 | #[derive(Debug, PartialEq, Eq)] | 25 | #[derive(Debug, PartialEq, Eq)] |
26 | pub enum ParseError { | 26 | pub enum ParseError { |
27 | UnexpectedToken(String), | ||
27 | Expected(String), | 28 | Expected(String), |
29 | InvalidRepeat, | ||
28 | RepetitionEmptyTokenTree, | 30 | RepetitionEmptyTokenTree, |
29 | } | 31 | } |
30 | 32 | ||
@@ -34,7 +36,6 @@ pub enum ExpandError { | |||
34 | UnexpectedToken, | 36 | UnexpectedToken, |
35 | BindingError(String), | 37 | BindingError(String), |
36 | ConversionError, | 38 | ConversionError, |
37 | InvalidRepeat, | ||
38 | ProcMacroError(tt::ExpansionError), | 39 | ProcMacroError(tt::ExpansionError), |
39 | UnresolvedProcMacro, | 40 | UnresolvedProcMacro, |
40 | Other(String), | 41 | Other(String), |
@@ -53,7 +54,6 @@ impl fmt::Display for ExpandError { | |||
53 | ExpandError::UnexpectedToken => f.write_str("unexpected token in input"), | 54 | ExpandError::UnexpectedToken => f.write_str("unexpected token in input"), |
54 | ExpandError::BindingError(e) => f.write_str(e), | 55 | ExpandError::BindingError(e) => f.write_str(e), |
55 | ExpandError::ConversionError => f.write_str("could not convert tokens"), | 56 | ExpandError::ConversionError => f.write_str("could not convert tokens"), |
56 | ExpandError::InvalidRepeat => f.write_str("invalid repeat expression"), | ||
57 | ExpandError::ProcMacroError(e) => e.fmt(f), | 57 | ExpandError::ProcMacroError(e) => e.fmt(f), |
58 | ExpandError::UnresolvedProcMacro => f.write_str("unresolved proc macro"), | 58 | ExpandError::UnresolvedProcMacro => f.write_str("unresolved proc macro"), |
59 | ExpandError::Other(e) => f.write_str(e), | 59 | ExpandError::Other(e) => f.write_str(e), |
@@ -94,11 +94,11 @@ struct Rule { | |||
94 | #[derive(Clone, Debug, PartialEq, Eq)] | 94 | #[derive(Clone, Debug, PartialEq, Eq)] |
95 | struct MetaTemplate { | 95 | struct MetaTemplate { |
96 | delimiter: Option<Delimiter>, | 96 | delimiter: Option<Delimiter>, |
97 | tokens: Vec<Result<Op, ExpandError>>, | 97 | tokens: Vec<Op>, |
98 | } | 98 | } |
99 | 99 | ||
100 | impl<'a> MetaTemplate { | 100 | impl<'a> MetaTemplate { |
101 | fn iter(&self) -> impl Iterator<Item = &Result<Op, ExpandError>> { | 101 | fn iter(&self) -> impl Iterator<Item = &Op> { |
102 | self.tokens.iter() | 102 | self.tokens.iter() |
103 | } | 103 | } |
104 | 104 | ||
@@ -288,25 +288,15 @@ impl Rule { | |||
288 | .expect_subtree() | 288 | .expect_subtree() |
289 | .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; | 289 | .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; |
290 | 290 | ||
291 | let lhs = MetaTemplate { tokens: parse_pattern(&lhs), delimiter: None }; | 291 | let lhs = MetaTemplate { tokens: parse_pattern(&lhs)?, delimiter: None }; |
292 | let rhs = MetaTemplate { tokens: parse_template(&rhs), delimiter: None }; | 292 | let rhs = MetaTemplate { tokens: parse_template(&rhs)?, delimiter: None }; |
293 | 293 | ||
294 | Ok(crate::Rule { lhs, rhs }) | 294 | Ok(crate::Rule { lhs, rhs }) |
295 | } | 295 | } |
296 | } | 296 | } |
297 | 297 | ||
298 | fn to_parse_error(e: &ExpandError) -> ParseError { | ||
299 | let msg = match e { | ||
300 | ExpandError::InvalidRepeat => "invalid repeat".to_string(), | ||
301 | _ => "invalid macro definition".to_string(), | ||
302 | }; | ||
303 | ParseError::Expected(msg) | ||
304 | } | ||
305 | |||
306 | fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { | 298 | fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { |
307 | for op in pattern.iter() { | 299 | for op in pattern.iter() { |
308 | let op = op.as_ref().map_err(|e| to_parse_error(&e))?; | ||
309 | |||
310 | match op { | 300 | match op { |
311 | Op::Subtree(subtree) => validate(&subtree)?, | 301 | Op::Subtree(subtree) => validate(&subtree)?, |
312 | Op::Repeat { subtree, separator, .. } => { | 302 | Op::Repeat { subtree, separator, .. } => { |
@@ -315,20 +305,21 @@ fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { | |||
315 | 305 | ||
316 | if separator.is_none() { | 306 | if separator.is_none() { |
317 | if subtree.iter().all(|child_op| { | 307 | if subtree.iter().all(|child_op| { |
318 | match child_op.as_ref().map_err(to_parse_error) { | 308 | match child_op { |
319 | Ok(Op::Var { kind, .. }) => { | 309 | Op::Var { kind, .. } => { |
320 | // vis is optional | 310 | // vis is optional |
321 | if kind.as_ref().map_or(false, |it| it == "vis") { | 311 | if kind.as_ref().map_or(false, |it| it == "vis") { |
322 | return true; | 312 | return true; |
323 | } | 313 | } |
324 | } | 314 | } |
325 | Ok(Op::Repeat { kind, .. }) => { | 315 | Op::Repeat { kind, .. } => { |
326 | return matches!( | 316 | return matches!( |
327 | kind, | 317 | kind, |
328 | parser::RepeatKind::ZeroOrMore | parser::RepeatKind::ZeroOrOne | 318 | parser::RepeatKind::ZeroOrMore | parser::RepeatKind::ZeroOrOne |
329 | ) | 319 | ) |
330 | } | 320 | } |
331 | _ => {} | 321 | Op::Leaf(_) => {} |
322 | Op::Subtree(_) => {} | ||
332 | } | 323 | } |
333 | false | 324 | false |
334 | }) { | 325 | }) { |