tamer: xir::parse::ele: AttrValueError for attr_parse!'s ValueError
This integrates the previous ValueError for `attr_parse!` into `ele_parse!`. DEV-7145main
parent
3a764d111e
commit
992c000b68
|
@ -39,42 +39,55 @@ pub struct EleParseCfg {
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! ele_parse {
|
||||
(type Object = $objty:ty; $($rest:tt)*) => {
|
||||
ele_parse!(@!nonterm_decl <$objty> $($rest)*);
|
||||
(
|
||||
// Attr has to be first to avoid ambiguity with `$rest`.
|
||||
$(type AttrValueError = $evty:ty;)?
|
||||
type Object = $objty:ty;
|
||||
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
ele_parse!(@!nonterm_decl <$objty, $($evty)?> $($rest)*);
|
||||
};
|
||||
|
||||
(@!nonterm_decl <$objty:ty> $nt:ident := $($rest:tt)*) => {
|
||||
ele_parse!(@!nonterm_def <$objty> $nt $($rest)*);
|
||||
(@!nonterm_decl <$objty:ty, $($evty:ty)?> $nt:ident := $($rest:tt)*) => {
|
||||
ele_parse!(@!nonterm_def <$objty, $($evty)?> $nt $($rest)*);
|
||||
};
|
||||
|
||||
(@!nonterm_def <$objty:ty>
|
||||
(@!nonterm_def <$objty:ty, $($evty:ty)?>
|
||||
$nt:ident $qname:ident $(($($ntp:tt)*))?
|
||||
{ $($matches:tt)* } $($rest:tt)*
|
||||
) => {
|
||||
ele_parse!(@!ele_expand_body <$objty> $nt $qname ($($($ntp)*)?) $($matches)*);
|
||||
ele_parse!(@!ele_expand_body <$objty, $($evty)?>
|
||||
$nt $qname ($($($ntp)*)?) $($matches)*
|
||||
);
|
||||
|
||||
ele_parse! {
|
||||
$(type AttrValueError = $evty;)?
|
||||
type Object = $objty;
|
||||
$($rest)*
|
||||
}
|
||||
};
|
||||
|
||||
(@!nonterm_def <$objty:ty> $nt:ident
|
||||
(@!nonterm_def <$objty:ty, $($evty:ty)?> $nt:ident
|
||||
($ntref_first:ident $(| $ntref:ident)+); $($rest:tt)*
|
||||
) => {
|
||||
ele_parse!(@!ele_dfn_sum <$objty> $nt [$ntref_first $($ntref)*]);
|
||||
ele_parse!(@!ele_dfn_sum <$objty>
|
||||
$nt [$ntref_first $($ntref)*]
|
||||
);
|
||||
|
||||
ele_parse! {
|
||||
$(type AttrValueError = $evty;)?
|
||||
type Object = $objty;
|
||||
$($rest)*
|
||||
}
|
||||
};
|
||||
|
||||
(@!nonterm_decl <$objty:ty>) => {};
|
||||
(@!nonterm_decl <$objty:ty, $($evty:ty)?>) => {};
|
||||
|
||||
// Expand the provided data to a more verbose form that provides the
|
||||
// context necessary for state transitions.
|
||||
(@!ele_expand_body <$objty:ty> $nt:ident $qname:ident ($($ntp:tt)*)
|
||||
(@!ele_expand_body <$objty:ty, $($evty:ty)?>
|
||||
$nt:ident $qname:ident ($($ntp:tt)*)
|
||||
@ { $($attrbody:tt)* } => $attrmap:expr,
|
||||
$(/$(($close_span:ident))? => $closemap:expr,)?
|
||||
|
||||
|
@ -86,7 +99,7 @@ macro_rules! ele_parse {
|
|||
)*
|
||||
) => {
|
||||
ele_parse! {
|
||||
@!ele_dfn_body <$objty> $nt $qname ($($ntp)*)
|
||||
@!ele_dfn_body <$objty, $($evty)?> $nt $qname ($($ntp)*)
|
||||
@ { $($attrbody)* } => $attrmap,
|
||||
/$($($close_span)?)? => ele_parse!(@!ele_close $($closemap)?),
|
||||
|
||||
|
@ -130,7 +143,9 @@ macro_rules! ele_parse {
|
|||
Self::Context::default()
|
||||
};
|
||||
|
||||
(@!ele_dfn_body <$objty:ty> $nt:ident $qname:ident ($($open_span:ident)?)
|
||||
(@!ele_dfn_body <$objty:ty, $($evty:ty)?>
|
||||
$nt:ident $qname:ident ($($open_span:ident)?)
|
||||
|
||||
// Attribute definition special form.
|
||||
@ {
|
||||
// We must lightly parse attributes here so that we can retrieve
|
||||
|
@ -162,6 +177,8 @@ macro_rules! ele_parse {
|
|||
) => {
|
||||
paste::paste! {
|
||||
crate::attr_parse! {
|
||||
$(type ValueError = $evty;)?
|
||||
|
||||
struct [<$nt AttrsState_>] -> [<$nt Attrs_>] {
|
||||
$(
|
||||
$(#[$fattr])*
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
//! the system,
|
||||
//! simply force the test to panic at the end.
|
||||
|
||||
use std::{error::Error, fmt::Display};
|
||||
|
||||
use crate::{
|
||||
convert::ExpectInto,
|
||||
diagnose::Diagnostic,
|
||||
|
@ -169,7 +171,45 @@ fn empty_element_with_attr_bindings() {
|
|||
struct Foo(SymbolId, SymbolId, (Span, Span));
|
||||
impl Object for Foo {}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct AttrVal(Attr);
|
||||
|
||||
impl TryFrom<Attr> for AttrVal {
|
||||
// Type must match AttrValueError on `ele_parse!`
|
||||
type Error = AttrValueError;
|
||||
|
||||
fn try_from(attr: Attr) -> Result<Self, Self::Error> {
|
||||
Ok(AttrVal(attr))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum AttrValueError {}
|
||||
|
||||
impl Error for AttrValueError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for AttrValueError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostic for AttrValueError {
|
||||
fn describe(&self) -> Vec<crate::diagnose::AnnotatedSpan> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
ele_parse! {
|
||||
// AttrValueError should be passed to `attr_parse!`
|
||||
// (which is invoked by `ele_parse!`)
|
||||
// as ValueError.
|
||||
type AttrValueError = AttrValueError;
|
||||
|
||||
type Object = Foo;
|
||||
|
||||
// In practice we wouldn't actually use Attr
|
||||
|
@ -177,12 +217,12 @@ fn empty_element_with_attr_bindings() {
|
|||
// but for the sake of this test we'll keep things simple.
|
||||
Sut := QN_PACKAGE {
|
||||
@ {
|
||||
name: (QN_NAME) => Attr,
|
||||
value: (QN_VALUE) => Attr,
|
||||
name: (QN_NAME) => AttrVal,
|
||||
value: (QN_VALUE) => AttrVal,
|
||||
} => Foo(
|
||||
name.value(),
|
||||
value.value(),
|
||||
(name.attr_span().value_span(), value.attr_span().value_span())
|
||||
name.0.value(),
|
||||
value.0.value(),
|
||||
(name.0.attr_span().value_span(), value.0.attr_span().value_span())
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue