From 84cb7e52daad84a9af7f5e2f3d46793dae7cd991 Mon Sep 17 00:00:00 2001 From: Hare Date: Mon, 9 Dec 2024 00:39:19 +0900 Subject: [PATCH] Add NodeEnd token and multiple nodes support --- src/om/tokenizer.rs | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/om/tokenizer.rs b/src/om/tokenizer.rs index 49c8a5a..794c466 100644 --- a/src/om/tokenizer.rs +++ b/src/om/tokenizer.rs @@ -49,6 +49,10 @@ impl Iterator for Tokenizer { self.state = State::NodeOpen; } ' ' | '\n' | '\t' => {} + ')' => { + self.state = State::Data; + return Some(Token::NodeEnd); + } _ if self.is_eof() => { return Some(Token::EOF); } @@ -80,9 +84,6 @@ impl Iterator for Tokenizer { }); self.buffer.clear(); } - ')' => { - self.state = State::Data; - } _ if self.is_eof() => { return Some(Token::EOF); } @@ -171,7 +172,7 @@ impl Iterator for Tokenizer { x if x.is_ascii_alphanumeric() => { self.buffer.push(c); } - ']' => { + ' ' | '\n' | '\t' | ']' => { if let Some(t) = self.latest.as_mut() { match t { Token::Define { @@ -181,13 +182,13 @@ impl Iterator for Tokenizer { behavior.last_mut().unwrap().set_value(self.buffer.clone()); self.buffer.clear(); self.state = State::Behavior; + self.reconsume = true; } _ => {} } } - return self.latest.take(); } - ' ' | '\n' => {} + _ if self.is_eof() => { return Some(Token::EOF); } @@ -218,6 +219,7 @@ pub enum Token { behavior: Vec, }, Character(char), + NodeEnd, EOF, } @@ -251,4 +253,32 @@ mod tests { assert_eq!(Some(e), tokenizer.next()); } } + + #[test] + fn test_tokenizer_multiple_nodes() { + let input = "(foo [prefix:key=value]) (bar [prefix:key=value])".to_string(); + let mut tokenizer = Tokenizer::new(input); + let expected = [ + Token::Define { + name: "foo".to_string(), + behavior: vec![BehaviorItem { + prefix: Some("prefix".to_string()), + key: "key".to_string(), + value: "value".to_string(), + }], + }, + Token::Define { + name: "bar".to_string(), + behavior: vec![BehaviorItem { + prefix: Some("prefix".to_string()), + key: "key".to_string(), + value: "value".to_string(), + }], + }, + Token::EOF, + ]; + for e in expected { + assert_eq!(Some(e), tokenizer.next()); + } + } }