Add keyword parser
diff --git a/src/data.rs b/src/data.rs
index 64c893d..30edc8b 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -53,7 +53,6 @@
use ident::parsing::ident;
use lit::parsing::int;
use ty::parsing::ty;
- use nom::multispace;
named!(pub struct_body -> VariantData, alt!(
struct_like_body => { VariantData::Struct }
@@ -134,8 +133,7 @@
named!(pub visibility -> Visibility, alt!(
do_parse!(
- punct!("pub") >>
- multispace >>
+ keyword!("pub") >>
(Visibility::Public)
)
|
diff --git a/src/expr.rs b/src/expr.rs
index c2310ce..10e429f 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -340,7 +340,6 @@
use generics::parsing::lifetime;
use ident::parsing::ident;
use lit::parsing::lit;
- use nom::multispace;
use ty::parsing::ty;
named!(pub expr -> Expr, do_parse!(
@@ -414,8 +413,7 @@
));
named!(expr_box -> Expr, do_parse!(
- punct!("box") >>
- multispace >>
+ keyword!("box") >>
inner: expr >>
(Expr::Box(Box::new(inner)))
));
@@ -511,8 +509,7 @@
named!(expr_lit -> Expr, map!(lit, Expr::Lit));
named!(and_cast -> Ty, do_parse!(
- punct!("as") >>
- multispace >>
+ keyword!("as") >>
ty: ty >>
(ty)
));
@@ -520,14 +517,13 @@
named!(and_ascription -> Ty, preceded!(punct!(":"), ty));
named!(expr_if -> Expr, do_parse!(
- punct!("if") >>
- multispace >>
+ keyword!("if") >>
cond: expr >>
punct!("{") >>
then_block: within_block >>
punct!("}") >>
else_block: option!(preceded!(
- punct!("else"),
+ keyword!("else"),
alt!(
expr_if
|
@@ -554,7 +550,7 @@
named!(expr_loop -> Expr, do_parse!(
lt: option!(terminated!(lifetime, punct!(":"))) >>
- punct!("loop") >>
+ keyword!("loop") >>
loop_block: block >>
(Expr::Loop(
Box::new(loop_block),
@@ -588,7 +584,7 @@
));
named!(block_check_mode -> BlockCheckMode, alt!(
- punct!("unsafe") => { |_| BlockCheckMode::Unsafe }
+ keyword!("unsafe") => { |_| BlockCheckMode::Unsafe }
|
epsilon!() => { |_| BlockCheckMode::Default }
));
diff --git a/src/generics.rs b/src/generics.rs
index e7cc873..c0d5c94 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -88,7 +88,6 @@
use super::*;
use ident::parsing::ident;
use ty::parsing::{ty, poly_trait_ref};
- use nom::multispace;
named!(pub generics -> Generics, do_parse!(
bracketed: alt!(
@@ -133,7 +132,7 @@
));
named!(pub bound_lifetimes -> Vec<LifetimeDef>, opt_vec!(do_parse!(
- punct!("for") >>
+ keyword!("for") >>
punct!("<") >>
lifetimes: separated_list!(punct!(","), lifetime_def) >>
punct!(">") >>
@@ -171,8 +170,7 @@
named!(pub where_clause -> WhereClause, alt!(
do_parse!(
- punct!("where") >>
- multispace >>
+ keyword!("where") >>
predicates: separated_nonempty_list!(punct!(","), where_predicate) >>
option!(punct!(",")) >>
(WhereClause { predicates: predicates })
diff --git a/src/helper.rs b/src/helper.rs
index 2a429e9..de8b715 100644
--- a/src/helper.rs
+++ b/src/helper.rs
@@ -1,6 +1,7 @@
#![cfg(feature = "parsing")]
use nom::IResult;
+use unicode_xid::UnicodeXID;
macro_rules! punct {
($i:expr, $punct:expr) => {
@@ -12,8 +13,7 @@
for (i, ch) in input.char_indices() {
if !ch.is_whitespace() {
return if input[i..].starts_with(token) {
- let end = i + token.len();
- IResult::Done(&input[end..], &input[i..end])
+ IResult::Done(&input[i + token.len()..], token)
} else {
IResult::Error
};
@@ -22,6 +22,35 @@
IResult::Error
}
+macro_rules! keyword {
+ ($i:expr, $keyword:expr) => {
+ $crate::helper::keyword($i, $keyword)
+ };
+}
+
+pub fn keyword<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> {
+ match punct(input, token) {
+ IResult::Done(rest, _) => {
+ match word_break(rest) {
+ IResult::Done(_, _) => IResult::Done(rest, token),
+ IResult::Error => IResult::Error,
+ }
+ }
+ IResult::Error => IResult::Error,
+ }
+}
+
+pub fn word_break<'a>(input: &'a str) -> IResult<&'a str, ()> {
+ match input.chars().next() {
+ Some(ch) if UnicodeXID::is_xid_continue(ch) => {
+ IResult::Error
+ }
+ Some(_) | None => {
+ IResult::Done(input, ())
+ }
+ }
+}
+
macro_rules! option {
($i:expr, $submac:ident!( $($args:tt)* )) => {
match $submac!($i, $($args)*) {
diff --git a/src/item.rs b/src/item.rs
index b91af03..d8488c8 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -214,7 +214,6 @@
use ident::parsing::ident;
use macro_input::{Body, MacroInput};
use macro_input::parsing::macro_input;
- use nom::multispace;
named!(pub item -> Item, alt!(
item_extern_crate
@@ -237,13 +236,11 @@
named!(item_extern_crate -> Item, do_parse!(
attrs: many0!(attribute) >>
vis: visibility >>
- punct!("extern") >>
- multispace >>
- punct!("crate") >>
- multispace >>
+ keyword!("extern") >>
+ keyword!("crate") >>
id: ident >>
rename: option!(preceded!(
- tuple!(punct!("as"), multispace),
+ keyword!("as"),
ident
)) >>
punct!(";") >>
diff --git a/src/lib.rs b/src/lib.rs
index 0841f17..df62d75 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,6 +5,9 @@
extern crate quote;
#[cfg(feature = "parsing")]
+extern crate unicode_xid;
+
+#[cfg(feature = "parsing")]
#[macro_use]
mod nom;
diff --git a/src/macro_input.rs b/src/macro_input.rs
index 64a735e..848e609 100644
--- a/src/macro_input.rs
+++ b/src/macro_input.rs
@@ -27,8 +27,7 @@
named!(pub macro_input -> MacroInput, do_parse!(
attrs: many0!(attribute) >>
vis: visibility >>
- which: alt!(punct!("struct") | punct!("enum")) >>
- multispace >>
+ which: alt!(keyword!("struct") | keyword!("enum")) >>
id: ident >>
generics: generics >>
item: switch!(value!(which),
diff --git a/src/ty.rs b/src/ty.rs
index 0dc6eaf..35b640d 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -239,9 +239,9 @@
named!(ty_ptr -> Ty, do_parse!(
punct!("*") >>
mutability: alt!(
- punct!("const") => { |_| Mutability::Immutable }
+ keyword!("const") => { |_| Mutability::Immutable }
|
- punct!("mut") => { |_| Mutability::Mutable }
+ keyword!("mut") => { |_| Mutability::Mutable }
) >>
target: ty >>
(Ty::Ptr(Box::new(MutTy {
@@ -262,8 +262,7 @@
));
named!(ty_bare_fn -> Ty, do_parse!(
- punct!("fn") >>
- multispace >>
+ keyword!("fn") >>
lifetimes: opt_vec!(delimited!(
punct!("<"),
separated_list!(punct!(","), lifetime_def),
@@ -303,7 +302,7 @@
punct!("<") >>
this: map!(ty, Box::new) >>
path: option!(preceded!(
- tuple!(punct!("as"), multispace),
+ keyword!("as"),
path
)) >>
punct!(">") >>
@@ -327,8 +326,7 @@
));
named!(ty_impl_trait -> Ty, do_parse!(
- punct!("impl") >>
- multispace >>
+ keyword!("impl") >>
elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
(Ty::ImplTrait(elem))
));
@@ -342,8 +340,7 @@
named!(mutability -> Mutability, alt!(
do_parse!(
- punct!("mut") >>
- multispace >>
+ keyword!("mut") >>
(Mutability::Mutable)
)
|