mirror of
https://github.com/TxtDot/dalet-rs.git
synced 2024-11-21 16:26:21 +03:00
fix: lexer, parser align, create parser example
This commit is contained in:
parent
9592a8ffba
commit
50f5c7fe19
7 changed files with 132 additions and 32 deletions
|
@ -96,8 +96,8 @@ row [
|
||||||
this is codeblock
|
this is codeblock
|
||||||
}
|
}
|
||||||
|
|
||||||
# {# Text} Text after "`# " not modified
|
# {# Text} Text after "{#" not modified
|
||||||
code "markdown" {# this is codeblock}
|
code "markdown" {# this is codeblock}
|
||||||
]]
|
]]
|
||||||
|
|
||||||
[[
|
[[
|
||||||
|
@ -125,14 +125,14 @@ row [
|
||||||
# Element
|
# Element
|
||||||
# Description
|
# Description
|
||||||
# ]
|
# ]
|
||||||
table {
|
# table {
|
||||||
+| Tag | Description |
|
# +| Tag | Description |
|
||||||
| h | Heading |
|
# | h | Heading |
|
||||||
| p | Paragraph |
|
# | p | Paragraph |
|
||||||
| img | Image |
|
# | img | Image |
|
||||||
| link | Link |
|
# | link | Link |
|
||||||
| btn | Button |
|
# | btn | Button |
|
||||||
| ul | Unordered list |
|
# | ul | Unordered list |
|
||||||
| br | Line break |
|
# | br | Line break |
|
||||||
+| quantity | 7 |
|
# +| quantity | 7 |
|
||||||
}
|
# }
|
||||||
|
|
|
@ -15,7 +15,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
Err(e) => e.into_iter().for_each(|e| {
|
Err(e) => e.into_iter().for_each(|e| {
|
||||||
Report::build(ReportKind::Error, src_file, e.span().start)
|
Report::build(ReportKind::Error, src_file, e.span().start)
|
||||||
.with_code("Compiler")
|
.with_code("Lexer")
|
||||||
.with_message(e.to_string().clone())
|
.with_message(e.to_string().clone())
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::new((src_file, e.span().into_range()))
|
Label::new((src_file, e.span().into_range()))
|
||||||
|
|
32
examples/daleth_parser.rs
Normal file
32
examples/daleth_parser.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use ariadne::{Color, Label, Report, ReportKind, Source};
|
||||||
|
use chumsky::{input::Input, Parser};
|
||||||
|
use dalet::daleth::{lexer::lexer, parser::parser};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let src_file = "daleth.dlth";
|
||||||
|
let src = include_str!("./daleth.dlth");
|
||||||
|
|
||||||
|
let lexed = lexer().parse(src).unwrap();
|
||||||
|
let parsed = parser().parse(lexed.as_slice().spanned((0..src.len()).into()));
|
||||||
|
|
||||||
|
match parsed.into_result() {
|
||||||
|
Ok(t) => {
|
||||||
|
println!("{:#?}", t);
|
||||||
|
// println!("{}", format(&t));
|
||||||
|
}
|
||||||
|
Err(e) => e.into_iter().for_each(|e| {
|
||||||
|
// println!("{:#}", )
|
||||||
|
Report::build(ReportKind::Error, src_file, e.span().start)
|
||||||
|
.with_code("Parser")
|
||||||
|
.with_message(e.to_string())
|
||||||
|
.with_label(
|
||||||
|
Label::new((src_file, e.span().into_range()))
|
||||||
|
.with_message(e.to_string())
|
||||||
|
.with_color(Color::Red),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
.print((src_file, Source::from(&src)))
|
||||||
|
.unwrap()
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
|
@ -10,8 +10,8 @@ pub fn lexer<'src>(
|
||||||
let token = choice((symbol(), tag(), argument(), textual()));
|
let token = choice((symbol(), tag(), argument(), textual()));
|
||||||
|
|
||||||
token
|
token
|
||||||
|
.padded_by(comment().padded().repeated())
|
||||||
.padded()
|
.padded()
|
||||||
.padded_by(comment())
|
|
||||||
.map_with(|t, e| (t, e.span()))
|
.map_with(|t, e| (t, e.span()))
|
||||||
.repeated()
|
.repeated()
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Token<'src> {
|
pub enum Token<'src> {
|
||||||
// Symbols
|
// Symbols
|
||||||
|
@ -64,3 +66,55 @@ pub enum Token<'src> {
|
||||||
Pre,
|
Pre,
|
||||||
Meta,
|
Meta,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'src> fmt::Display for Token<'src> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Token::LSquare => write!(f, "["),
|
||||||
|
Token::RSquare => write!(f, "]"),
|
||||||
|
Token::ElOpen => write!(f, "[["),
|
||||||
|
Token::ElClose => write!(f, "]]"),
|
||||||
|
Token::NumberArgument(n) => write!(f, "{}", n),
|
||||||
|
Token::TextArgument(t) => write!(f, "{}", t),
|
||||||
|
Token::TextBody(_) => write!(f, "text body"),
|
||||||
|
Token::MLText(_) => write!(f, "text body"),
|
||||||
|
Token::MLMSText(_, _) => write!(f, "text body"),
|
||||||
|
Token::MLRText(_) => write!(f, "text body"),
|
||||||
|
Token::TextTag(_) => write!(f, "text tag"),
|
||||||
|
Token::Paragraph(_) => write!(f, "paragraph"),
|
||||||
|
Token::Comment(_) => write!(f, "comment"),
|
||||||
|
Token::EmptyLine => write!(f, "empty line"),
|
||||||
|
Token::El => write!(f, "el"),
|
||||||
|
Token::H => write!(f, "h"),
|
||||||
|
Token::P => write!(f, "p"),
|
||||||
|
Token::Br => write!(f, "br"),
|
||||||
|
Token::Ul => write!(f, "ul"),
|
||||||
|
Token::Ol => write!(f, "el"),
|
||||||
|
Token::Row => write!(f, "ol"),
|
||||||
|
Token::Link => write!(f, "link"),
|
||||||
|
Token::Navlink => write!(f, "navlink"),
|
||||||
|
Token::Btn => write!(f, "btn"),
|
||||||
|
Token::Navbtn => write!(f, "navbtn"),
|
||||||
|
Token::Img => write!(f, "img"),
|
||||||
|
Token::Table => write!(f, "table"),
|
||||||
|
Token::Tcol => write!(f, "tcol"),
|
||||||
|
Token::Tpcol => write!(f, "tpcol"),
|
||||||
|
Token::Hr => write!(f, "hr"),
|
||||||
|
Token::B => write!(f, "b"),
|
||||||
|
Token::I => write!(f, "i"),
|
||||||
|
Token::Bq => write!(f, "bq"),
|
||||||
|
Token::Footlnk => write!(f, "footlnk"),
|
||||||
|
Token::Footn => write!(f, "footn"),
|
||||||
|
Token::A => write!(f, "a"),
|
||||||
|
Token::S => write!(f, "s"),
|
||||||
|
Token::Sup => write!(f, "sup"),
|
||||||
|
Token::Sub => write!(f, "sub"),
|
||||||
|
Token::Disc => write!(f, "disc"),
|
||||||
|
Token::Block => write!(f, "block"),
|
||||||
|
Token::Carousel => write!(f, "carousel"),
|
||||||
|
Token::Code => write!(f, "code"),
|
||||||
|
Token::Pre => write!(f, "pre"),
|
||||||
|
Token::Meta => write!(f, "meta"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,19 +2,25 @@ pub mod types;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
lexer::types::Token,
|
lexer::types::Token,
|
||||||
types::{Span, Spanned},
|
types::Span,
|
||||||
utils::{set_indent, trim_indent},
|
utils::{set_spaces, trim_indent},
|
||||||
|
};
|
||||||
|
use crate::typed::{
|
||||||
|
AlignArg, Body, Hl, NNArg, NNBody, Page, TNullArg,
|
||||||
|
Tag::{self, *},
|
||||||
};
|
};
|
||||||
use crate::typed::{AlignArg, Body, Hl, NNArg, NNBody, Page, TNullArg, Tag::*};
|
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
pub fn parser<'tokens, 'src: 'tokens>(
|
||||||
'tokens,
|
) -> impl Parser<'tokens, ParserInput<'tokens, 'src>, Page, extra::Err<Rich<'tokens, Token<'src>, Span>>>
|
||||||
ParserInput<'tokens, 'src>,
|
{
|
||||||
Spanned<Page>,
|
tag().repeated().collect().map(|t| (Page { data: t }))
|
||||||
extra::Err<Rich<'tokens, Token<'src>, Span>>,
|
}
|
||||||
> {
|
|
||||||
|
pub fn tag<'tokens, 'src: 'tokens>(
|
||||||
|
) -> impl Parser<'tokens, ParserInput<'tokens, 'src>, Tag, extra::Err<Rich<'tokens, Token<'src>, Span>>>
|
||||||
|
{
|
||||||
recursive(|tag| {
|
recursive(|tag| {
|
||||||
let tags_body = tag
|
let tags_body = tag
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -25,7 +31,7 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||||
let text_body = select! {
|
let text_body = select! {
|
||||||
Token::TextBody(t) => t.to_owned(),
|
Token::TextBody(t) => t.to_owned(),
|
||||||
Token::MLText(t) => trim_indent(t).to_owned(),
|
Token::MLText(t) => trim_indent(t).to_owned(),
|
||||||
Token::MLMSText(n, t) => set_indent(t, n).to_owned(),
|
Token::MLMSText(n, t) => set_spaces(t, n).to_owned(),
|
||||||
Token::MLRText(t) => t.to_owned()
|
Token::MLRText(t) => t.to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,8 +59,11 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||||
.or_not()
|
.or_not()
|
||||||
.map(|v| v.unwrap_or(TNullArg::Null));
|
.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 hlarg = num_arg.try_map(|n, s| Hl::try_from(n).map_err(|e| Rich::custom(s, e)));
|
||||||
let alignarg =
|
let alignarg = choice((
|
||||||
num_arg.try_map(|n, s| AlignArg::try_from(n).map_err(|e| Rich::custom(s, e)));
|
just(Token::TextArgument("start")).to(AlignArg::Start),
|
||||||
|
just(Token::TextArgument("center")).to(AlignArg::Start),
|
||||||
|
just(Token::TextArgument("end")).to(AlignArg::Start),
|
||||||
|
));
|
||||||
|
|
||||||
let el = just(Token::El).ignore_then(nnbody.clone()).map(El);
|
let el = just(Token::El).ignore_then(nnbody.clone()).map(El);
|
||||||
let h = just(Token::H)
|
let h = just(Token::H)
|
||||||
|
@ -66,7 +75,7 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||||
let ul = just(Token::Ul).ignore_then(tags_body.clone()).map(Ul);
|
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 ol = just(Token::Ol).ignore_then(tags_body.clone()).map(Ol);
|
||||||
let row = just(Token::Row)
|
let row = just(Token::Row)
|
||||||
.ignore_then(alignarg.or_not())
|
.ignore_then(alignarg.clone().or_not())
|
||||||
.then(tags_body.clone())
|
.then(tags_body.clone())
|
||||||
.map(|(arg, body)| Row(body, arg.unwrap_or(AlignArg::Start)));
|
.map(|(arg, body)| Row(body, arg.unwrap_or(AlignArg::Start)));
|
||||||
let link = just(Token::Link)
|
let link = just(Token::Link)
|
||||||
|
@ -141,7 +150,4 @@ pub fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||||
.or(choice((block, carousel, code, pre, meta)))
|
.or(choice((block, carousel, code, pre, meta)))
|
||||||
.or(choice((el_text, el_tags, paragraph)))
|
.or(choice((el_text, el_tags, paragraph)))
|
||||||
})
|
})
|
||||||
.repeated()
|
|
||||||
.collect()
|
|
||||||
.map_with(|t, e| (Page { data: t }, e.span()))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ pub fn set_indent(input: &str, indent: usize) -> String {
|
||||||
prepend_indent(&trim_indent(input), indent)
|
prepend_indent(&trim_indent(input), indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_spaces(input: &str, spaces: usize) -> String {
|
||||||
|
prepend_spaces(&trim_indent(input), spaces)
|
||||||
|
}
|
||||||
|
|
||||||
fn trim_unused<'a>(s: &'a str) -> &'a str {
|
fn trim_unused<'a>(s: &'a str) -> &'a str {
|
||||||
let mut trim_start = 0;
|
let mut trim_start = 0;
|
||||||
let mut been_newlines = false;
|
let mut been_newlines = false;
|
||||||
|
@ -50,7 +54,11 @@ fn trim_unused<'a>(s: &'a str) -> &'a str {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepend_indent(input: &str, indent: usize) -> String {
|
pub fn prepend_indent(input: &str, indent: usize) -> String {
|
||||||
let indent = &" ".repeat(indent);
|
prepend_spaces(input, indent * 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepend_spaces(input: &str, spaces: usize) -> String {
|
||||||
|
let indent = &" ".repeat(spaces);
|
||||||
let lines: Vec<String> = input
|
let lines: Vec<String> = input
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| format!("{}{}", indent, line))
|
.map(|line| format!("{}{}", indent, line))
|
||||||
|
|
Loading…
Add table
Reference in a new issue