tamer: xir::flat::{State=>XirToXirf}: Rename

Like the previous two commits, this states the intent of this parser, which
results in more clear pipeline composition.

DEV-7145
main
Mike Gerwitz 2022-06-02 13:41:24 -04:00
parent 91b55999e2
commit 3da82b351e
6 changed files with 96 additions and 94 deletions

View File

@ -42,9 +42,9 @@ use crate::{
},
parse::{Lower, ParseError, Parsed, ParsedObject, UnknownToken},
sym::{GlobalSymbolResolve, SymbolId},
xir::reader::XmlXirReader,
xir::{
flat::{self, Object as XirfToken, StateError as XirfError},
flat::{XirToXirf, XirToXirfError, XirfToken},
reader::XmlXirReader,
writer::{Error as XirWriterError, XmlWriter},
DefaultEscaper, Error as XirError, Escaper, Token as XirToken,
},
@ -192,11 +192,11 @@ fn load_xmlo<'a, P: AsRef<Path>, S: Escaper>(
// abstracted away.
let (mut asg, mut state) = Lower::<
ParsedObject<XirToken, XirError>,
flat::State<64>,
XirToXirf<64>,
>::lower::<_, TameldError>(
&mut XmlXirReader::new(file, escaper, ctx),
|toks| {
Lower::<flat::State<64>, XmloReader>::lower(toks, |xmlo| {
Lower::<XirToXirf<64>, XmloReader>::lower(toks, |xmlo| {
let mut iter = xmlo.scan(false, |st, rtok| match st {
true => None,
false => {
@ -282,7 +282,7 @@ pub enum TameldError {
Io(io::Error),
SortError(SortError),
XirParseError(ParseError<UnknownToken, XirError>),
XirfParseError(ParseError<XirToken, XirfError>),
XirfParseError(ParseError<XirToken, XirToXirfError>),
XmloParseError(ParseError<XirfToken, XmloError>),
XmloLowerError(ParseError<XmloToken, XmloAirError>),
AirLowerError(ParseError<AirToken, AsgError>),
@ -315,8 +315,8 @@ impl From<ParseError<XirfToken, XmloError>> for TameldError {
}
}
impl From<ParseError<XirToken, XirfError>> for TameldError {
fn from(e: ParseError<XirToken, XirfError>) -> Self {
impl From<ParseError<XirToken, XirToXirfError>> for TameldError {
fn from(e: ParseError<XirToken, XirToXirfError>) -> Self {
Self::XirfParseError(e)
}
}

View File

@ -23,7 +23,7 @@ use crate::diagnose::{Annotate, AnnotatedSpan, Diagnostic};
use crate::parse::Token;
use crate::span::Span;
use crate::sym::SymbolId;
use crate::xir::flat::Object as XirfToken;
use crate::xir::flat::XirfToken;
use std::fmt::Display;
/// Error during `xmlo` processing.

View File

@ -29,7 +29,7 @@ use crate::{
},
span::Span,
sym::{st::*, SymbolId},
xir::{attr::Attr, flat::Object as Xirf, QName},
xir::{attr::Attr, flat::XirfToken as Xirf, QName},
};
/// `xmlo` reader events.

View File

@ -29,7 +29,7 @@ use crate::{
sym::GlobalSymbolIntern,
xir::{
attr::Attr,
flat::{Depth, Object as Xirf},
flat::{Depth, XirfToken as Xirf},
QName,
},
};

View File

@ -20,14 +20,14 @@
//! Lightly-parsed XIR as a flat stream (XIRF).
//!
//! XIRF lightly parses a raw XIR [`TokenStream`] into a stream of
//! [`Object`]s that are,
//! [`XirfToken`]s that are,
//! like a [`TokenStream`],
//! flat in structure.
//! It provides the following features over raw XIR:
//!
//! 1. All closing tags must correspond to a matching opening tag at the
//! same depth;
//! 2. [`Object`] exposes the [`Depth`] of each opening/closing tag;
//! 2. [`XirfToken`] exposes the [`Depth`] of each opening/closing tag;
//! 3. Attribute tokens are parsed into [`Attr`] objects;
//! 4. Documents must begin with an element and end with the closing of
//! that element;
@ -73,7 +73,7 @@ impl Display for Depth {
/// but are still validated to ensure that they are well-formed and that
/// the XML is well-structured.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Object {
pub enum XirfToken {
/// Opening tag of an element.
Open(QName, Span, Depth),
@ -97,7 +97,7 @@ pub enum Object {
/// Character data as part of an element.
///
/// See also [`CData`](Object::CData) variant.
/// See also [`CData`](XirfToken::CData) variant.
Text(SymbolId, Span),
/// CData node (`<![CDATA[...]]>`).
@ -115,9 +115,9 @@ pub enum Object {
Whitespace(Whitespace, Span),
}
impl Token for Object {
impl Token for XirfToken {
fn span(&self) -> Span {
use Object::*;
use XirfToken::*;
match self {
Open(_, span, _)
@ -132,11 +132,11 @@ impl Token for Object {
}
}
impl parse::Object for Object {}
impl parse::Object for XirfToken {}
impl Display for Object {
impl Display for XirfToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Object::*;
use XirfToken::*;
match self {
Open(qname, span, _) => {
@ -158,7 +158,7 @@ impl Display for Object {
}
}
impl From<Attr> for Object {
impl From<Attr> for XirfToken {
fn from(attr: Attr) -> Self {
Self::Attr(attr)
}
@ -168,7 +168,7 @@ impl From<Attr> for Object {
pub trait FlatAttrParseState<const MAX_DEPTH: usize> =
ParseState<Token = XirToken, Object = Attr>
where
<Self as ParseState>::Error: Into<StateError>,
<Self as ParseState>::Error: Into<XirToXirfError>,
StateContext<MAX_DEPTH>: AsMut<<Self as ParseState>::Context>;
/// Stack of element [`QName`] and [`Span`] pairs,
@ -182,7 +182,7 @@ type ElementStack<const MAX_DEPTH: usize> = ArrayVec<(QName, Span), MAX_DEPTH>;
///
/// This parser is a pushdown automaton that parses a single XML document.
#[derive(Debug, Default, PartialEq, Eq)]
pub enum State<const MAX_DEPTH: usize, SA = AttrParseState>
pub enum XirToXirf<const MAX_DEPTH: usize, SA = AttrParseState>
where
SA: FlatAttrParseState<MAX_DEPTH>,
{
@ -200,13 +200,13 @@ where
pub type StateContext<const MAX_DEPTH: usize> =
Context<ElementStack<MAX_DEPTH>>;
impl<const MAX_DEPTH: usize, SA> ParseState for State<MAX_DEPTH, SA>
impl<const MAX_DEPTH: usize, SA> ParseState for XirToXirf<MAX_DEPTH, SA>
where
SA: FlatAttrParseState<MAX_DEPTH>,
{
type Token = XirToken;
type Object = Object;
type Error = StateError;
type Object = XirfToken;
type Error = XirToXirfError;
type Context = StateContext<MAX_DEPTH>;
fn parse_token(
@ -214,18 +214,18 @@ where
tok: Self::Token,
stack: &mut Self::Context,
) -> TransitionResult<Self> {
use State::{AttrExpected, Done, NodeExpected, PreRoot};
use XirToXirf::{AttrExpected, Done, NodeExpected, PreRoot};
match (self, tok) {
// Comments are permitted before and after the first root element.
(st @ (PreRoot | Done), XirToken::Comment(sym, span)) => {
Transition(st).ok(Object::Comment(sym, span))
Transition(st).ok(XirfToken::Comment(sym, span))
}
(PreRoot, tok @ XirToken::Open(..)) => Self::parse_node(tok, stack),
(PreRoot, tok) => {
Transition(PreRoot).err(StateError::RootOpenExpected(tok))
Transition(PreRoot).err(XirToXirfError::RootOpenExpected(tok))
}
(NodeExpected, tok) => Self::parse_node(tok, stack),
@ -251,16 +251,16 @@ where
// TODO: It'd be nice if we could also return additional context to
// aid the user in diagnosing the problem,
// e.g. what element(s) still need closing.
*self == State::Done
*self == XirToXirf::Done
}
}
impl<const MAX_DEPTH: usize, SA> Display for State<MAX_DEPTH, SA>
impl<const MAX_DEPTH: usize, SA> Display for XirToXirf<MAX_DEPTH, SA>
where
SA: FlatAttrParseState<MAX_DEPTH>,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use State::*;
use XirToXirf::*;
match self {
PreRoot => write!(f, "expecting document root"),
@ -271,7 +271,7 @@ where
}
}
impl<const MAX_DEPTH: usize, SA> State<MAX_DEPTH, SA>
impl<const MAX_DEPTH: usize, SA> XirToXirf<MAX_DEPTH, SA>
where
SA: FlatAttrParseState<MAX_DEPTH>,
{
@ -280,12 +280,12 @@ where
tok: <Self as ParseState>::Token,
stack: &mut ElementStack<MAX_DEPTH>,
) -> TransitionResult<Self> {
use Object::*;
use State::{AttrExpected, Done, NodeExpected};
use XirToXirf::{AttrExpected, Done, NodeExpected};
use XirfToken::*;
match tok {
XirToken::Open(qname, span) if stack.len() == MAX_DEPTH => {
Transition(NodeExpected).err(StateError::MaxDepthExceeded {
Transition(NodeExpected).err(XirToXirfError::MaxDepthExceeded {
open: (qname, span),
max: Depth(MAX_DEPTH),
})
@ -311,7 +311,7 @@ where
if qname != open_qname =>
{
Transition(NodeExpected).err(
StateError::UnbalancedTag {
XirToXirfError::UnbalancedTag {
open: (open_qname, open_span),
close: (qname, close_span),
},
@ -365,13 +365,13 @@ where
/// stream.
pub fn parse<const MAX_DEPTH: usize>(
toks: impl TokenStream,
) -> impl Iterator<Item = ParsedResult<State<MAX_DEPTH>>> {
State::<MAX_DEPTH>::parse(toks)
) -> impl Iterator<Item = ParsedResult<XirToXirf<MAX_DEPTH>>> {
XirToXirf::<MAX_DEPTH>::parse(toks)
}
/// Parsing error from [`State`].
/// Parsing error from [`XirToXirf`].
#[derive(Debug, Eq, PartialEq)]
pub enum StateError {
pub enum XirToXirfError {
/// Opening root element tag was expected.
RootOpenExpected(XirToken),
@ -389,9 +389,9 @@ pub enum StateError {
AttrError(AttrParseError),
}
impl Display for StateError {
impl Display for XirToXirfError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use StateError::*;
use XirToXirfError::*;
match self {
RootOpenExpected(_tok) => {
@ -420,7 +420,7 @@ impl Display for StateError {
}
}
impl Error for StateError {
impl Error for XirToXirfError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::AttrError(e) => Some(e),
@ -429,9 +429,9 @@ impl Error for StateError {
}
}
impl Diagnostic for StateError {
impl Diagnostic for XirToXirfError {
fn describe(&self) -> Vec<AnnotatedSpan> {
use StateError::*;
use XirToXirfError::*;
match self {
RootOpenExpected(tok) => {
@ -473,7 +473,7 @@ impl Diagnostic for StateError {
}
}
impl From<AttrParseError> for StateError {
impl From<AttrParseError> for XirToXirfError {
fn from(e: AttrParseError) -> Self {
Self::AttrError(e)
}

View File

@ -45,8 +45,8 @@ fn empty_element_self_close() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(name, S, Depth(0))),
Parsed::Object(Object::Close(None, S2, Depth(0))),
Parsed::Object(XirfToken::Open(name, S, Depth(0))),
Parsed::Object(XirfToken::Close(None, S2, Depth(0))),
]),
sut.collect(),
);
@ -65,8 +65,8 @@ fn empty_element_balanced_close() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(name, S, Depth(0))),
Parsed::Object(Object::Close(Some(name), S2, Depth(0))),
Parsed::Object(XirfToken::Open(name, S, Depth(0))),
Parsed::Object(XirfToken::Close(Some(name), S2, Depth(0))),
]),
sut.collect(),
);
@ -90,7 +90,7 @@ fn extra_closing_tag() {
let sut = parse::<1>(toks);
assert_matches!(
sut.collect::<Result<Vec<Parsed<Object>>, _>>(),
sut.collect::<Result<Vec<Parsed<XirfToken>>, _>>(),
Err(ParseError::UnexpectedToken(
XirToken::Close(Some(given_name), given_span),
_
@ -115,7 +115,7 @@ fn extra_self_closing_tag() {
let sut = parse::<1>(toks);
assert_matches!(
sut.collect::<Result<Vec<Parsed<Object>>, _>>(),
sut.collect::<Result<Vec<Parsed<XirfToken>>, _>>(),
Err(ParseError::UnexpectedToken(XirToken::Close(None, given_span), _))
if given_span == S3,
);
@ -138,11 +138,11 @@ fn empty_element_unbalanced_close() {
assert_eq!(
sut.next(),
Some(Ok(Parsed::Object(Object::Open(open_name, S, Depth(0)))))
Some(Ok(Parsed::Object(XirfToken::Open(open_name, S, Depth(0)))))
);
assert_eq!(
sut.next(),
Some(Err(ParseError::StateError(StateError::UnbalancedTag {
Some(Err(ParseError::StateError(XirToXirfError::UnbalancedTag {
open: (open_name, S),
close: (close_name, S2),
})))
@ -167,10 +167,10 @@ fn single_empty_child() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(name, S, Depth(0))),
Parsed::Object(Object::Open(child, S2, Depth(1))),
Parsed::Object(Object::Close(None, S3, Depth(1))),
Parsed::Object(Object::Close(Some(name), S4, Depth(0))),
Parsed::Object(XirfToken::Open(name, S, Depth(0))),
Parsed::Object(XirfToken::Open(child, S2, Depth(1))),
Parsed::Object(XirfToken::Close(None, S3, Depth(1))),
Parsed::Object(XirfToken::Close(Some(name), S4, Depth(0))),
]),
sut.collect(),
);
@ -192,14 +192,16 @@ fn depth_exceeded() {
let mut sut = parse::<1>(toks);
assert_eq!(
Some(Ok(Parsed::Object(Object::Open(name, S, Depth(0))))),
Some(Ok(Parsed::Object(XirfToken::Open(name, S, Depth(0))))),
sut.next()
);
assert_eq!(
Some(Err(ParseError::StateError(StateError::MaxDepthExceeded {
open: (exceed, S2),
max: Depth(1),
}))),
Some(Err(ParseError::StateError(
XirToXirfError::MaxDepthExceeded {
open: (exceed, S2),
max: Depth(1),
}
))),
sut.next()
);
}
@ -226,12 +228,12 @@ fn empty_element_with_attrs() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(name, S, Depth(0))),
Parsed::Object(XirfToken::Open(name, S, Depth(0))),
Parsed::Incomplete,
Parsed::Object(Object::Attr(Attr::new(attr1, val1, (S2, S3)))),
Parsed::Object(XirfToken::Attr(Attr::new(attr1, val1, (S2, S3)))),
Parsed::Incomplete,
Parsed::Object(Object::Attr(Attr::new(attr2, val2, (S3, S4)))),
Parsed::Object(Object::Close(None, S4, Depth(0))),
Parsed::Object(XirfToken::Attr(Attr::new(attr2, val2, (S3, S4)))),
Parsed::Object(XirfToken::Close(None, S4, Depth(0))),
]),
sut.collect(),
);
@ -258,12 +260,12 @@ fn child_element_after_attrs() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(name, S, Depth(0))),
Parsed::Object(XirfToken::Open(name, S, Depth(0))),
Parsed::Incomplete,
Parsed::Object(Object::Attr(Attr::new(attr, val, (S, S2)))),
Parsed::Object(Object::Open(child, S, Depth(1))),
Parsed::Object(Object::Close(None, S2, Depth(1))),
Parsed::Object(Object::Close(Some(name), S3, Depth(0))),
Parsed::Object(XirfToken::Attr(Attr::new(attr, val, (S, S2)))),
Parsed::Object(XirfToken::Open(child, S, Depth(1))),
Parsed::Object(XirfToken::Close(None, S2, Depth(1))),
Parsed::Object(XirfToken::Close(Some(name), S3, Depth(0))),
]),
sut.collect(),
);
@ -289,12 +291,12 @@ fn element_with_empty_sibling_children() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(parent, S, Depth(0))),
Parsed::Object(Object::Open(childa, S2, Depth(1))),
Parsed::Object(Object::Close(None, S3, Depth(1))),
Parsed::Object(Object::Open(childb, S2, Depth(1))),
Parsed::Object(Object::Close(None, S3, Depth(1))),
Parsed::Object(Object::Close(Some(parent), S2, Depth(0))),
Parsed::Object(XirfToken::Open(parent, S, Depth(0))),
Parsed::Object(XirfToken::Open(childa, S2, Depth(1))),
Parsed::Object(XirfToken::Close(None, S3, Depth(1))),
Parsed::Object(XirfToken::Open(childb, S2, Depth(1))),
Parsed::Object(XirfToken::Close(None, S3, Depth(1))),
Parsed::Object(XirfToken::Close(Some(parent), S2, Depth(0))),
]),
sut.collect(),
);
@ -322,12 +324,12 @@ fn element_with_child_with_attributes() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(parent, S, Depth(0))),
Parsed::Object(Object::Open(child, S, Depth(1))),
Parsed::Object(XirfToken::Open(parent, S, Depth(0))),
Parsed::Object(XirfToken::Open(child, S, Depth(1))),
Parsed::Incomplete,
Parsed::Object(Object::Attr(Attr::new(attr, value, (S, S2)))),
Parsed::Object(Object::Close(None, S3, Depth(1))),
Parsed::Object(Object::Close(Some(parent), S3, Depth(0))),
Parsed::Object(XirfToken::Attr(Attr::new(attr, value, (S, S2)))),
Parsed::Object(XirfToken::Close(None, S3, Depth(1))),
Parsed::Object(XirfToken::Close(Some(parent), S3, Depth(0))),
]),
sut.collect(),
);
@ -349,9 +351,9 @@ fn element_with_text() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Open(parent, S, Depth(0))),
Parsed::Object(Object::Text(text, S2)),
Parsed::Object(Object::Close(Some(parent), S3, Depth(0))),
Parsed::Object(XirfToken::Open(parent, S, Depth(0))),
Parsed::Object(XirfToken::Text(text, S2)),
Parsed::Object(XirfToken::Close(Some(parent), S3, Depth(0))),
]),
sut.collect(),
);
@ -365,7 +367,7 @@ fn not_accepting_state_if_element_open() {
let mut sut = parse::<1>(toks);
assert_eq!(
Some(Ok(Parsed::Object(Object::Open(name, S, Depth(0))))),
Some(Ok(Parsed::Object(XirfToken::Open(name, S, Depth(0))))),
sut.next()
);
@ -392,10 +394,10 @@ fn comment_before_or_after_root_ok() {
assert_eq!(
Ok(vec![
Parsed::Object(Object::Comment(cstart, S)),
Parsed::Object(Object::Open(name, S2, Depth(0))),
Parsed::Object(Object::Close(None, S3, Depth(0))),
Parsed::Object(Object::Comment(cend, S4)),
Parsed::Object(XirfToken::Comment(cstart, S)),
Parsed::Object(XirfToken::Open(name, S2, Depth(0))),
Parsed::Object(XirfToken::Close(None, S3, Depth(0))),
Parsed::Object(XirfToken::Comment(cend, S4)),
]),
sut.collect(),
);
@ -425,7 +427,7 @@ fn content_after_root_close_error() {
assert_matches!(
sut.collect(),
Result::<Vec<Parsed<Object>>, _>::Err(ParseError::UnexpectedToken(
Result::<Vec<Parsed<XirfToken>>, _>::Err(ParseError::UnexpectedToken(
XirToken::Open(given_name, given_span),
_)) if given_name == name && given_span == S3
);
@ -441,8 +443,8 @@ fn content_before_root_open_error() {
let sut = parse::<1>(toks);
assert_eq!(
Result::<Vec<Parsed<Object>>, _>::Err(ParseError::StateError(
StateError::RootOpenExpected(XirToken::Text(text, S))
Result::<Vec<Parsed<XirfToken>>, _>::Err(ParseError::StateError(
XirToXirfError::RootOpenExpected(XirToken::Text(text, S))
)),
sut.collect()
);