From 74b4ecf29d389728ed43692a308b42d4d282c6e5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 24 Apr 2024 21:15:59 +0200 Subject: rebel-parse: add support for !Copy tokens --- crates/rebel-parse/benches/recipe.rs | 4 ++-- crates/rebel-parse/src/grammar/recipe.rs | 8 +++---- crates/rebel-parse/src/grammar/tokenize.rs | 4 ++-- crates/rebel-parse/src/token.rs | 34 +++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/crates/rebel-parse/benches/recipe.rs b/crates/rebel-parse/benches/recipe.rs index 08eab7d..4cff857 100644 --- a/crates/rebel-parse/benches/recipe.rs +++ b/crates/rebel-parse/benches/recipe.rs @@ -1,4 +1,4 @@ -use rebel_parse::{ast, token::Token}; +use rebel_parse::{ast, token::TokenStream}; fn main() { divan::main(); @@ -7,7 +7,7 @@ fn main() { const RECIPE: &str = include_str!("../../../examples/recipes/gmp/build.recipe"); #[divan::bench] -fn tokenize() -> Vec> { +fn tokenize() -> TokenStream<'static> { rebel_parse::tokenize::token_stream(divan::black_box(RECIPE)).unwrap() } diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index 2888374..633b021 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -4,7 +4,7 @@ use crate::token::*; pub use rules::*; peg::parser! { - pub grammar rules<'a>() for [Token<'a>] { + pub grammar rules<'a>() for TokenStream<'a> { use ast::OpBinary::*; use ast::OpUnary::*; @@ -126,10 +126,10 @@ peg::parser! { } rule p_(ch: char) - = [Token::Punct(Punct(c, Spacing::Joint)) if c == ch] {} + = [Token::Punct(Punct(c, Spacing::Joint)) if *c == ch] {} rule p(ch: char) -> () - = [Token::Punct(Punct(c, _)) if c == ch] {} + = [Token::Punct(Punct(c, _)) if *c == ch] {} rule p2(ch1: char, ch2: char) = p_(ch1) p(ch2) @@ -153,7 +153,7 @@ peg::parser! { = const_ident("task") rule const_ident(keyword: &str) - = [Token::Ident(name) if keyword == name] + = [Token::Ident(name) if *name == keyword] rule delimited(expr: rule, delim: rule<()>) -> Vec = values:(expr() ++ delim()) delim()? { values } diff --git a/crates/rebel-parse/src/grammar/tokenize.rs b/crates/rebel-parse/src/grammar/tokenize.rs index 826f4ce..5f21461 100644 --- a/crates/rebel-parse/src/grammar/tokenize.rs +++ b/crates/rebel-parse/src/grammar/tokenize.rs @@ -4,8 +4,8 @@ pub use rules::*; peg::parser! { pub grammar rules() for str { - pub rule token_stream() -> Vec> - = _ tokens:(token() ** _) _ { tokens } + pub rule token_stream() -> TokenStream<'input> + = _ tokens:(token() ** _) _ { TokenStream(tokens) } pub rule token() -> Token<'input> = number:number() { Token::Number(number) } diff --git a/crates/rebel-parse/src/token.rs b/crates/rebel-parse/src/token.rs index 5e6b741..d147205 100644 --- a/crates/rebel-parse/src/token.rs +++ b/crates/rebel-parse/src/token.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Token<'a> { Ident(&'a str), Punct(Punct), @@ -27,3 +27,35 @@ pub enum StringKind { RawString, ScriptString, } + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TokenStream<'a>(pub Vec>); + +impl<'a> peg::Parse for TokenStream<'a> { + type PositionRepr = usize; + + fn start(&self) -> usize { + 0 + } + + fn is_eof(&self, pos: usize) -> bool { + pos >= self.0.len() + } + + fn position_repr(&self, pos: usize) -> Self::PositionRepr { + pos + } +} + +impl<'input, 'a: 'input> peg::ParseElem<'input> for TokenStream<'a> { + type Element = &'input Token<'a>; + + fn parse_elem(&'input self, pos: usize) -> peg::RuleResult { + use peg::RuleResult; + + match self.0[pos..].first() { + Some(c) => RuleResult::Matched(pos + 1, c), + None => RuleResult::Failed, + } + } +} -- cgit v1.2.3