diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 765e563..f0ee50c 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -29,12 +29,16 @@ pub fn parse<'a>(source: &'a str) -> Result, ParseError<'a, Vec {{ + ($inner:tt @ $($item:ident)::+ ( $($t:tt $val:tt $val2:tt),* )) => {{ + $($item)::+ ( $( $crate::_ast_t!($t $crate::_ast_ti!($inner, $val $val2)) )* ) + }}; + + ($inner:tt @ $($item:ident)::+ { $($name:ident $t:tt $val:tt $val2:tt),*}) => {{ $( - let $name = $crate::_ast_t!($t $crate::_ast_ti!($inner, $val $($val2)?)); + let $name = $crate::_ast_t!($t $crate::_ast_ti!($inner, $val $val2)); )* - $item { $($name,)* } + $($item)::+ { $($name,)* } }}; } @@ -58,6 +62,18 @@ macro_rules! _ast_t { #[macro_export] macro_rules! _ast_ti { + ($inner:ident, !*) => { + $crate::error::collect_recovered($inner) + }; + + ($inner:ident, @*) => { + $crate::error::collect_recovered($inner.next.unwrap().into_inner()) + }; + + ($inner:ident, @ @) => { + $inner.next().unwrap().try_into() + }; + ($inner:ident, ! $val:ident) => { $val::try_from(&mut $inner) }; diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index 44a942f..8a1dd53 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -1,7 +1,8 @@ use crate::{ Rule, ast::*, - error::{AstError, AstResult, GetParseError}, + ast_expr, + error::{AstError, AstResult, GetParseError, collect_recovered}, }; impl<'a> TryFrom> for Expression { @@ -32,15 +33,16 @@ impl<'a> TryFrom> for Expression { prefixes, postfixes: inner .map(|p| Postfix::try_from(p)) - .collect::>>()?, + .collect::>>() + .get()?, }) } else { Ok(exp) } } Rule::primary => Expression::try_from(inner.next().unwrap()), - Rule::static_path => Ok(Expression::Path(Path::try_from(pair)?)), - Rule::literal => Ok(Expression::Literal(Literal::try_from(pair)?)), + Rule::static_path => Ok(Expression::Path(Path::try_from(pair).get()?)), + Rule::literal => Ok(Expression::Literal(Literal::try_from(pair).get()?)), _ => unimplemented!("{rule:#?}"), } } @@ -72,27 +74,24 @@ impl<'a> TryFrom> for Postfix { Ok(match rule { Rule::postfix => Postfix::try_from(inner.next().unwrap())?, - Rule::field_px => Postfix::FieldAccess(Identifier::try_from(inner.next().unwrap()).get()?), + Rule::field_px => ast_expr!(inner@Postfix::FieldAccess(:@@)), - Rule::call_px => Postfix::Call(inner.map(Expression::try_from).collect::, - _, - >>()?), + Rule::call_px => ast_expr!(inner@Postfix::Call(:!*)), Rule::struct_px => Postfix::StructCall( inner .map(|p| { let mut pi = p.into_inner(); Ok(( - Identifier::try_from(pi.next().unwrap())?, - Expression::try_from(pi.next().unwrap())?, + Identifier::try_from(pi.next().unwrap()).get()?, + Expression::try_from(pi.next().unwrap()).get()?, )) }) - .collect::>>()?, + .collect::>>() + .get()?, ), - Rule::index_px => Postfix::Index(Expression::try_from(inner.next().unwrap())?), + Rule::index_px => ast_expr!(inner@Postfix::Index(:@@)), Rule::binary_px => { let op_pair = inner.next().unwrap(); @@ -115,7 +114,8 @@ impl<'a> TryFrom> for Postfix { unimplemented!("Binary operator not implemented yet: {}", op_pair.as_str()) } }; - Postfix::Binary(op, Expression::try_from(inner.next().unwrap())?) + + ast_expr!(inner@Postfix::Binary(:&op, :@@)) } Rule::macro_call_px => Postfix::MacroCall(inner.as_str().to_string()),