#![warn(missing_docs)]
use gss::{GSSNodeIndex, GSSNode};
use petgraph::prelude::EdgeIndex;
use thiserror::Error;
use wagon_utils::{comma_separated_with_or_str, ErrorReport};
use std::{hash::{Hash, Hasher}, rc::Rc, str::{from_utf8, Utf8Error}, collections::HashSet, mem::Discriminant};
use sppf::{SPPFNodeIndex, SPPFNode};
use value::{Value, ValueError, InnerValue, InnerValueError};
use wagon_ident::Ident;
pub mod sppf;
pub mod gss;
pub mod value;
mod label;
mod state;
mod descriptor;
mod slot;
pub use label::{Label, RegexTerminal};
pub use state::{GLLState, LabelMap, RuleMap, RegexMap};
pub use slot::GrammarSlot;
pub type TerminalBit<'a> = &'a u8;
pub type Terminal<'a> = &'a[u8];
pub const ROOT_UUID: &str = "S'";
pub type GLLBlockLabel<'a> = Rc<dyn Label<'a>>;
pub type AttributeMap<'a> = Vec<Value<'a>>;
pub type ReturnMap<'a> = Vec<Option<Value<'a>>>;
pub type AttributeKey = usize;
pub type GLLResult<'a, T> = Result<T, GLLError<'a>>;
pub type ParseResult<'a, T> = Result<T, GLLParseError<'a>>;
pub type ImplementationResult<'a, T> = Result<T, GLLImplementationError<'a>>;
#[derive(Debug, Error)]
pub enum GLLError<'a> {
#[error(transparent)]
ImplementationError(GLLImplementationError<'a>),
#[error(transparent)]
ParseError(GLLParseError<'a>),
#[error("{0}")]
ProcessError(#[from] GLLProcessError)
}
#[derive(Debug, Error)]
pub enum GLLImplementationError<'a> {
#[error("{0}")]
Utf8Error(#[from] Utf8Error),
#[error("{0}")]
ValueError(ValueError<'a>),
#[error("No rule with id {0} exists in the state object.")]
UnknownRule(&'a str),
#[error("No label with id {0} exists in the state object.")]
UnknownLabel(&'a str),
#[error("{ROOT_UUID} could not be found.")]
MissingRoot,
#[error("Expected to find SPPF node {0:?} in the graph, but it was not there.")]
MissingSPPFNode(SPPFNodeIndex),
#[error("Expected SPPFNode of type {}, got {1:?}", comma_separated_with_or_str(.0))]
IncorrectSPPFType(Vec<&'a str>, Discriminant<SPPFNode<'a>>),
#[error("Expected to find GSS node {0:?} in the graph, but it was not there.")]
MissingGSSNode(GSSNodeIndex),
#[error("Expected to find GSS edge {0:?} in the graph, but it was not there.")]
MissingGSSEdge(EdgeIndex),
#[error("The {0}th attribute is not at GSS node {1:?}")]
MissingAttribute(AttributeKey, Rc<GSSNode<'a>>),
#[error("The {0}th attribute is not in the context of GSS node {1:?}")]
MissingContext(AttributeKey, Rc<GSSNode<'a>>),
#[error("Tried to access completed slot {0} as if it were not completed.")]
CompletedSlot(String),
#[error("A fatal error occurred! {0}.")]
Fatal(&'a str),
}
#[derive(Debug, Error)]
pub enum GLLParseError<'a> {
#[error("Encountered unexpected byte at {pointer}. Expected {expected} saw {offender}.")]
UnexpectedByte {
pointer: usize,
expected: u8,
offender: u8
},
#[error("Tried reading more than possible from input. Current pointer at {pointer}, tried reading {offender:?}.")]
TooLong {
pointer: usize,
offender: Terminal<'a>
},
#[error("No parse candidates were found for rule `{rule}` in context `{context}`")]
NoCandidates {
pointer: usize,
rule: String,
context: String
},
#[error("All weights for rule `{rule}` in context `{context}` were 0")]
ZeroWeights {
pointer: usize,
rule: String,
context: String
}
}
impl<'a> From<GLLImplementationError<'a>> for GLLError<'a> {
fn from(value: GLLImplementationError<'a>) -> Self {
Self::ImplementationError(value)
}
}
impl<'a> From<GLLParseError<'a>> for GLLError<'a> {
fn from(value: GLLParseError<'a>) -> Self {
Self::ParseError(value)
}
}
impl<'a> From<InnerValueError<Value<'a>>> for GLLImplementationError<'a> {
fn from(value: InnerValueError<Value<'a>>) -> Self {
Self::ValueError(ValueError::ValueError(value))
}
}
impl<'a> From<ValueError<'a>> for GLLImplementationError<'a> {
fn from(value: ValueError<'a>) -> Self {
Self::ValueError(value)
}
}
impl<'a> From<ValueError<'a>> for GLLError<'a> {
fn from(value: ValueError<'a>) -> Self {
Self::ImplementationError(GLLImplementationError::ValueError(value))
}
}
impl<'a> From<InnerValueError<Value<'a>>> for GLLError<'a> {
fn from(value: InnerValueError<Value<'a>>) -> Self {
Self::ImplementationError(GLLImplementationError::ValueError(ValueError::ValueError(value)))
}
}
impl<'a> From<InnerValueError<InnerValue<Value<'a>>>> for GLLImplementationError<'a> {
fn from(value: InnerValueError<InnerValue<Value<'a>>>) -> Self {
Self::ValueError(ValueError::ValueError(value.into()))
}
}
impl<'a> From<InnerValueError<InnerValue<Value<'a>>>> for GLLError<'a> {
fn from(value: InnerValueError<InnerValue<Value<'a>>>) -> Self {
Self::ImplementationError(GLLImplementationError::from(value))
}
}
impl ErrorReport for GLLError<'_> {
fn span(self) -> wagon_utils::Span {
match self {
GLLError::ParseError(e) => match e {
GLLParseError::UnexpectedByte { pointer, .. } | GLLParseError::TooLong { pointer, .. }
| GLLParseError::NoCandidates { pointer, .. } | GLLParseError::ZeroWeights { pointer, .. } => pointer..pointer,
},
_ => wagon_utils::Span::default(),
}
}
fn msg(&self) -> (String, String) {
match self {
GLLError::ImplementationError(e) => ("Fatal Implementation Error".to_string(), e.to_string()),
GLLError::ParseError(e) => ("Parse Error".to_string(), e.to_string()),
GLLError::ProcessError(e) => ("Post-Processing Error".to_string(), e.to_string()),
}
}
}
pub type ProcessResult<T> = Result<T, GLLProcessError>;
#[derive(Debug, Error)]
pub enum GLLProcessError {
#[error("Expected to find SPPF node {0:?} in the graph, but it was not there.")]
MissingSPPFNode(SPPFNodeIndex),
}