Skip to content

Instantly share code, notes, and snippets.

@emwalker
Last active November 29, 2023 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emwalker/572811acb8ab1e5d5cb9a8219233bf2b to your computer and use it in GitHub Desktop.
Save emwalker/572811acb8ab1e5d5cb9a8219233bf2b to your computer and use it in GitHub Desktop.
Nom parser for CSS3 tokens
use super::{ast::Node, new_tokenizer::Token};
use nom::{
branch::alt, bytes::complete::tag, combinator::map, sequence::tuple, Compare, IResult,
InputIter, InputLength, InputTake,
};
impl InputLength for Token {
fn input_len(&self) -> usize {
1
}
}
#[derive(Clone, Debug)]
struct Span<'t>(&'t [Token]);
impl InputTake for Span<'_> {
fn take(&self, count: usize) -> Self {
todo!()
}
fn take_split(&self, count: usize) -> (Self, Self) {
todo!()
}
}
impl Compare<Token> for Span<'_> {
fn compare(&self, t: Token) -> nom::CompareResult {
todo!()
}
fn compare_no_case(&self, t: Token) -> nom::CompareResult {
todo!()
}
}
impl InputLength for Span<'_> {
fn input_len(&self) -> usize {
self.0.len()
}
}
struct SpanIter;
impl Iterator for SpanIter {
type Item = (usize, Token);
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
struct TokenIter;
impl Iterator for TokenIter {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
impl InputIter for Span<'_> {
type Item = Token;
type Iter = SpanIter;
type IterElem = TokenIter;
fn iter_indices(&self) -> Self::Iter {
todo!()
}
fn iter_elements(&self) -> Self::IterElem {
todo!()
}
fn position<P>(&self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool,
{
todo!()
}
fn slice_index(&self, count: usize) -> Result<usize, nom::Needed> {
todo!()
}
}
fn ident(i: Span) -> IResult<Span, Node> {
todo!()
}
fn child_combinator(i: Span) -> IResult<Span, Node> {
map(
tuple((ident, tag(Token::Delim('>')), ident)),
|(a, _, b)| Node {
name: "ChildCombinator".into(),
children: vec![a, b],
..Default::default()
},
)(i)
}
fn adjecent_sibling_combinator(i: Span) -> IResult<Span, Node> {
todo!()
}
fn general_sibling_combinator(i: Span) -> IResult<Span, Node> {
todo!()
}
fn column_combinator(i: Span) -> IResult<Span, Node> {
todo!()
}
fn parse_combinator(i: Span) -> IResult<Span, Node> {
alt((
child_combinator,
adjecent_sibling_combinator,
general_sibling_combinator,
column_combinator,
))(i)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
bytes::{CharIterator, Encoding},
css3::new_tokenizer::{TokenStreamer, Tokenizer},
};
fn input(s: &str) -> Vec<Token> {
let mut iter = CharIterator::new();
iter.read_from_str(s, Some(Encoding::UTF8));
let mut tokenizer = Tokenizer::new(&mut iter);
let mut res = vec![];
while tokenizer.current() != Token::Eof {
res.push(tokenizer.consume());
}
res
}
#[test]
fn good() {
let input = input("a > b");
let span = Span(&input);
let (_, node) = parse_combinator(span).unwrap();
assert_eq!(node.name, "ChildCombinator");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment