logoalt Hacker News

ryandv11/10/20241 replyview on HN

I tried winnow as suggested elsewhere in this thread, this is what it may look like:

    use winnow::combinator::{ repeat };
    use winnow::token::take_while;
    use winnow::prelude::*;

    pub fn csg_parse(input: &mut &str) -> PResult<usize> {
        let a: &str = take_while(0.., 'a').parse_next(input)?;
        let n: usize = a.len();
        repeat(n, "b").parse_next(input)?;
        repeat(n, "c").parse_next(input)?;
        '\n'.parse_next(input)?;
        return Ok(n);
    }

    #[cfg(test)]
    mod test {
        use super::*;

        #[test]
        fn parses_examples() {
            assert_eq!(Ok(0), csg_parse(&mut "\n"));
            assert_eq!(Ok(3), csg_parse(&mut "aaabbbccc\n"));

            assert!(csg_parse(&mut "abcc\n").is_err());
            assert!(csg_parse(&mut "abbcc\n").is_err());
            assert!(csg_parse(&mut "aabc\n").is_err());
            assert!(csg_parse(&mut "aabbc\n").is_err());
            assert!(csg_parse(&mut "def\n").is_err());
        }
    }

Replies

thesz11/11/2024

So you are directly express context-sensitivity instead of approximating it with infinite context-free grammar.

Okay, good enough.