working on it (slow)
This commit is contained in:
parent
834049af18
commit
c3642676b2
1 changed files with 24 additions and 93 deletions
117
src/main.rs
117
src/main.rs
|
@ -1,6 +1,12 @@
|
||||||
use std::fmt::Display;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
use winnow::{IResult, bytes::{take_while0, take_until0}, character::{alphanumeric1, multispace0}, error::ParseError, Parser, sequence::{delimited, preceded}, branch, combinator::todo, multi::{fold_many0, many0}};
|
use winnow::prelude::*;
|
||||||
|
|
||||||
|
use crate::parser::el_parser;
|
||||||
|
|
||||||
|
mod parser;
|
||||||
|
mod element;
|
||||||
|
mod util;
|
||||||
|
|
||||||
const TEST_IHL: &str = "
|
const TEST_IHL: &str = "
|
||||||
html {
|
html {
|
||||||
|
@ -12,7 +18,7 @@ html {
|
||||||
p \"this is a test file\"
|
p \"this is a test file\"
|
||||||
p {
|
p {
|
||||||
\"some text followed by \"
|
\"some text followed by \"
|
||||||
a \"a hyperlink\"
|
a [ href = \"https://schrottkatze.de\" ] \"a hyperlink\"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,98 +30,23 @@ fn main() {
|
||||||
println!("{e}");
|
println!("{e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn el_parser(input: &str) -> IResult<&str, Element> {
|
type Name<'a> = &'a str;
|
||||||
(
|
|
||||||
el_name_parser,
|
|
||||||
el_body_parser
|
|
||||||
).map(|(name, children)| Element { name, children }).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
enum Token<'a> {
|
||||||
fn el_name_parser(input: &str) -> IResult<&str, &str> {
|
Name(Name<'a>),
|
||||||
ws(alphanumeric1).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn el_body_parser(input: &str) -> IResult<&str, ElBody> {
|
|
||||||
ws(branch::alt((
|
|
||||||
string_parser.map(|s| ElBody::Text(s)),
|
|
||||||
delimited(
|
|
||||||
'{',
|
|
||||||
many0(content_parser).map(|v| ElBody::Elements(v)),
|
|
||||||
'}'
|
|
||||||
)
|
|
||||||
))).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn content_parser(input: &str) -> IResult<&str, ElContent> {
|
|
||||||
ws(branch::alt((
|
|
||||||
string_parser.map(|s| ElContent::Text(s)),
|
|
||||||
el_parser.map(|e| ElContent::El(e))
|
|
||||||
))).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn string_parser(input: &str) -> IResult<&str, &str> {
|
|
||||||
delimited(
|
|
||||||
'"',
|
|
||||||
take_until0("\""),
|
|
||||||
'"',
|
|
||||||
).parse_next(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Element<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
children: ElBody<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Display for Element<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "<{0}>{1}</{0}>", self.name, self.children)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// the direct content of `children`, so it can be a plaintext element
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ElBody<'a> {
|
|
||||||
Elements(Vec<ElContent<'a>>),
|
|
||||||
Text(&'a str),
|
Text(&'a str),
|
||||||
}
|
Number(i32), // TODO: more complex number type
|
||||||
impl<'a> Display for ElBody<'a> {
|
//
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
BlockBrackets(Vec<Token<'a>>), // [] block
|
||||||
match self {
|
BlockBraces(Vec<Token<'a>>), // {} block
|
||||||
ElBody::Text(s) => f.write_str(s),
|
BlockParentheses(Vec<Token<'a>>), // () block
|
||||||
ElBody::Elements(els) => els.iter().try_for_each(|e| f.write_str(&e.to_string()))
|
|
||||||
}
|
PunctColon, // :
|
||||||
}
|
PunctSemi, // ;
|
||||||
|
PunctComma, // ,
|
||||||
|
PunctDot, // .
|
||||||
|
|
||||||
|
KwItem, // `item` defines a new simple ish item type
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ElContent<'a> {
|
|
||||||
El(Element<'a>),
|
|
||||||
Text(&'a str),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Display for ElContent<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
ElContent::Text(s) => f.write_str(s),
|
|
||||||
ElContent::El(el) => f.write_str(&el.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parse_basic() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// whitespace combinator from [winnow docs](https://docs.rs/winnow/latest/winnow/_topic/language/index.html#wrapper-combinators-that-eat-whitespace-before-and-after-a-parser)
|
|
||||||
fn ws<'a, F, O, E: ParseError<&'a str>>(inner: F) -> impl Parser<&'a str, O, E>
|
|
||||||
where
|
|
||||||
F: Parser<&'a str, O, E>,
|
|
||||||
{
|
|
||||||
delimited(
|
|
||||||
multispace0,
|
|
||||||
inner,
|
|
||||||
multispace0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue