aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/lib.rs')
-rw-r--r--crates/mbe/src/lib.rs31
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)]
26pub enum ParseError { 26pub 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)]
95struct MetaTemplate { 95struct MetaTemplate {
96 delimiter: Option<Delimiter>, 96 delimiter: Option<Delimiter>,
97 tokens: Vec<Result<Op, ExpandError>>, 97 tokens: Vec<Op>,
98} 98}
99 99
100impl<'a> MetaTemplate { 100impl<'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
298fn 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
306fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { 298fn 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 }) {