Start working on cog parser. Codeblock parser seems to work

This commit is contained in:
Ermia Behzadifar 2024-11-12 16:34:27 +01:00
parent 86530202b3
commit d1c99982c7
5 changed files with 117 additions and 11 deletions

26
Cargo.lock generated
View file

@ -17,3 +17,29 @@ version = "0.1.0"
[[package]]
name = "cogs_parser"
version = "0.1.0"
dependencies = [
"cogs_ast",
"nom",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]

View file

@ -1,23 +1,28 @@
#[derive(Debug)]
pub struct Component {
pub elements: Vec<Element>,
}
#[derive(Debug)]
pub enum Element {
Html(HtmlTag),
Block(CodeBlock),
}
#[derive(Debug)]
pub struct HtmlTag {
pub tag: String,
pub attributes: Vec<Attribute>,
pub content: Vec<Element>,
}
#[derive(Debug)]
pub struct Attribute {
pub name: String,
pub value: String,
}
#[derive(Debug)]
pub struct CodeBlock {
pub is_async: bool,
pub content: String,

View file

@ -4,3 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
nom = "7.1.3"
cogs_ast.path = "../ast"

View file

@ -1,14 +1,82 @@
pub fn add(left: u64, right: u64) -> u64 {
left + right
use nom::{
IResult,
character::{
complete::{char, multispace0},
streaming::none_of
},
combinator::{opt, value},
branch::alt,
multi::{many0, many1},
sequence::{delimited, pair, preceded, terminated},
};
use cogs_ast::{Component, Element, HtmlTag, Attribute, CodeBlock};
pub fn parse_cog(input: &str) -> IResult<&str, Component> {
let (input, elements) = many0(parse_element)(input)?;
Ok((input, Component { elements }))
}
#[cfg(test)]
mod tests {
use super::*;
fn parse_element(input: &str) -> IResult<&str, Element> {
alt((parse_html_tag, parse_code_block))(input)
}
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
fn parse_html_tag(input: &str) -> IResult<&str, Element> {
let (input, (tag, (attributes, content))) = delimited(
char('<'),
pair(
terminated(many1(none_of(" >/\n")), many0(multispace0)),
pair(
opt(delimited(char(' '), many1(parse_attribute), char('>'))),
many0(parse_element),
),
),
char('>'),
)(input)?;
println!("got result {tag:?}");
Ok((
input,
Element::Html(HtmlTag {
tag: tag.iter().collect(),
attributes: attributes.unwrap(),
content,
}),
))
}
fn parse_attribute(input: &str) -> IResult<&str, Attribute> {
println!("Attempting to parse attribute");
let (input, (name, value)) = pair(
many1(none_of("= ")),
preceded(char('='), delimited(char('"'), many0(none_of("\"")), char('"'))),
)(input)?;
Ok((
input,
Attribute {
name: name.iter().collect(),
value: value.iter().collect(),
},
))
}
fn parse_code_block(input: &str) -> IResult<&str, Element> {
let (input, (is_async, content)) = delimited(
char('{'),
pair(
opt(value(true, preceded(char('a'), char('s')))),
many1(none_of("}")),
),
char('}'),
)(input)?;
Ok((
input,
Element::Block(CodeBlock {
is_async: is_async.unwrap_or(false),
content: content.into_iter().collect(),
}),
))
}

View file

@ -0,0 +1,5 @@
use cogs_parser::parse_cog;
fn main() {
println!("{:#?}", parse_cog("{println!(\"Hello\")}\n<h1>hi</h1>"));
}