Expand description
The crate provides a basic mechanism to parse grammars using Logo as a lexer and a simple recursive descendant LL(1) parser with a backtracking function.
Example
use crate::parsit::token;
use crate::parsit::step::Step;
use crate::parsit::parser::EmptyToken;
use crate::parsit::parser::Parsit;
use crate::parsit::error::ParseError;
use logos::Logos;
#[derive(Logos, Debug, Copy, Clone, PartialEq)]
pub enum Token<'a> {
#[regex(r"[a-zA-Z-]+")]
Word(&'a str),
#[token(",")]
Comma,
#[token(".")]
Dot,
#[token("!")]
Bang,
#[token("?")]
Question,
#[regex(r"[ \t\r\n]+", logos::skip)]
Whitespace,
}
#[derive(Debug, Copy, Clone, PartialEq)]
enum Item<'a> {
Word(&'a str),
Comma,
}
#[derive(Debug, Clone, PartialEq)]
enum Sentence<'a> {
Sentence(Vec<Item<'a>>),
Question(Vec<Item<'a>>),
Exclamation(Vec<Item<'a>>),
}
struct Parser<'a> {
inner: Parsit<'a, Token<'a>>,
}
impl<'a> Parser<'a> {
fn new(text: &'a str) -> Parser<'a> {
let delegate: Parsit<Token> = Parsit::new(text).unwrap();
Parser { inner: delegate }
}
fn sentence(&self, pos: usize) -> Step<'a,Sentence<'a>> {
let items = |p| self.inner.one_or_more(p, |p| self.word(p));
let sentence = |p| items(p)
.then_zip(|p| token!(self.inner.token(p) => Token::Dot))
.take_left()
.map(Sentence::Sentence);
let exclamation = |p| items(p)
.then_zip(|p| token!(self.inner.token(p) => Token::Bang))
.take_left()
.map(Sentence::Exclamation);
let question = |p| items(p)
.then_zip(|p| token!(self.inner.token(p) => Token::Question))
.take_left()
.map(Sentence::Question);
sentence(pos)
.or_from(pos)
.or(exclamation)
.or(question).into()
}
fn word(&self, pos: usize) -> Step<'a,Item<'a>> {
token!(self.inner.token(pos) =>
Token::Word(v) => Item::Word(v),
Token::Comma => Item::Comma
)
}
fn text(&self) -> Result<Vec<Sentence<'a>>, ParseError<'a>> {
self.inner.zero_or_more(0, |p| self.sentence(p)).into()
}
}
let parser = Parser::new(r#"
I have a strange addiction,
It often sets off sparks!
I really cannot seem to stop,
Using exclamation marks!
Anyone heard of the interrobang?
The poem is for kids.
"#);
let result = parser.text();
println!("{:?}",result);
Modules
Macros
- Helps to parse a sequence
- Helps to parse a token on the lexer level
- Helps to parse a wrapper