summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-24 21:15:59 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-25 18:55:45 +0200
commit74b4ecf29d389728ed43692a308b42d4d282c6e5 (patch)
tree5d28afda0a0b7f27714dcf0830e60843a7421224
parenta421cd94ac14f6c33d8d70741540cfbc49bb3e92 (diff)
downloadrebel-74b4ecf29d389728ed43692a308b42d4d282c6e5.tar
rebel-74b4ecf29d389728ed43692a308b42d4d282c6e5.zip
rebel-parse: add support for !Copy tokens
-rw-r--r--crates/rebel-parse/benches/recipe.rs4
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs8
-rw-r--r--crates/rebel-parse/src/grammar/tokenize.rs4
-rw-r--r--crates/rebel-parse/src/token.rs34
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<Token<'static>> {
+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<T>(expr: rule<T>, delim: rule<()>) -> Vec<T>
= 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<Token<'input>>
- = _ 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<Token<'a>>);
+
+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<Self::Element> {
+ use peg::RuleResult;
+
+ match self.0[pos..].first() {
+ Some(c) => RuleResult::Matched(pos + 1, c),
+ None => RuleResult::Failed,
+ }
+ }
+}