Skip to content

Commit

Permalink
parser: accept more input types
Browse files Browse the repository at this point in the history
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
  • Loading branch information
Keruspe committed Nov 29, 2017
1 parent 2addc29 commit 09f1cfd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 32 deletions.
32 changes: 16 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ name = "brainfuck"

[dependencies]
clap = "^2"
nom = "^4.0.0-alpha1"
#nom = "^4.0.0-alpha1"
[dependencies.nom]
git = "git://github.com/Keruspe/nom"

[badges]
travis-ci = { repository = "Keruspe/brainfuck.rs" }
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ impl From<io::Error> for Error {
}
}

impl<'a> From<nom::Err<&'a [u8], u32>> for Error {
fn from(err: nom::Err<&[u8], u32>) -> Error {
impl<T: fmt::Debug> From<nom::Err<T, u32>> for Error {
fn from(err: nom::Err<T, u32>) -> Error {
Error::ParseError(format!("{:?}", err))
}
}
Expand Down
40 changes: 27 additions & 13 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use ast::{Block, Node};
use nom;

use std::ops;

const ALLOWED: &'static str = "<>+-.,[]";

pub fn skip_unknown_bf(i: &[u8]) -> Result<(&[u8], &[u8]), nom::Err<&[u8], u32>> {
is_not!(i, ALLOWED).or(Ok((i, &i[0..0])))
pub fn skip_unknown_bf<T>(i: T) -> nom::IResult<T, T, u32>
where T: nom::InputIter+nom::InputLength+nom::Slice<ops::RangeFrom<usize>>+nom::Slice<ops::RangeTo<usize>>+nom::Slice<ops::Range<usize>>+Copy,
&'static str: nom::FindToken<<T as nom::InputIter>::RawItem> {
is_not!(i, ALLOWED).or(Ok((i, i.slice(0..0))))
}

macro_rules! tag_bf (
Expand All @@ -14,17 +18,27 @@ macro_rules! tag_bf (
});
);

named!(pub lshift<Node>, do_parse!(tag_bf!("<") >> (Node::LShift)));
named!(pub rshift<Node>, do_parse!(tag_bf!(">") >> (Node::RShift)));
named!(pub plus<Node>, do_parse!(tag_bf!("+") >> (Node::Inc)));
named!(pub minus<Node>, do_parse!(tag_bf!("-") >> (Node::Dec)));
named!(pub dot<Node>, do_parse!(tag_bf!(".") >> (Node::PutCh)));
named!(pub comma<Node>, do_parse!(tag_bf!(",") >> (Node::GetCh)));
named!(pub parse_loop<Node>, preceded!(tag_bf!("["), map!(many_till!(call!(node), tag_bf!("]")), |(nodes, _)| Node::Loop(From::from(nodes)))));
named!(pub node<Node>, alt!(lshift | rshift | plus | minus | dot | comma | parse_loop));

pub fn parse(i: &[u8]) -> Result<Block, nom::Err<&[u8], u32>> {
do_parse!(i,
macro_rules! bf_named {
(pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
fn $name<T>( i: T ) -> nom::IResult<T, $o, u32>
where T: nom::InputIter+nom::InputLength+nom::AtEof+nom::Compare<&'static str>+nom::Slice<ops::RangeFrom<usize>>+nom::Slice<ops::RangeTo<usize>>+nom::Slice<ops::Range<usize>>+Clone+Copy+PartialEq,
&'static str: nom::FindToken<<T as nom::InputIter>::RawItem> {
$submac!(i, $($args)*)
}
);
}

bf_named!(pub lshift<Node>, do_parse!(tag_bf!("<") >> (Node::LShift)));
bf_named!(pub rshift<Node>, do_parse!(tag_bf!(">") >> (Node::RShift)));
bf_named!(pub plus<Node>, do_parse!(tag_bf!("+") >> (Node::Inc)));
bf_named!(pub minus<Node>, do_parse!(tag_bf!("-") >> (Node::Dec)));
bf_named!(pub dot<Node>, do_parse!(tag_bf!(".") >> (Node::PutCh)));
bf_named!(pub comma<Node>, do_parse!(tag_bf!(",") >> (Node::GetCh)));
bf_named!(pub parse_loop<Node>, preceded!(tag_bf!("["), map!(many_till!(call!(node), tag_bf!("]")), |(nodes, _)| Node::Loop(From::from(nodes)))));
bf_named!(pub node<Node>, alt!(lshift | rshift | plus | minus | dot | comma | parse_loop));

pub fn parse(i: &[u8]) -> Result<Block, nom::Err<nom::types::CompleteByteSlice, u32>> {
do_parse!(nom::types::CompleteByteSlice(i),
res: map!(many0!(complete!(node)), From::from) >>
eof!() >>
(res)
Expand Down

0 comments on commit 09f1cfd

Please sign in to comment.