feat: daleth parser

This commit is contained in:
Artemy Egorov 2024-08-12 11:33:10 +03:00
parent 9c41541712
commit 9592a8ffba
7 changed files with 134 additions and 38 deletions

View file

@ -40,7 +40,7 @@ fn additional_str<'src>(
Token::TextBody(_) => "", Token::TextBody(_) => "",
Token::MLText(_) => "", Token::MLText(_) => "",
Token::MLMSText(_, _) => "", Token::MLMSText(_, _) => "",
Token::RMLText(_) => "", Token::MLRText(_) => "",
_ => "\n", _ => "\n",
}; };
@ -100,7 +100,7 @@ pub fn format<'src>(spanned_tokens: &Vec<Spanned<Token<'src>>>) -> String {
set_indent(t, current_indent + 1), set_indent(t, current_indent + 1),
prepend_indent("}", current_indent) prepend_indent("}", current_indent)
), ),
Token::RMLText(t) => format!(" {{#{t}}}\n"), Token::MLRText(t) => format!(" {{#{t}}}\n"),
Token::Comment(c) => format!("{}\n", prepend_indent(&format!("#{c}"), current_indent)), Token::Comment(c) => format!("{}\n", prepend_indent(&format!("#{c}"), current_indent)),
Token::TextTag(t) => format!("{}\n", prepend_indent(t, current_indent)), Token::TextTag(t) => format!("{}\n", prepend_indent(t, current_indent)),

View file

@ -159,7 +159,7 @@ fn textual<'src>() -> impl Parser<'src, &'src str, Token<'src>, extra::Err<Rich<
let rmltext = multiline_text_body let rmltext = multiline_text_body
.delimited_by(just("{#"), just('}')) .delimited_by(just("{#"), just('}'))
.map(Token::RMLText) .map(Token::MLRText)
.labelled("Raw multiline text"); .labelled("Raw multiline text");
choice((paragraph, mlmstext, rmltext, mltext, text_body, text_tag)) choice((paragraph, mlmstext, rmltext, mltext, text_body, text_tag))

View file

@ -20,8 +20,8 @@ pub enum Token<'src> {
MLText(&'src str), MLText(&'src str),
/// Multi Line with min spaces text /// Multi Line with min spaces text
MLMSText(usize, &'src str), MLMSText(usize, &'src str),
/// Raw Multi line text /// Multi Line raw text
RMLText(&'src str), MLRText(&'src str),
// Special // Special
TextTag(&'src str), TextTag(&'src str),

View file

@ -3,8 +3,9 @@ pub mod types;
use super::{ use super::{
lexer::types::Token, lexer::types::Token,
types::{Span, Spanned}, types::{Span, Spanned},
utils::{set_indent, trim_indent},
}; };
use crate::typed::{Page, Tag::*}; use crate::typed::{AlignArg, Body, Hl, NNArg, NNBody, Page, TNullArg, Tag::*};
use chumsky::prelude::*; use chumsky::prelude::*;
use types::*; use types::*;
@ -14,11 +15,133 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
Spanned<Page>, Spanned<Page>,
extra::Err<Rich<'tokens, Token<'src>, Span>>, extra::Err<Rich<'tokens, Token<'src>, Span>>,
> { > {
let br = just(Token::Br).to(Br); recursive(|tag| {
let tags_body = tag
.clone()
.repeated()
.collect()
.delimited_by(just(Token::LSquare), just(Token::RSquare));
let tag = br; let text_body = select! {
Token::TextBody(t) => t.to_owned(),
Token::MLText(t) => trim_indent(t).to_owned(),
Token::MLMSText(n, t) => set_indent(t, n).to_owned(),
Token::MLRText(t) => t.to_owned()
};
tag.repeated() let nnbody = text_body
.collect() .map(NNBody::Text)
.map_with(|t, e| (Page { data: t }, e.span())) .or(tags_body.clone().map(NNBody::Tags));
let body = text_body
.map(Body::Text)
.or(tags_body.clone().map(Body::Tags))
.or_not()
.to(Body::Null);
let num_arg = select! {
Token::NumberArgument(n) => n
};
let text_arg = select! {
Token::TextArgument(t) => t.to_owned()
};
let nnarg = text_arg.map(NNArg::Text).or(num_arg.map(NNArg::Number));
let tnullarg = text_arg
.map(TNullArg::Text)
.or_not()
.map(|v| v.unwrap_or(TNullArg::Null));
let hlarg = num_arg.try_map(|n, s| Hl::try_from(n).map_err(|e| Rich::custom(s, e)));
let alignarg =
num_arg.try_map(|n, s| AlignArg::try_from(n).map_err(|e| Rich::custom(s, e)));
let el = just(Token::El).ignore_then(nnbody.clone()).map(El);
let h = just(Token::H)
.ignore_then(hlarg)
.then(text_body)
.map(|(level, body)| H(body, level));
let p = just(Token::P).ignore_then(nnbody.clone()).map(P);
let br = just(Token::Br).to(Br);
let ul = just(Token::Ul).ignore_then(tags_body.clone()).map(Ul);
let ol = just(Token::Ol).ignore_then(tags_body.clone()).map(Ol);
let row = just(Token::Row)
.ignore_then(alignarg.or_not())
.then(tags_body.clone())
.map(|(arg, body)| Row(body, arg.unwrap_or(AlignArg::Start)));
let link = just(Token::Link)
.ignore_then(text_arg.clone())
.then(body.clone())
.map(|(arg, body)| Link(body, arg));
let navlink = just(Token::Navlink)
.ignore_then(text_arg.clone())
.then(body.clone())
.map(|(arg, body)| Navlink(body, arg));
let btn = just(Token::Btn)
.ignore_then(text_arg.clone())
.then(body.clone())
.map(|(arg, body)| Btn(body, arg));
let navbtn = just(Token::Navbtn)
.ignore_then(text_arg.clone())
.then(body.clone())
.map(|(arg, body)| Navbtn(body, arg));
let img = just(Token::Img).ignore_then(text_arg.clone()).map(Img);
let table = just(Token::Table).ignore_then(tags_body.clone()).map(Table);
let tcol = just(Token::Tcol).ignore_then(tags_body.clone()).map(Tcol);
let tpcol = just(Token::Tpcol).ignore_then(tags_body.clone()).map(Tpcol);
let hr = just(Token::Hr).to(Hr);
let b = just(Token::B).ignore_then(text_body.clone()).map(B);
let i = just(Token::I).ignore_then(text_body.clone()).map(I);
let bq = just(Token::Bq).ignore_then(nnbody.clone()).map(Bq);
let footlnk = just(Token::Footlnk).ignore_then(nnarg).map(Footlnk);
let footn = just(Token::Footn)
.ignore_then(nnarg.clone())
.then(text_body.clone())
.map(|(arg, body)| Footn(body, arg));
let a = just(Token::A).ignore_then(nnarg.clone()).map(A);
let s = just(Token::S).ignore_then(text_body.clone()).map(S);
let sup = just(Token::Sup).ignore_then(text_body.clone()).map(Sup);
let sub = just(Token::Sub).ignore_then(text_body.clone()).map(Sub);
let disc = just(Token::Disc).ignore_then(nnbody.clone()).map(Disc);
let block = just(Token::Block)
.ignore_then(alignarg.or_not())
.then(nnbody.clone())
.map(|(arg, body)| Block(body, arg.unwrap_or(AlignArg::Start)));
let carousel = just(Token::Carousel)
.ignore_then(tags_body.clone())
.map(Carousel);
let code = just(Token::Code)
.ignore_then(tnullarg)
.then(text_body.clone())
.map(|(arg, body)| Code(body, arg));
let pre = just(Token::Pre).ignore_then(text_body.clone()).map(Pre);
let meta = just(Token::Meta)
.ignore_then(text_arg)
.then(text_body.clone())
.map(|(arg, body)| Meta(body, arg));
let el_text = select! {
Token::TextTag(t) => El(NNBody::Text(t.to_owned()))
};
let el_tags = tag
.repeated()
.collect()
.delimited_by(just(Token::ElOpen), just(Token::ElClose))
.map(|v| El(NNBody::Tags(v)));
let paragraph = select! {
Token::Paragraph(t) => P(NNBody::Text(t.replace("\n"," ").trim().to_owned()))
};
choice((
el, h, p, br, ul, ol, row, link, navlink, btn, navbtn, img, table, tcol, tpcol, hr, b,
i, bq, footlnk, footn, a, s, sup, sub, disc,
))
.or(choice((block, carousel, code, pre, meta)))
.or(choice((el_text, el_tags, paragraph)))
})
.repeated()
.collect()
.map_with(|t, e| (Page { data: t }, e.span()))
} }

View file

@ -109,16 +109,6 @@ impl TryFrom<DlBody> for String {
} }
} }
impl From<DlArgument> for Arg {
fn from(value: DlArgument) -> Self {
match value {
DlArgument::Text(s) => s.into(),
DlArgument::Number(n) => n.into(),
DlArgument::Null => Self::Null,
}
}
}
impl TryFrom<DlArgument> for NNArg { impl TryFrom<DlArgument> for NNArg {
type Error = ConversionError; type Error = ConversionError;

View file

@ -83,16 +83,6 @@ impl From<Body> for DlBody {
} }
} }
impl From<Arg> for DlArgument {
fn from(item: Arg) -> DlArgument {
match item {
Arg::Null => NA,
Arg::Number(v) => v.into(),
Arg::Text(v) => v.into(),
}
}
}
impl From<NNArg> for DlArgument { impl From<NNArg> for DlArgument {
fn from(item: NNArg) -> DlArgument { fn from(item: NNArg) -> DlArgument {
match item { match item {

View file

@ -65,13 +65,6 @@ pub enum NNBody {
/// Text body /// Text body
pub type TBody = String; pub type TBody = String;
#[derive(AutoFrom, Debug, Clone, PartialEq, Eq)]
pub enum Arg {
Text(String),
Number(u8),
Null,
}
#[derive(AutoFrom, Debug, Clone, PartialEq, Eq)] #[derive(AutoFrom, Debug, Clone, PartialEq, Eq)]
pub enum TNullArg { pub enum TNullArg {
Text(String), Text(String),