From 7dbebdaa966ed7ae91d2fe4e16d7586fd4763b25 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 22 Jun 2016 23:07:15 +0800 Subject: [PATCH] adding lifetime back Signed-off-by: Ning Sun --- src/input.rs | 4 +- src/inputs/string_input.rs | 20 ++++---- src/parser.rs | 17 ++++--- src/parsers/rdp.rs | 98 +++++++++++++++++++++++++++----------- tests/sentence_lifetime.rs | 2 +- 5 files changed, 95 insertions(+), 46 deletions(-) diff --git a/src/input.rs b/src/input.rs index 6ab2dde3..e43dc9f8 100644 --- a/src/input.rs +++ b/src/input.rs @@ -6,7 +6,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. /// A `trait` that defines an input for a `Parser`. -pub trait Input { +pub trait Input<'a> { /// Returns length of an `Input`. fn len(&self) -> usize; @@ -20,7 +20,7 @@ pub trait Input { fn set_pos(&mut self, pos: usize); /// Slices an `Input`. - fn slice(&self, start: usize, end: usize) -> &str; + fn slice(&self, start: usize, end: usize) -> &'a str; /// Returns the line and column of a position for an `Input`. fn line_col(&self, pos: usize) -> (usize, usize); diff --git a/src/inputs/string_input.rs b/src/inputs/string_input.rs index 81458566..930cb586 100644 --- a/src/inputs/string_input.rs +++ b/src/inputs/string_input.rs @@ -25,7 +25,7 @@ use super::super::Input; /// ``` pub struct StringInput<'a> { string: &'a str, - pos: usize + pos: usize, } impl<'a> StringInput<'a> { @@ -43,12 +43,12 @@ impl<'a> StringInput<'a> { pub fn new(string: &'a str) -> StringInput<'a> { StringInput { string: string, - pos : 0 + pos: 0, } } } -impl<'a> Input for StringInput<'a> { +impl<'a> Input<'a> for StringInput<'a> { #[inline] fn len(&self) -> usize { self.string.len() @@ -70,14 +70,16 @@ impl<'a> Input for StringInput<'a> { } #[inline] - fn slice(&self, start: usize, end: usize) -> &str { + fn slice(&self, start: usize, end: usize) -> &'a str { &self.string[start..end] } #[inline] fn line_col(&self, pos: usize) -> (usize, usize) { - fn find(chars: &mut Peekable, pos: usize, - current: (usize, usize)) -> (usize, usize) { + fn find(chars: &mut Peekable, + pos: usize, + current: (usize, usize)) + -> (usize, usize) { if pos == 0 { current } else { @@ -94,10 +96,10 @@ impl<'a> Input for StringInput<'a> { } else { find(chars, pos - 1, (current.0 + 1, 1)) } - }, + } Some('\n') => find(chars, pos - 1, (current.0 + 1, 1)), - Some(c) => find(chars, pos - c.len_utf8(), (current.0, current.1 + 1)), - None => unreachable!() + Some(c) => find(chars, pos - c.len_utf8(), (current.0, current.1 + 1)), + None => unreachable!(), } } } diff --git a/src/parser.rs b/src/parser.rs index 2b38477f..cbc710a3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -8,13 +8,13 @@ use super::Input; /// A `trait` that defines a parser. -pub trait Parser { +pub trait Parser<'a, T: Input<'a>> { type Rule; type Token; - fn input(&self) -> &Input; + fn input(&self) -> &T; - fn input_mut(&mut self) -> &mut Input; + fn input_mut(&mut self) -> &mut T; /// Tries to match `rule`, returns whether it matched, and advances a parser with in case it /// did. If `revert` is `true`, the parser will not advance. @@ -28,9 +28,14 @@ pub trait Parser { /// was not silented) along with its precedence and right-associativity, or `None` if no /// operator passes. This operator triplet is also returned by the function when it greedily /// parses an operator useful for a higher precedence. - fn prec_climb(&mut self, pos: usize, left: usize, min_prec: u8, - last_op: Option<(Option, u8, bool)>, primary: &mut F, - climb: &mut G) -> (Option<(Option, u8, bool)>, Option) + fn prec_climb(&mut self, + pos: usize, + left: usize, + min_prec: u8, + last_op: Option<(Option, u8, bool)>, + primary: &mut F, + climb: &mut G) + -> (Option<(Option, u8, bool)>, Option) where F: FnMut(&mut Self) -> bool, G: FnMut(&mut Self) -> Option<(Option, u8, bool)>; diff --git a/src/parsers/rdp.rs b/src/parsers/rdp.rs index b4113253..bbde9a01 100644 --- a/src/parsers/rdp.rs +++ b/src/parsers/rdp.rs @@ -115,7 +115,7 @@ macro_rules! impl_rdp { use std::cell::Cell; use std::cmp; - pub struct Rdp { + pub struct Rdp { input: T, queue: Vec>, queue_index: Cell, @@ -128,7 +128,7 @@ macro_rules! impl_rdp { impl_rdp!(@filter [ $( $ts )* ] []); - impl Rdp { + impl<'a, T: Input<'a>> Rdp { pub fn new(input: T) -> Rdp { Rdp { input: input, @@ -189,17 +189,17 @@ macro_rules! impl_rdp { )* } - impl Parser for Rdp { + impl<'a, T: Input<'a>> Parser<'a, T> for Rdp { type Rule = Rule; type Token = Token; #[inline] - fn input(&self) -> &Input { + fn input(&self) -> &T { &self.input } #[inline] - fn input_mut(&mut self) -> &mut Input { + fn input_mut(&mut self) -> &mut T { &mut self.input } @@ -467,15 +467,41 @@ mod tests { assert!(parser.expression()); assert!(!parser.end()); - let queue = vec![ - Token { rule: Rule::paren, start: 2, end: 9 }, - Token { rule: Rule::paren, start: 5, end: 8 }, - Token { rule: Rule::paren, start: 9, end: 20 }, - Token { rule: Rule::paren, start: 10, end: 16 }, - Token { rule: Rule::paren, start: 12, end: 14 }, - Token { rule: Rule::paren, start: 16, end: 18 }, - Token { rule: Rule::paren, start: 20, end: 22 } - ]; + let queue = vec![Token { + rule: Rule::paren, + start: 2, + end: 9, + }, + Token { + rule: Rule::paren, + start: 5, + end: 8, + }, + Token { + rule: Rule::paren, + start: 9, + end: 20, + }, + Token { + rule: Rule::paren, + start: 10, + end: 16, + }, + Token { + rule: Rule::paren, + start: 12, + end: 14, + }, + Token { + rule: Rule::paren, + start: 16, + end: 18, + }, + Token { + rule: Rule::paren, + start: 20, + end: 22, + }]; assert_eq!(parser.queue(), &queue); } @@ -487,9 +513,11 @@ mod tests { assert!(parser.zero()); assert!(!parser.end()); - let queue = vec![ - Token { rule: Rule::zero, start: 2, end: 15 } - ]; + let queue = vec![Token { + rule: Rule::zero, + start: 2, + end: 15, + }]; assert_eq!(parser.queue(), &queue); } @@ -501,9 +529,11 @@ mod tests { assert!(parser.one()); assert!(!parser.end()); - let queue = vec![ - Token { rule: Rule::one, start: 2, end: 15 } - ]; + let queue = vec![Token { + rule: Rule::one, + start: 2, + end: 15, + }]; assert_eq!(parser.queue(), &queue); } @@ -515,10 +545,16 @@ mod tests { assert!(parser.expression()); assert!(parser.end()); - let queue = vec![ - Token { rule: Rule::paren, start: 6, end: 10 }, - Token { rule: Rule::paren, start: 7, end: 9 } - ]; + let queue = vec![Token { + rule: Rule::paren, + start: 6, + end: 10, + }, + Token { + rule: Rule::paren, + start: 7, + end: 9, + }]; assert_eq!(parser.queue(), &queue); } @@ -530,10 +566,16 @@ mod tests { assert!(parser.expression()); assert!(parser.end()); - let queue = vec![ - Token { rule: Rule::paren, start: 11, end: 15 }, - Token { rule: Rule::paren, start: 12, end: 14 } - ]; + let queue = vec![Token { + rule: Rule::paren, + start: 11, + end: 15, + }, + Token { + rule: Rule::paren, + start: 12, + end: 14, + }]; assert_eq!(parser.queue(), &queue); } diff --git a/tests/sentence_lifetime.rs b/tests/sentence_lifetime.rs index 618e648c..8700c9a1 100644 --- a/tests/sentence_lifetime.rs +++ b/tests/sentence_lifetime.rs @@ -24,7 +24,7 @@ impl_rdp! { } process! { - _word(&self) -> Node { + _word(&self) -> Node<'a> { (&w: word) => Node::Sentence(w) } }