A lot of stuff I'm not gonna enumerate

rule fundamentals
This commit is contained in:
2022-07-06 20:13:13 +02:00
parent 49aa73956c
commit ec7ad81fac
21 changed files with 483 additions and 420 deletions

View File

@@ -1,6 +1,6 @@
use std::{ops::Range, iter};
use std::{ops::Range, iter, fmt};
use ordered_float::NotNan;
use chumsky::{Parser, prelude::*, text::whitespace};
use chumsky::{Parser, prelude::*};
use std::fmt::Debug;
use crate::utils::BoxedIter;
@@ -14,6 +14,11 @@ impl Debug for Entry {
// f.debug_tuple("Entry").field(&self.0).field(&self.1).finish()
}
}
impl Into<(Lexeme, Range<usize>)> for Entry {
fn into(self) -> (Lexeme, Range<usize>) {
(self.0, self.1)
}
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum Lexeme {
@@ -61,6 +66,9 @@ impl Lexeme {
pub fn name<T: ToString>(n: T) -> Self {
Lexeme::Name(n.to_string())
}
pub fn rule<T>(prio: T) -> Self where T: Into<f64> {
Lexeme::Rule(NotNan::new(prio.into()).expect("Rule priority cannot be NaN"))
}
pub fn paren_parser<T, P>(
expr: P
) -> impl Parser<Lexeme, (char, T), Error = Simple<Lexeme>> + Clone
@@ -76,15 +84,20 @@ impl Lexeme {
}
}
fn rule_parser() -> impl Parser<char, NotNan<f64>, Error = Simple<char>> {
just('=').ignore_then(
choice((
none_of("-0123456789").rewind().to(NotNan::new(0f64).unwrap()),
number::float_parser().then_ignore(just("=>"))
)).map_err_with_span(|err, span| {
panic!("Something's up! {:?} {}", span, err)
})
)
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct LexedText(pub Vec<Vec<Entry>>);
impl Debug for LexedText {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for row in &self.0 {
for tok in row {
tok.fmt(f)?;
f.write_str(" ")?
}
f.write_str("\n")?
}
Ok(())
}
}
type LexSubres<'a> = BoxedIter<'a, Entry>;
@@ -104,7 +117,7 @@ fn paren_parser<'a>(
})
}
pub fn lexer<'a, T: 'a>(ops: &[T]) -> impl Parser<char, Vec<Vec<Entry>>, Error=Simple<char>> + 'a
pub fn lexer<'a, T: 'a>(ops: &[T]) -> impl Parser<char, LexedText, Error=Simple<char>> + 'a
where T: AsRef<str> + Clone {
let all_ops = ops.iter().map(|o| o.as_ref().to_string())
.chain(iter::once(".".to_string())).collect::<Vec<_>>();
@@ -114,7 +127,8 @@ where T: AsRef<str> + Clone {
paren_parser(recurse.clone(), '[', ']'),
paren_parser(recurse.clone(), '{', '}'),
choice((
rule_parser().map(Lexeme::Rule),
just("==").padded().to(Lexeme::rule(0f64)),
just("=").ignore_then(number::float_parser()).then_ignore(just("=>")).map(Lexeme::rule),
comment::comment_parser().map(Lexeme::Comment),
just("::").padded().to(Lexeme::NS),
just('\\').padded().to(Lexeme::BS),
@@ -130,5 +144,5 @@ where T: AsRef<str> + Clone {
}).separated_by(one_of("\t ").repeated())
.flatten().collect()
.separated_by(just('\n').then(text::whitespace()).ignored())
}
.map(LexedText)
}