rust-nix/src/parser/token/mod.rs

158 lines
2.9 KiB
Rust

mod brackets;
mod number;
mod op_kw_ident;
mod path;
mod strings;
mod tokenlist;
pub use self::{
brackets::{
CurlyOpen,
CurlyClose,
CurlyBrackets,
SquareOpen,
SquareClose,
SquareBrackets,
RoundOpen,
RoundClose,
RoundBrackets,
InterpolateOpen,
Interpolate,
},
op_kw_ident::SimpleToken,
path::Path,
tokenlist::TokenList,
strings::{
Literal,
StringPart,
},
};
use super::{
source::{Span, SpanRef},
Number,
SpannedData,
Identifier,
};
trait SpanExt {
fn data<T>(self, data: T) -> SpannedData<T>;
}
impl SpanExt for SpanRef<'_> {
fn data<T>(self, data: T) -> SpannedData<T> {
SpannedData { data: data, span: self.into() }
}
}
struct Spanned<F, O> {
f: F,
o: std::marker::PhantomData<O>,
}
impl<'a, F, O, E> nom::Parser<SpanRef<'a>, SpannedData<O>, E> for Spanned<F, O>
where
F: nom::Parser<SpanRef<'a>, O, E>,
{
fn parse(&mut self, input: SpanRef<'a>) -> nom::IResult<SpanRef<'a>, SpannedData<O>, E> {
use nom::{Offset, Slice};
match self.f.parse(input) {
Ok((remaining, result)) => {
let index = input.offset(&remaining);
let consumed = input.slice(..index);
Ok((remaining, consumed.data(result)))
}
Err(e) => Err(e),
}
}
}
trait ParserExt<'a, O, E> {
fn spanned(self) -> Spanned<Self, O>
where
Self: Sized,
{
Spanned { f: self, o: std::marker::PhantomData }
}
}
impl<'a, O, E, T> ParserExt<'_, O, E> for T
where
T: nom::Parser<SpanRef<'a>, O, E>
{
}
trait IResultExt {
fn unrecoverable(self) -> Self;
}
impl<T, E> IResultExt for Result<T, nom::Err<E>> {
fn unrecoverable(self) -> Self {
match self {
Err(nom::Err::Error(e)) => Err(nom::Err::Failure(e)),
v => v,
}
}
}
#[derive(Clone, derivative::Derivative)]
#[derivative(Debug)]
pub enum Token {
#[derivative(Debug="transparent")]
SimpleToken(SimpleToken),
#[derivative(Debug="transparent")]
Number(Number),
#[derivative(Debug="transparent")]
Identifier(Identifier),
#[derivative(Debug="transparent")]
Path(Path),
/// `"..."` (might have been ''..'' or URI in source)
String(Vec<StringPart>),
/// `${...}`
#[derivative(Debug="transparent")]
Interpolate(Interpolate),
/// `{ ... }`
#[derivative(Debug="transparent")]
CurlyBrackets(CurlyBrackets),
/// `[ ... ]`
#[derivative(Debug="transparent")]
SquareBrackets(SquareBrackets),
/// `( ... )`
#[derivative(Debug="transparent")]
RoundBrackets(RoundBrackets),
}
macro_rules! to_token {
($($id:ident,)*) => { $(
impl From<$id> for Token {
fn from(t: $id) -> Self {
Self::$id(t)
}
}
impl From<SpannedData<$id>> for SpannedData<Token> {
fn from(t: SpannedData<$id>) -> Self {
SpannedData {
data: Token::$id(t.data),
span: t.span,
}
}
}
)* };
}
to_token!{
SimpleToken,
Number,
Identifier,
Path,
Interpolate,
CurlyBrackets,
SquareBrackets,
RoundBrackets,
}
// pub type PResult<T> = nom::IResult<Span, T, nom_supreme::error::ErrorTree<Span>>;
pub type PResult<'a, T> = nom::IResult<SpanRef<'a>, T>;