mirror of https://github.com/kdl-org/kdl.git
node, identifier, and comments done
This commit is contained in:
parent
950d5bfc85
commit
100a736145
13
src/node.rs
13
src/node.rs
|
|
@ -1 +1,12 @@
|
|||
pub struct Node;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
pub values: Vec<NodeValue>,
|
||||
pub properties: HashMap<String, NodeValue>,
|
||||
pub children: Vec<Node>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NodeValue {}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::combinator::{map, opt};
|
||||
use nom::character::complete::{alpha1, alphanumeric1, one_of};
|
||||
use nom::combinator::{map, not, opt, recognize};
|
||||
use nom::multi::{many0, many1};
|
||||
use nom::sequence::{delimited, preceded};
|
||||
use nom::sequence::{delimited, pair, preceded};
|
||||
use nom::IResult;
|
||||
|
||||
use crate::error::{ErrorKind, NodeParseError};
|
||||
use crate::node::Node;
|
||||
use crate::node::{Node, NodeValue};
|
||||
|
||||
/// `document := linespace* (node (newline document)?)?`
|
||||
pub(crate) fn nodes(input: &str) -> IResult<&str, Vec<Node>, NodeParseError<&str>> {
|
||||
|
|
@ -14,16 +17,70 @@ pub(crate) fn nodes(input: &str) -> IResult<&str, Vec<Node>, NodeParseError<&str
|
|||
many0(node)(input)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum NodeArg<'a> {
|
||||
Value(NodeValue),
|
||||
Property(&'a str, NodeValue),
|
||||
}
|
||||
|
||||
/// `node := identifier (node-space node-argument)* (node-space node-document)?`
|
||||
pub(crate) fn node(input: &str) -> IResult<&str, Node, NodeParseError<&str>> {
|
||||
let (input, tag) = identifier(input)?;
|
||||
let (input, args) = many0(preceded(node_space, node_arg))(input)?;
|
||||
let (input, children) = opt(preceded(node_space, node_children))(input)?;
|
||||
todo!();
|
||||
let (values, properties): (Vec<NodeArg>, Vec<NodeArg>) = args
|
||||
.into_iter()
|
||||
.partition(|arg| matches!(arg, NodeArg::Value(_)));
|
||||
Ok((
|
||||
input,
|
||||
Node {
|
||||
name: tag.into(),
|
||||
children: children.unwrap_or_else(Vec::new),
|
||||
values: values
|
||||
.into_iter()
|
||||
.map(|arg| match arg {
|
||||
NodeArg::Value(val) => val,
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect(),
|
||||
properties: properties.into_iter().fold(HashMap::new(), |mut acc, arg| {
|
||||
match arg {
|
||||
NodeArg::Property(key, value) => {
|
||||
acc.insert(String::from(key), value);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
acc
|
||||
}),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// `identifier := [a-zA-Z] [a-zA-Z0-9!#$%&'*+\-./:<>?@\^_|~]* | string`
|
||||
/// `identifier := [a-zA-Z_] [a-zA-Z0-9!#$%&'*+\-./:<>?@\^_|~]* | string`
|
||||
fn identifier(input: &str) -> IResult<&str, &str, NodeParseError<&str>> {
|
||||
alt((
|
||||
recognize(pair(
|
||||
alt((alpha1, tag("_"))),
|
||||
many0(alt((
|
||||
alphanumeric1,
|
||||
recognize(one_of("~!@#$%^&*-_+./:<>?")),
|
||||
))),
|
||||
)),
|
||||
string,
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn node_arg(input: &str) -> IResult<&str, NodeArg, NodeParseError<&str>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn node_children(input: &str) -> IResult<&str, Vec<Node>, NodeParseError<&str>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// TODO: This should be much more specific about what escapes are allowed.
|
||||
/// `string := '"' ('\\' ["\\] | [^"])* '"'`
|
||||
fn string(input: &str) -> IResult<&str, &str, NodeParseError<&str>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
@ -37,12 +94,18 @@ fn node_space(input: &str) -> IResult<&str, (), NodeParseError<&str>> {
|
|||
|
||||
/// `single-line-comment := '//' ('\r' [^\n] | [^\r\n])* newline`
|
||||
fn single_line_comment(input: &str) -> IResult<&str, &str, NodeParseError<&str>> {
|
||||
todo!()
|
||||
let (input, _) = tag("//")(input)?;
|
||||
let (input, comment) = recognize(many0(alt((
|
||||
preceded(tag("\r"), not(tag("\n"))),
|
||||
not(tag("\r\n")),
|
||||
))))(input)?;
|
||||
let (input, _) = newline(input)?;
|
||||
Ok((input, comment))
|
||||
}
|
||||
|
||||
/// `multi-line-comment := '/*' ('*' [^\/] | [^*])* '*/'`
|
||||
fn multi_line_comment(input: &str) -> IResult<&str, &str, NodeParseError<&str>> {
|
||||
todo!()
|
||||
delimited(tag("/*"), recognize(many0(not(tag("*/")))), tag("*/"))(input)
|
||||
}
|
||||
|
||||
/// `escline := '\\' ws* (single-line-comment | newline)`
|
||||
|
|
|
|||
Loading…
Reference in New Issue