Skip to content

Commit

Permalink
Merge pull request pest-parser#55 from steffengy/example
Browse files Browse the repository at this point in the history
Implement support for references within StringInput
  • Loading branch information
dragostis committed Jun 13, 2016
2 parents 402c560 + 248d8ea commit 31ac0a1
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/inputs/string_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<'a> StringInput<'a> {
}
}

impl<'a> Input for StringInput<'a> {
impl<'a> Input<'a> for StringInput<'a> {
#[inline]
fn len(&self) -> usize {
self.string.len()
Expand All @@ -70,7 +70,7 @@ 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]
}

Expand Down
4 changes: 2 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/// A `trait` that defines a parser.
pub trait Parser {
pub trait Parser<'a> {
type Rule;
type Token;

Expand Down Expand Up @@ -52,7 +52,7 @@ pub trait Parser {
fn reset(&mut self);

/// Slices a `Parser`'s `Input`.
fn slice_input(&self, start: usize, end: usize) -> &str;
fn slice_input(&self, start: usize, end: usize) -> &'a str;

/// Returns the queue of all matched `Token`s.
fn queue(&self) -> &Vec<Self::Token>;
Expand Down
17 changes: 10 additions & 7 deletions src/parsers/rdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,22 +114,24 @@ macro_rules! impl_rdp {
( grammar! { $( $ts:tt )* } $( $mac:ident! { $( $rest:tt )* } )* ) => {
use std::cell::Cell;
use std::cmp;
use std::marker::PhantomData;

pub struct Rdp<T: Input> {
pub struct Rdp<'n, T: Input<'n>> {
input: T,
queue: Vec<Token<Rule>>,
queue_index: Cell<usize>,
failures: Vec<Rule>,
fail_pos: usize,
atomic: bool,
comment: bool,
eoi_matched: bool
eoi_matched: bool,
phantom: PhantomData<Input<'n>>
}

impl_rdp!(@filter [ $( $ts )* ] []);

impl<T: Input> Rdp<T> {
pub fn new(input: T) -> Rdp<T> {
impl<'n, T: Input<'n>> Rdp<'n, T> {
pub fn new(input: T) -> Rdp<'n, T> {
Rdp {
input: input,
queue: vec![],
Expand All @@ -138,7 +140,8 @@ macro_rules! impl_rdp {
fail_pos: 0,
atomic: false,
comment: false,
eoi_matched: false
eoi_matched: false,
phantom: PhantomData
}
}

Expand Down Expand Up @@ -189,7 +192,7 @@ macro_rules! impl_rdp {
)*
}

impl<T: Input> Parser for Rdp<T> {
impl<'n, T: Input<'n>> Parser<'n> for Rdp<'n, T> {
type Rule = Rule;
type Token = Token<Rule>;

Expand Down Expand Up @@ -316,7 +319,7 @@ macro_rules! impl_rdp {
}

#[inline]
fn slice_input(&self, start: usize, end: usize) -> &str {
fn slice_input(&self, start: usize, end: usize) -> &'n str {
self.input.slice(start, end)
}

Expand Down
43 changes: 43 additions & 0 deletions tests/sentence_lifetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// pest. Elegant, efficient grammars
// Copyright (C) 2016 Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#[macro_use]
extern crate pest;

use std::collections::LinkedList;

use pest::prelude::*;

#[derive(Debug, PartialEq)]
pub enum Node<'a> {
Sentence(&'a str),
}

impl_rdp! {
grammar! {
word = { letter* }
letter = { ['a'..'z'] }
}

process! {
main(&self) -> Node<'n> {
(&w: word) => Node::Sentence(w)
}
}
}

#[test]
fn word() {
let file = "abc def";
let result = {
let mut parser = Rdp::new(StringInput::new(&file));

assert!(parser.word());
parser.process()
};
assert_eq!(result, Node::Sentence("abc"));
}

0 comments on commit 31ac0a1

Please sign in to comment.