tamer: Re-introduce literal parsing for xmlns in NIR for PackageStmt
This _only_ re-introduces for PackageStmt since that's all I have tests for at present. More will be re-added later. They were previously removed when the attribute parsing was upended in `ele_parse!`. This does lose the attribute name, compared to before; that'll ideally be re-added, and I'll explore options for doing so later, since I also want them in other contexts. But it needs to be done generically (not XML-related). This had to be done before blowing up on TODOs, or system tests would fail. DEV-13708main
parent
acafe91ab9
commit
647e0ccbbd
|
@ -63,7 +63,6 @@ use crate::{
|
|||
sym::SymbolId,
|
||||
xir::{
|
||||
attr::{Attr, AttrSpan},
|
||||
fmt::TtXmlAttr,
|
||||
QName,
|
||||
},
|
||||
};
|
||||
|
@ -145,6 +144,19 @@ pub enum Nir {
|
|||
/// it may represent literate documentation or a literal in a
|
||||
/// metavariable definition.
|
||||
Text(SPair),
|
||||
|
||||
/// "No-op" (no operation) that does nothing.
|
||||
///
|
||||
/// Since this is taking user input and effectively discarding it,
|
||||
/// this contains a [`Span`],
|
||||
/// so that we can clearly see the source code associated with what we
|
||||
/// chose to discard.
|
||||
///
|
||||
/// Ideally this can be eliminated in the future by causing an
|
||||
/// incomplete parse,
|
||||
/// which is all this does in the end.
|
||||
/// See its uses for more information.
|
||||
Noop(Span),
|
||||
}
|
||||
|
||||
impl Nir {
|
||||
|
@ -167,6 +179,8 @@ impl Nir {
|
|||
|
||||
BindIdent(spair) | RefSubject(spair) | Ref(spair) | Desc(spair)
|
||||
| Text(spair) => Some(spair.symbol()),
|
||||
|
||||
Noop(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +214,8 @@ impl Functor<SymbolId> for Nir {
|
|||
Ref(spair) => Ref(spair.map(f)),
|
||||
Desc(spair) => Desc(spair.map(f)),
|
||||
Text(spair) => Text(spair.map(f)),
|
||||
|
||||
Noop(_) => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,6 +337,11 @@ impl Token for Nir {
|
|||
|
||||
BindIdent(spair) | RefSubject(spair) | Ref(spair) | Desc(spair)
|
||||
| Text(spair) => spair.span(),
|
||||
|
||||
// A no-op is discarding user input,
|
||||
// so we still want to know where that is so that we can
|
||||
// explicitly inquire about and report on it.
|
||||
Noop(span) => *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -352,6 +373,8 @@ impl Display for Nir {
|
|||
// need to determine how to handle newlines and other types of
|
||||
// output.
|
||||
Text(_) => write!(f, "text"),
|
||||
|
||||
Noop(_) => write!(f, "no-op"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,21 +534,14 @@ pub enum PkgType {
|
|||
Mod,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Literal<const S: SymbolId>;
|
||||
|
||||
impl<const S: SymbolId> TryFrom<Attr> for Literal<S> {
|
||||
type Error = NirAttrParseError;
|
||||
|
||||
fn try_from(attr: Attr) -> Result<Self, Self::Error> {
|
||||
match attr {
|
||||
Attr(_, val, _) if val == S => Ok(Literal),
|
||||
Attr(name, _, aspan) => Err(NirAttrParseError::LiteralMismatch(
|
||||
name,
|
||||
aspan.value_span(),
|
||||
S,
|
||||
)),
|
||||
}
|
||||
/// Assert that a literal value `S` was provided,
|
||||
/// yielding a [`Nir::Noop`] if successful.
|
||||
pub fn literal<const S: SymbolId>(
|
||||
value: SPair,
|
||||
) -> Result<Nir, NirAttrParseError> {
|
||||
match value {
|
||||
SPair(val, span) if val == S => Ok(Nir::Noop(span)),
|
||||
_ => Err(NirAttrParseError::LiteralMismatch(value.span(), S)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,7 +555,7 @@ type ExpectedSymbolId = SymbolId;
|
|||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum NirAttrParseError {
|
||||
LiteralMismatch(QName, Span, ExpectedSymbolId),
|
||||
LiteralMismatch(Span, ExpectedSymbolId),
|
||||
}
|
||||
|
||||
impl Error for NirAttrParseError {
|
||||
|
@ -551,8 +567,8 @@ impl Error for NirAttrParseError {
|
|||
impl Display for NirAttrParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::LiteralMismatch(name, _, _) => {
|
||||
write!(f, "unexpected value for {}", TtXmlAttr::wrap(name),)
|
||||
Self::LiteralMismatch(_, expected) => {
|
||||
write!(f, "expected literal {}", TtQuote::wrap(expected),)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -561,7 +577,7 @@ impl Display for NirAttrParseError {
|
|||
impl Diagnostic for NirAttrParseError {
|
||||
fn describe(&self) -> Vec<crate::diagnose::AnnotatedSpan> {
|
||||
match self {
|
||||
Self::LiteralMismatch(_, span, expected) => span
|
||||
Self::LiteralMismatch(span, expected) => span
|
||||
.error(format!("expecting {}", TtQuote::wrap(expected)))
|
||||
.into(),
|
||||
}
|
||||
|
|
|
@ -245,6 +245,8 @@ impl ParseState for NirToAir {
|
|||
(Ready, Todo(..) | TodoAttr(..)) => {
|
||||
Transition(Ready).ok(Air::Todo(UNKNOWN_SPAN))
|
||||
}
|
||||
|
||||
(st, Noop(_)) => Transition(st).incomplete(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
use super::{Nir::*, *};
|
||||
use crate::{
|
||||
ele_parse,
|
||||
sym::st::raw::*,
|
||||
xir::st::{prefix::*, qname::*},
|
||||
};
|
||||
|
||||
|
@ -227,15 +228,15 @@ ele_parse! {
|
|||
/// different package types.
|
||||
PackageStmt := QN_PACKAGE(_, ospan) {
|
||||
@ {
|
||||
QN_XMLNS => TodoAttr,
|
||||
QN_XMLNS_C => TodoAttr,
|
||||
QN_XMLNS_T => TodoAttr,
|
||||
QN_XMLNS => literal::<{URI_LV_RATER}>,
|
||||
QN_XMLNS_C => literal::<{URI_LV_CALC}>,
|
||||
QN_XMLNS_T => literal::<{URI_LV_TPL}>,
|
||||
|
||||
// TODO: Having trouble getting rid of `@xmlns:lv` using Saxon
|
||||
// for `progui-pkg`,
|
||||
// so just allow for now.
|
||||
// It can't actually be used on nodes.
|
||||
QN_XMLNS_LV => TodoAttr,
|
||||
QN_XMLNS_LV => literal::<{URI_LV_RATER}>,
|
||||
|
||||
QN_ID => TodoAttr,
|
||||
QN_TITLE => TodoAttr,
|
||||
|
|
|
@ -507,10 +507,12 @@ macro_rules! ele_parse {
|
|||
let $open_span = span;
|
||||
)?
|
||||
|
||||
Transition(Self(Attrs(
|
||||
(qname, span, depth),
|
||||
parse_attrs(qname, span)
|
||||
))).ok(<$objty>::from($attrmap))
|
||||
<$objty>::try_from($attrmap)
|
||||
.map($crate::parse::ParseStatus::Object)
|
||||
.transition(Self(Attrs(
|
||||
(qname, span, depth),
|
||||
parse_attrs(qname, span)
|
||||
)))
|
||||
},
|
||||
|
||||
// We only attempt recovery when encountering an
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
use core::fmt::Debug;
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
error::Error,
|
||||
fmt::{Display, Formatter},
|
||||
marker::PhantomData,
|
||||
|
@ -71,6 +72,12 @@ impl<NT: Nt> Error for NtError<NT> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<NT: Nt> From<Infallible> for NtError<NT> {
|
||||
fn from(_value: Infallible) -> Self {
|
||||
unreachable!("From<Infallible>")
|
||||
}
|
||||
}
|
||||
|
||||
impl<NT: Nt> Display for NtError<NT> {
|
||||
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
use crate::xir::fmt::{TtCloseXmlEle, TtOpenXmlEle};
|
||||
|
|
Loading…
Reference in New Issue