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]]
|
||||
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",
|
||||
]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -4,3 +4,5 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nom = "7.1.3"
|
||||
cogs_ast.path = "../ast"
|
|
@ -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(),
|
||||
}),
|
||||
))
|
||||
}
|
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