Start working on cog parser. Codeblock parser seems to work
This commit is contained in:
parent
86530202b3
commit
d1c99982c7
5 changed files with 117 additions and 11 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -17,3 +17,29 @@ version = "0.1.0"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cogs_parser"
|
name = "cogs_parser"
|
||||||
version = "0.1.0"
|
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",
|
||||||
|
]
|
||||||
|
|
|
@ -1,23 +1,28 @@
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Component {
|
pub struct Component {
|
||||||
pub elements: Vec<Element>,
|
pub elements: Vec<Element>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Element {
|
pub enum Element {
|
||||||
Html(HtmlTag),
|
Html(HtmlTag),
|
||||||
Block(CodeBlock),
|
Block(CodeBlock),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct HtmlTag {
|
pub struct HtmlTag {
|
||||||
pub tag: String,
|
pub tag: String,
|
||||||
pub attributes: Vec<Attribute>,
|
pub attributes: Vec<Attribute>,
|
||||||
pub content: Vec<Element>,
|
pub content: Vec<Element>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Attribute {
|
pub struct Attribute {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct CodeBlock {
|
pub struct CodeBlock {
|
||||||
pub is_async: bool,
|
pub is_async: bool,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
|
|
|
@ -4,3 +4,5 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
nom = "7.1.3"
|
||||||
|
cogs_ast.path = "../ast"
|
|
@ -1,14 +1,82 @@
|
||||||
pub fn add(left: u64, right: u64) -> u64 {
|
use nom::{
|
||||||
left + right
|
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)]
|
fn parse_element(input: &str) -> IResult<&str, Element> {
|
||||||
mod tests {
|
alt((parse_html_tag, parse_code_block))(input)
|
||||||
use super::*;
|
}
|
||||||
|
|
||||||
#[test]
|
fn parse_html_tag(input: &str) -> IResult<&str, Element> {
|
||||||
fn it_works() {
|
let (input, (tag, (attributes, content))) = delimited(
|
||||||
let result = add(2, 2);
|
char('<'),
|
||||||
assert_eq!(result, 4);
|
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(),
|
||||||
|
}),
|
||||||
|
))
|
||||||
}
|
}
|
5
crates/parser/src/main.rs
Normal file
5
crates/parser/src/main.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use cogs_parser::parse_cog;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{:#?}", parse_cog("{println!(\"Hello\")}\n<h1>hi</h1>"));
|
||||||
|
}
|
Loading…
Reference in a new issue