diff --git a/parser/src/ast/argument_name.rs b/parser/src/ast/argument_name.rs index 4e1ed83..df29a2d 100644 --- a/parser/src/ast/argument_name.rs +++ b/parser/src/ast/argument_name.rs @@ -1,11 +1,16 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; #[derive(Debug, Clone)] pub struct ArgumentName<'a> { - pub span: Span<'a>, - pub name: String, + span: Span<'a>, + name: String, +} + +impl<'a> Parse<'a> for ArgumentName<'a> { + const RULE: Rule = Rule::argument_keyword; } impl<'a> From> for ArgumentName<'a> { @@ -31,13 +36,10 @@ impl<'a> ArgumentName<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn argument_name() { - let pair = parse_str("marty_mcfly:", Rule::argument_keyword); - let argument_name = ArgumentName::from(pair); - - assert_eq!(argument_name.name, "marty_mcfly"); + let argument_name = ArgumentName::parse("marty_mcfly:").unwrap(); + assert_eq!(argument_name.name(), "marty_mcfly"); } } diff --git a/parser/src/ast/array.rs b/parser/src/ast/array.rs index 0b96dc6..1b3e160 100644 --- a/parser/src/ast/array.rs +++ b/parser/src/ast/array.rs @@ -1,5 +1,6 @@ use ast::expression::Expression; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -9,6 +10,10 @@ pub struct Array<'a> { values: Vec>, } +impl<'a> Parse<'a> for Array<'a> { + const RULE: Rule = Rule::array; +} + impl<'a> From> for Array<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::array); @@ -32,12 +37,10 @@ impl<'a> Array<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn array_of_ints() { - let result = parse_str("[1, 2, 3]", Rule::array); - let array = Array::from(result); + let array = Array::parse("[1, 2, 3]").unwrap(); let mut value = 0; for expr in array.values() { value = value + 1; diff --git a/parser/src/ast/atom.rs b/parser/src/ast/atom.rs index 3b89b89..5858f3d 100644 --- a/parser/src/ast/atom.rs +++ b/parser/src/ast/atom.rs @@ -1,5 +1,6 @@ use ast::into_span::IntoSpan; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -9,6 +10,10 @@ pub struct Atom<'a> { pub name: String, } +impl<'a> Parse<'a> for Atom<'a> { + const RULE: Rule = Rule::atom; +} + impl<'a> From> for Atom<'a> { fn from(pair: Pair<'a, Rule>) -> Self { match pair.as_rule() { @@ -62,12 +67,10 @@ impl<'a> IntoSpan<'a> for Atom<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn atom() { - let pair = parse_str(":marty_mcfly", Rule::atom); - let atom = Atom::from(pair); + let atom = Atom::parse(":marty_mcfly").unwrap(); assert_eq!(atom.name(), "marty_mcfly"); } } diff --git a/parser/src/ast/block.rs b/parser/src/ast/block.rs index 21fd4b6..c8e3ba5 100644 --- a/parser/src/ast/block.rs +++ b/parser/src/ast/block.rs @@ -1,5 +1,6 @@ use ast::{define_function::DefineFunction, expression::Expression}; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -15,6 +16,10 @@ pub enum Inner<'a> { Expression(Expression<'a>), } +impl<'a> Parse<'a> for Block<'a> { + const RULE: Rule = Rule::block; +} + impl<'a> From> for Block<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::block); @@ -26,8 +31,7 @@ impl<'a> From> for Block<'a> { Rule::def_function => Inner::DefineFunction(DefineFunction::from(p)), Rule::expression => Inner::Expression(Expression::from(p)), _ => unreachable!(), - }) - .collect(); + }).collect(); Block { span: span, @@ -61,19 +65,16 @@ impl<'a> Block<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn block_empty() { - let pair = parse_str("-> end", Rule::block_test); - let block = Block::from(pair); + let block = Block::parse("-> end").unwrap(); assert!(block.body().is_empty()); } #[test] fn block_single() { - let pair = parse_str("-> 123 end", Rule::block_test); - let block = Block::from(pair); + let block = Block::parse("-> 123 end").unwrap(); assert_eq!(block.body().len(), 1); assert_eq!( block.body()[0] @@ -90,15 +91,13 @@ mod test { #[test] fn block_multi() { - let pair = parse_str( + let block = Block::parse( "-> :marty :doc :einstein end", - Rule::block_test, - ); - let block = Block::from(pair); + ).unwrap(); assert_eq!(block.body().len(), 3); assert_eq!( block.body()[0] @@ -137,8 +136,7 @@ mod test { #[test] fn block_with_function_define() { - let pair = parse_str("-> def marty? end", Rule::block); - let block = Block::from(pair); + let block = Block::parse("-> def marty? end").unwrap(); assert_eq!(block.body()[0].define_function().unwrap().name(), "marty?"); } } diff --git a/parser/src/ast/boolean.rs b/parser/src/ast/boolean.rs index 01fcf83..f571ef7 100644 --- a/parser/src/ast/boolean.rs +++ b/parser/src/ast/boolean.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct Boolean<'a> { value: bool, } +impl<'a> Parse<'a> for Boolean<'a> { + const RULE: Rule = Rule::boolean; +} + impl<'a> From> for Boolean<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::boolean); @@ -44,19 +49,16 @@ impl<'a> Boolean<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn boolean_true() { - let pair = parse_str("true", Rule::boolean); - let b = Boolean::from(pair); + let b = Boolean::parse("true").unwrap(); assert!(b.value()); } #[test] fn boolean_false() { - let pair = parse_str("false", Rule::boolean); - let b = Boolean::from(pair); + let b = Boolean::parse("false").unwrap(); assert!(!b.value()); } diff --git a/parser/src/ast/call/call.rs b/parser/src/ast/call/call.rs index 58e2a5e..ebb3fdc 100644 --- a/parser/src/ast/call/call.rs +++ b/parser/src/ast/call/call.rs @@ -1,6 +1,7 @@ use ast::call::{message::Message, receiver::Receiver}; use ast::expression::Expression; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -12,6 +13,10 @@ pub struct Call<'a> { arguments: Vec>, } +impl<'a> Parse<'a> for Call<'a> { + const RULE: Rule = Rule::call; +} + impl<'a> From> for Call<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::call); @@ -53,13 +58,10 @@ impl<'a> Call<'a> { #[cfg(test)] mod test { use super::*; - use grammar::{parse_str, Rule}; #[test] fn call_no_arg() { - let result = parse_str("delorean.accelerate()", Rule::call); - let call = Call::from(result); - + let call = Call::parse("delorean.accelerate()").unwrap(); assert_eq!(call.receiver().name(), "delorean"); assert_eq!(call.message().name(), "accelerate"); assert_eq!(call.arguments().len(), 0); @@ -67,10 +69,8 @@ mod test { #[test] fn call_with_arg() { - let result = parse_str("delorean.accelerate(88)", Rule::call); - let call = Call::from(result); + let call = Call::parse("delorean.accelerate(88)").unwrap(); let ref arg = call.arguments[0]; - assert_eq!(call.receiver().name(), "delorean"); assert_eq!(call.message().name(), "accelerate"); assert_eq!(arg.literal().unwrap().integer().unwrap().value(), 88); diff --git a/parser/src/ast/call/message.rs b/parser/src/ast/call/message.rs index 5328093..805055d 100644 --- a/parser/src/ast/call/message.rs +++ b/parser/src/ast/call/message.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct Message<'a> { name: String, } +impl<'a> Parse<'a> for Message<'a> { + const RULE: Rule = Rule::call_message; +} + impl<'a> From> for Message<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::call_message); @@ -31,12 +36,10 @@ impl<'a> Message<'a> { #[cfg(test)] mod test { use super::*; - use grammar::{parse_str, Rule}; #[test] fn message() { - let result = parse_str("marty_mcfly", Rule::call_message); - let node = Message::from(result); + let node = Message::parse("marty_mcfly").unwrap(); assert_eq!(node.name(), "marty_mcfly"); } } diff --git a/parser/src/ast/call/receiver.rs b/parser/src/ast/call/receiver.rs index be8f6ee..0d45373 100644 --- a/parser/src/ast/call/receiver.rs +++ b/parser/src/ast/call/receiver.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct Receiver<'a> { name: String, } +impl<'a> Parse<'a> for Receiver<'a> { + const RULE: Rule = Rule::call_receiver; +} + impl<'a> From> for Receiver<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::call_receiver); @@ -31,12 +36,10 @@ impl<'a> Receiver<'a> { #[cfg(test)] mod test { use super::*; - use grammar::{parse_str, Rule}; #[test] fn receiver() { - let result = parse_str("marty_mcfly", Rule::call_receiver); - let node = Receiver::from(result); + let node = Receiver::parse("marty_mcfly").unwrap(); assert_eq!(node.name(), "marty_mcfly"); } } diff --git a/parser/src/ast/constructor.rs b/parser/src/ast/constructor.rs index 3158e7f..15e7666 100644 --- a/parser/src/ast/constructor.rs +++ b/parser/src/ast/constructor.rs @@ -1,5 +1,6 @@ use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName}; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -10,6 +11,10 @@ pub struct Constructor<'a> { fields: Vec<(ArgumentName<'a>, Expression<'a>)>, } +impl<'a> Parse<'a> for Constructor<'a> { + const RULE: Rule = Rule::constructor; +} + impl<'a> From> for Constructor<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::constructor); @@ -48,12 +53,10 @@ impl<'a> Constructor<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn constructor() { - let pair = parse_str("Delorean { speed: 88 }", Rule::constructor); - let constructor = Constructor::from(pair); + let constructor = Constructor::parse("Delorean { speed: 88 }").unwrap(); assert_eq!(constructor.type_name().name(), "Delorean"); let (ref arg_name, ref arg_value) = constructor.fields()[0]; assert_eq!(arg_name.name(), "speed"); diff --git a/parser/src/ast/define_function.rs b/parser/src/ast/define_function.rs index bb162fb..96533a1 100644 --- a/parser/src/ast/define_function.rs +++ b/parser/src/ast/define_function.rs @@ -1,5 +1,6 @@ use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName}; use grammar::Rule; +use parse::Parse; use pest::iterators::{Pair, Pairs}; use pest::Span; @@ -26,6 +27,10 @@ pub struct FunctionName<'a> { predicate: bool, } +impl<'a> Parse<'a> for DefineFunction<'a> { + const RULE: Rule = Rule::def_function; +} + impl<'a> DefineFunction<'a> { pub fn name(&self) -> &str { &self.fn_name.name @@ -125,8 +130,7 @@ fn get_arguments<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expressio let arg_name = pairs.next().unwrap(); let value = pairs.next().unwrap(); (ArgumentName::from(arg_name), Expression::from(value)) - }) - .collect() + }).collect() } impl<'a> From> for FunctionType { @@ -143,12 +147,10 @@ impl<'a> From> for FunctionType { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn name_only() { - let pair = parse_str("def marty", Rule::def_function); - let fun = DefineFunction::from(pair); + let fun = DefineFunction::parse("def marty").unwrap(); assert!(fun.is_public()); assert!(!fun.is_predicate()); assert_eq!(fun.name(), "marty"); @@ -156,8 +158,7 @@ mod test { #[test] fn name_with_predicate() { - let pair = parse_str("def marty?", Rule::def_function); - let fun = DefineFunction::from(pair); + let fun = DefineFunction::parse("def marty?").unwrap(); assert!(fun.is_public()); assert!(fun.is_predicate()); assert_eq!(fun.name(), "marty?"); @@ -165,8 +166,7 @@ mod test { #[test] fn with_return_type() { - let pair = parse_str("def marty", Rule::def_function); - let fun = DefineFunction::from(pair); + let fun = DefineFunction::parse("def marty").unwrap(); assert!(fun.is_public()); assert!(!fun.is_predicate()); assert_eq!(fun.name(), "marty"); @@ -175,8 +175,7 @@ mod test { #[test] fn with_arguments() { - let pair = parse_str("def marty family: McFly, car: Delorean", Rule::def_function); - let fun = DefineFunction::from(pair); + let fun = DefineFunction::parse("def marty family: McFly, car: Delorean").unwrap(); assert!(fun.is_public()); assert!(!fun.is_predicate()); assert_eq!(fun.name(), "marty"); diff --git a/parser/src/ast/define_module.rs b/parser/src/ast/define_module.rs index 25e35b8..a21cba5 100644 --- a/parser/src/ast/define_module.rs +++ b/parser/src/ast/define_module.rs @@ -1,5 +1,6 @@ use ast::{argument_name::ArgumentName, expression::Expression, type_name::TypeName}; use grammar::Rule; +use parse::Parse; use pest::iterators::{Pair, Pairs}; use pest::Span; @@ -60,6 +61,10 @@ impl<'a> From> for ModuleType { } } +impl<'a> Parse<'a> for DefineModule<'a> { + const RULE: Rule = Rule::def_module; +} + impl<'a> From> for DefineModule<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::def_module); @@ -87,43 +92,37 @@ fn get_arguments<'a>(pairs: Pairs<'a, Rule>) -> Vec<(ArgumentName<'a>, Expressio let arg_name = pairs.next().unwrap(); let value = pairs.next().unwrap(); (ArgumentName::from(arg_name), Expression::from(value)) - }) - .collect() + }).collect() } #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn type_name_only() { - let pair = parse_str("deftype Marty", Rule::def_module); - let module = DefineModule::from(pair); + let module = DefineModule::parse("deftype Marty").unwrap(); assert!(module.is_type()); assert_eq!(module.type_name().name(), "Marty"); } #[test] fn trait_name_only() { - let pair = parse_str("deftrait Marty", Rule::def_module); - let module = DefineModule::from(pair); + let module = DefineModule::parse("deftrait Marty").unwrap(); assert!(module.is_trait()); assert_eq!(module.type_name().name(), "Marty"); } #[test] fn impl_name_only() { - let pair = parse_str("defimpl Marty", Rule::def_module); - let module = DefineModule::from(pair); + let module = DefineModule::parse("defimpl Marty").unwrap(); assert!(module.is_implementation()); assert_eq!(module.type_name().name(), "Marty"); } #[test] fn type_with_fields() { - let pair = parse_str("deftype Delorean speed: Integer", Rule::def_module); - let module = DefineModule::from(pair); + let module = DefineModule::parse("deftype Delorean speed: Integer").unwrap(); assert!(module.is_type()); assert_eq!(module.type_name().name(), "Delorean"); let (ref arg_name, ref arg_value) = module.fields()[0]; diff --git a/parser/src/ast/expression.rs b/parser/src/ast/expression.rs index 86beab8..4344b51 100644 --- a/parser/src/ast/expression.rs +++ b/parser/src/ast/expression.rs @@ -3,6 +3,7 @@ use ast::{ unary::Unary, }; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -21,6 +22,10 @@ pub enum Inner<'a> { Unary(Unary<'a>), } +impl<'a> Parse<'a> for Expression<'a> { + const RULE: Rule = Rule::expression; +} + impl<'a> From> for Expression<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::expression); @@ -159,20 +164,17 @@ impl<'a> Expression<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn block() { - let pair = parse_str("-> 123 end", Rule::expression); - let expr = Expression::from(pair); + let expr = Expression::parse("-> 123 end").unwrap(); assert!(expr.is_block()); assert_eq!(expr.block().unwrap().body().len(), 1); } #[test] fn call() { - let pair = parse_str("marty.mcfly()", Rule::expression); - let expr = Expression::from(pair); + let expr = Expression::parse("marty.mcfly()").unwrap(); assert!(expr.is_call()); assert_eq!(expr.call().unwrap().receiver().name(), "marty"); assert_eq!(expr.call().unwrap().message().name(), "mcfly"); @@ -180,8 +182,7 @@ mod test { #[test] fn infix() { - let pair = parse_str("123 * 234", Rule::expression); - let expr = Expression::from(pair); + let expr = Expression::parse("123 * 234").unwrap(); assert!(expr.is_infix()); assert_eq!( expr.infix() @@ -209,16 +210,14 @@ mod test { #[test] fn literal() { - let pair = parse_str("123", Rule::expression); - let expr = Expression::from(pair); + let expr = Expression::parse("123").unwrap(); assert!(expr.is_literal()); assert_eq!(expr.literal().unwrap().integer().unwrap().value(), 123); } #[test] fn unary() { - let pair = parse_str("!123", Rule::expression); - let expr = Expression::from(pair); + let expr = Expression::parse("!123").unwrap(); assert!(expr.is_unary()); assert!(expr.unary().unwrap().op().is_logical_not()); assert_eq!( diff --git a/parser/src/ast/file.rs b/parser/src/ast/file.rs index 6d49ff6..a594771 100644 --- a/parser/src/ast/file.rs +++ b/parser/src/ast/file.rs @@ -1,5 +1,6 @@ use ast::define_module::DefineModule; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -9,6 +10,10 @@ pub struct File<'a> { modules: Vec>, } +impl<'a> Parse<'a> for File<'a> { + const RULE: Rule = Rule::file; +} + impl<'a> From> for File<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::file); @@ -32,12 +37,10 @@ impl<'a> File<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn file() { - let pair = parse_str("deftype Marty", Rule::file); - let file = File::from(pair); + let file = File::parse("deftype Marty").unwrap(); assert_eq!(file.modules().len(), 1); } } diff --git a/parser/src/ast/float.rs b/parser/src/ast/float.rs index 5205866..d16e2ac 100644 --- a/parser/src/ast/float.rs +++ b/parser/src/ast/float.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; use std::str::FromStr; @@ -9,6 +10,10 @@ pub struct Float<'a> { value: f64, } +impl<'a> Parse<'a> for Float<'a> { + const RULE: Rule = Rule::float; +} + impl<'a> From> for Float<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::float); @@ -33,19 +38,16 @@ impl<'a> Float<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn float_zero_zero() { - let pair = parse_str("0.0", Rule::float); - let flt = Float::from(pair); + let flt = Float::parse("0.0").unwrap(); assert_eq!(flt.value, 0.0); } #[test] fn float_123_123() { - let pair = parse_str("123.123", Rule::float); - let flt = Float::from(pair); + let flt = Float::parse("123.123").unwrap(); assert_eq!(flt.value, 123.123); } diff --git a/parser/src/ast/integer.rs b/parser/src/ast/integer.rs index 1645c8c..009526f 100644 --- a/parser/src/ast/integer.rs +++ b/parser/src/ast/integer.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -9,6 +10,10 @@ pub struct Integer<'a> { pub value: u64, } +impl<'a> Parse<'a> for Integer<'a> { + const RULE: Rule = Rule::integer; +} + impl<'a> From> for Integer<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::integer); @@ -50,44 +55,38 @@ impl<'a> Integer<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn integer_zero() { - let pair = parse_str("0", Rule::integer); - let int = Integer::from(pair); + let int = Integer::parse("0").unwrap(); assert_eq!(int.radix, 0); assert_eq!(int.value, 0); } #[test] fn integer_binary() { - let pair = parse_str("0b10101", Rule::integer); - let int = Integer::from(pair); + let int = Integer::parse("0b10101").unwrap(); assert_eq!(int.radix, 2); assert_eq!(int.value, 21); } #[test] fn integer_octal() { - let pair = parse_str("0o76543210", Rule::integer); - let int = Integer::from(pair); + let int = Integer::parse("0o76543210").unwrap(); assert_eq!(int.radix, 8); assert_eq!(int.value, 16434824); } #[test] fn integer_decimal() { - let pair = parse_str("9876543210", Rule::integer); - let int = Integer::from(pair); + let int = Integer::parse("9876543210").unwrap(); assert_eq!(int.radix, 10); assert_eq!(int.value, 9876543210); } #[test] fn integer_hexadecimal() { - let pair = parse_str("0xfEdCbA9876543210", Rule::integer); - let int = Integer::from(pair); + let int = Integer::parse("0xfEdCbA9876543210").unwrap(); assert_eq!(int.radix, 16); assert_eq!(int.value, 18364758544493064720); } diff --git a/parser/src/ast/literal.rs b/parser/src/ast/literal.rs index 17e3d1d..43080af 100644 --- a/parser/src/ast/literal.rs +++ b/parser/src/ast/literal.rs @@ -4,6 +4,7 @@ use ast::{ type_name::TypeName, variable::Variable, }; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -28,6 +29,10 @@ pub enum Inner<'a> { Variable(Variable<'a>), } +impl<'a> Parse<'a> for Literal<'a> { + const RULE: Rule = Rule::literal; +} + impl<'a> From> for Literal<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::literal); @@ -231,92 +236,80 @@ impl<'a> Literal<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn array() { - let pair = parse_str("[1, 2, 3]", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("[1, 2, 3]").unwrap(); assert!(lit.is_array()); assert_eq!(lit.array().unwrap().values().len(), 3); } #[test] fn map() { - let pair = parse_str("{a: 1, b: 2}", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("{a: 1, b: 2}").unwrap(); assert!(lit.is_map()); assert_eq!(lit.map().unwrap().values().len(), 2); } #[test] fn atom() { - let pair = parse_str(":marty_mcfly", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse(":marty_mcfly").unwrap(); assert!(lit.is_atom()); assert_eq!(lit.atom().unwrap().name(), "marty_mcfly"); } #[test] fn boolean() { - let pair = parse_str("true", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("true").unwrap(); assert!(lit.is_boolean()); assert!(lit.boolean().unwrap().is_true()); } #[test] fn constructor() { - let pair = parse_str("Delorean { speed: 88 }", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("Delorean { speed: 88 }").unwrap(); assert!(lit.is_constructor()); assert_eq!(lit.constructor().unwrap().type_name().name(), "Delorean"); } #[test] fn float() { - let pair = parse_str("123.456", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("123.456").unwrap(); assert!(lit.is_float()); assert_eq!(lit.float().unwrap().value(), 123.456); } #[test] fn integer() { - let pair = parse_str("123", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("123").unwrap(); assert!(lit.is_integer()); assert_eq!(lit.integer().unwrap().value(), 123); } #[test] fn property() { - let pair = parse_str("@doc_brown", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("@doc_brown").unwrap(); assert!(lit.is_property()); assert_eq!(lit.property().unwrap().name(), "doc_brown"); } #[test] fn string() { - let pair = parse_str("\"Doc \\\"Emmet\\\" Brown\"", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("\"Doc \\\"Emmet\\\" Brown\"").unwrap(); assert!(lit.is_string()); assert_eq!(lit.string().unwrap().value(), "Doc \"Emmet\" Brown"); } #[test] fn type_name() { - let pair = parse_str("MartyMcFly", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("MartyMcFly").unwrap(); assert!(lit.is_type_name()); assert_eq!(lit.type_name().unwrap().name(), "MartyMcFly"); } #[test] fn variable() { - let pair = parse_str("marty_mcfly", Rule::literal); - let lit = Literal::from(pair); + let lit = Literal::parse("marty_mcfly").unwrap(); assert!(lit.is_variable()); assert_eq!(lit.variable().unwrap().name(), "marty_mcfly"); } diff --git a/parser/src/ast/map.rs b/parser/src/ast/map.rs index 918c6e3..c550df3 100644 --- a/parser/src/ast/map.rs +++ b/parser/src/ast/map.rs @@ -1,5 +1,6 @@ use ast::{atom::Atom, expression::Expression, literal::Literal}; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -16,6 +17,10 @@ pub struct MapPair<'a> { value: Box>, } +impl<'a> Parse<'a> for Map<'a> { + const RULE: Rule = Rule::map; +} + impl<'a> From> for Map<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::map); @@ -71,12 +76,10 @@ impl<'a> Map<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn keyword_map() { - let pair = parse_str("{a: 1, b: 2}", Rule::map); - let map = Map::from(pair); + let map = Map::parse("{a: 1, b: 2}").unwrap(); let map_pair = &map.values()[0]; assert_eq!( @@ -113,8 +116,7 @@ mod test { #[test] fn expression_map() { - let pair = parse_str("{ 1 : 2, 3 : 4 }", Rule::map); - let map = Map::from(pair); + let map = Map::parse("{ 1 : 2, 3 : 4 }").unwrap(); let map_pair = &map.values()[0]; assert_eq!( diff --git a/parser/src/ast/operator.rs b/parser/src/ast/operator.rs index f8215d9..c7df5f2 100644 --- a/parser/src/ast/operator.rs +++ b/parser/src/ast/operator.rs @@ -1,11 +1,16 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; #[derive(Debug, Clone)] pub struct Operator<'a> { - pub span: Span<'a>, - pub op: Op, + span: Span<'a>, + op: Op, +} + +impl<'a> Parse<'a> for Operator<'a> { + const RULE: Rule = Rule::all_operators; } impl<'a> From> for Operator<'a> { @@ -194,27 +199,27 @@ impl<'a> Operator<'a> { impl<'a> From> for Op { fn from(pair: Pair<'a, Rule>) -> Self { match pair.as_rule() { - Rule::multiply => Op::Multiply, - Rule::divide => Op::Divide, - Rule::modulus => Op::Modulo, - Rule::plus => Op::Plus, - Rule::minus => Op::Minus, - Rule::shift_left => Op::ShiftLeft, - Rule::shift_right => Op::ShiftRight, - Rule::less_than => Op::LessThan, - Rule::less_than_or_equal => Op::LessThanOrEqual, - Rule::greater_than => Op::GreaterThan, - Rule::greater_than_or_equal => Op::GreaterThanOrEqual, - Rule::not_equal => Op::NotEqual, - Rule::equal => Op::Equal, - Rule::exponent => Op::Exponent, - Rule::logical_and => Op::LogicalAnd, - Rule::logical_or => Op::LogicalOr, - Rule::logical_not => Op::LogicalNot, + Rule::assign => Op::Assign, Rule::bitwise_and => Op::BitwiseAnd, Rule::bitwise_or => Op::BitwiseOr, Rule::bitwise_xor => Op::BitwiseXor, - Rule::assign => Op::Assign, + Rule::divide => Op::Divide, + Rule::equal => Op::Equal, + Rule::exponent => Op::Exponent, + Rule::greater_than => Op::GreaterThan, + Rule::greater_than_or_equal => Op::GreaterThanOrEqual, + Rule::less_than => Op::LessThan, + Rule::less_than_or_equal => Op::LessThanOrEqual, + Rule::logical_and => Op::LogicalAnd, + Rule::logical_not => Op::LogicalNot, + Rule::logical_or => Op::LogicalOr, + Rule::minus => Op::Minus, + Rule::modulus => Op::Modulo, + Rule::multiply => Op::Multiply, + Rule::not_equal => Op::NotEqual, + Rule::plus => Op::Plus, + Rule::shift_left => Op::ShiftLeft, + Rule::shift_right => Op::ShiftRight, _ => panic!("Node {:?} is not an operator", pair), } } @@ -223,256 +228,131 @@ impl<'a> From> for Op { #[cfg(test)] mod test { use super::*; - use grammar::{parse_str, Rule}; - - mod operator { - use super::*; - - #[test] - fn multiply() { - let result = parse_str("*", Rule::all_operators); - assert_eq!(Op::Multiply, Operator::from(result).op) - } - - #[test] - fn divide() { - let result = parse_str("/", Rule::all_operators); - assert_eq!(Op::Divide, Operator::from(result).op); - } - - #[test] - fn modulus() { - let result = parse_str("%", Rule::all_operators); - assert_eq!(Op::Modulo, Operator::from(result).op); - } - - #[test] - fn plus() { - let result = parse_str("+", Rule::all_operators); - assert_eq!(Op::Plus, Operator::from(result).op); - } - - #[test] - fn minus() { - let result = parse_str("-", Rule::all_operators); - assert_eq!(Op::Minus, Operator::from(result).op); - } - - #[test] - fn shift_left() { - let result = parse_str("<<", Rule::all_operators); - assert_eq!(Op::ShiftLeft, Operator::from(result).op); - } - - #[test] - fn shift_right() { - let result = parse_str(">>", Rule::all_operators); - assert_eq!(Op::ShiftRight, Operator::from(result).op); - } - - #[test] - fn less_than() { - let result = parse_str("<", Rule::all_operators); - assert_eq!(Op::LessThan, Operator::from(result).op); - } - - #[test] - fn less_than_or_equal() { - let result = parse_str("<=", Rule::all_operators); - assert_eq!(Op::LessThanOrEqual, Operator::from(result).op); - } - - #[test] - fn greater_than() { - let result = parse_str(">", Rule::all_operators); - assert_eq!(Op::GreaterThan, Operator::from(result).op); - } - - #[test] - fn greater_than_or_equal() { - let result = parse_str(">=", Rule::all_operators); - assert_eq!(Op::GreaterThanOrEqual, Operator::from(result).op); - } - - #[test] - fn not_equal() { - let result = parse_str("!=", Rule::all_operators); - assert_eq!(Op::NotEqual, Operator::from(result).op); - } - - #[test] - fn equal() { - let result = parse_str("==", Rule::all_operators); - assert_eq!(Op::Equal, Operator::from(result).op); - } - - #[test] - fn logical_and() { - let result = parse_str("&&", Rule::all_operators); - assert_eq!(Op::LogicalAnd, Operator::from(result).op); - } - - #[test] - fn logical_or() { - let result = parse_str("||", Rule::all_operators); - assert_eq!(Op::LogicalOr, Operator::from(result).op); - } - - #[test] - fn logical_not() { - let result = parse_str("!", Rule::all_operators); - assert_eq!(Op::LogicalNot, Operator::from(result).op); - } - - #[test] - fn bitwise_and() { - let result = parse_str("&", Rule::all_operators); - assert_eq!(Op::BitwiseAnd, Operator::from(result).op); - } - - #[test] - fn bitwise_or() { - let result = parse_str("|", Rule::all_operators); - assert_eq!(Op::BitwiseOr, Operator::from(result).op); - } - - #[test] - fn bitwise_xor() { - let result = parse_str("^", Rule::all_operators); - assert_eq!(Op::BitwiseXor, Operator::from(result).op); - } - - #[test] - fn assign() { - let result = parse_str("=", Rule::all_operators); - assert_eq!(Op::Assign, Operator::from(result).op); - } + #[test] + fn assign() { + let op = Operator::parse("=").unwrap(); + assert!(op.is_assign()); } - mod op { - use super::*; + #[test] + fn bitwise_and() { + let op = Operator::parse("&").unwrap(); + assert!(op.is_bitwise_and()); + } - #[test] - fn multiply() { - let result = parse_str("*", Rule::all_operators); - assert_eq!(Op::Multiply, Op::from(result)); - } + #[test] + fn bitwise_or() { + let op = Operator::parse("|").unwrap(); + assert!(op.is_bitwise_or()); + } - #[test] - fn divide() { - let result = parse_str("/", Rule::all_operators); - assert_eq!(Op::Divide, Op::from(result)); - } + #[test] + fn bitwise_xor() { + let op = Operator::parse("^").unwrap(); + assert!(op.is_bitwise_xor()); + } - #[test] - fn modulus() { - let result = parse_str("%", Rule::all_operators); - assert_eq!(Op::Modulo, Op::from(result)); - } + #[test] + fn divide() { + let op = Operator::parse("/").unwrap(); + assert!(op.is_divide()); + } - #[test] - fn plus() { - let result = parse_str("+", Rule::all_operators); - assert_eq!(Op::Plus, Op::from(result)); - } + #[test] + fn equal() { + let op = Operator::parse("==").unwrap(); + assert!(op.is_equal()); + } - #[test] - fn minus() { - let result = parse_str("-", Rule::all_operators); - assert_eq!(Op::Minus, Op::from(result)); - } + #[test] + fn exponent() { + let op = Operator::parse("**").unwrap(); + assert!(op.is_exponent()); + } - #[test] - fn shift_left() { - let result = parse_str("<<", Rule::all_operators); - assert_eq!(Op::ShiftLeft, Op::from(result)); - } + #[test] + fn greater_than() { + let op = Operator::parse(">").unwrap(); + assert!(op.is_greater_than()); + } - #[test] - fn shift_right() { - let result = parse_str(">>", Rule::all_operators); - assert_eq!(Op::ShiftRight, Op::from(result)); - } + #[test] + fn greater_than_or_equal() { + let op = Operator::parse(">=").unwrap(); + assert!(op.is_greater_than_or_equal()); + } - #[test] - fn less_than() { - let result = parse_str("<", Rule::all_operators); - assert_eq!(Op::LessThan, Op::from(result)); - } + #[test] + fn less_than() { + let op = Operator::parse("<").unwrap(); + assert!(op.is_less_than()); + } - #[test] - fn less_than_or_equal() { - let result = parse_str("<=", Rule::all_operators); - assert_eq!(Op::LessThanOrEqual, Op::from(result)); - } + #[test] + fn less_than_or_equal() { + let op = Operator::parse("<=").unwrap(); + assert!(op.is_less_than_or_equal()); + } - #[test] - fn greater_than() { - let result = parse_str(">", Rule::all_operators); - assert_eq!(Op::GreaterThan, Op::from(result)); - } + #[test] + fn logical_and() { + let op = Operator::parse("&&").unwrap(); + assert!(op.is_logical_and()); + } - #[test] - fn greater_than_or_equal() { - let result = parse_str(">=", Rule::all_operators); - assert_eq!(Op::GreaterThanOrEqual, Op::from(result)); - } + #[test] + fn logical_not() { + let op = Operator::parse("!").unwrap(); + assert!(op.is_logical_not()); + } - #[test] - fn not_equal() { - let result = parse_str("!=", Rule::all_operators); - assert_eq!(Op::NotEqual, Op::from(result)); - } + #[test] + fn logical_or() { + let op = Operator::parse("||").unwrap(); + assert!(op.is_logical_or()); + } - #[test] - fn equal() { - let result = parse_str("==", Rule::all_operators); - assert_eq!(Op::Equal, Op::from(result)); - } + #[test] + fn minus() { + let op = Operator::parse("-").unwrap(); + assert!(op.is_minus()); + } - #[test] - fn logical_and() { - let result = parse_str("&&", Rule::all_operators); - assert_eq!(Op::LogicalAnd, Op::from(result)); - } + #[test] + fn modulus() { + let op = Operator::parse("%").unwrap(); + assert!(op.is_modulo()); + } - #[test] - fn logical_or() { - let result = parse_str("||", Rule::all_operators); - assert_eq!(Op::LogicalOr, Op::from(result)); - } + #[test] + fn multiply() { + let op = Operator::parse("*").unwrap(); + assert!(op.is_multiply()); + } - #[test] - fn logical_not() { - let result = parse_str("!", Rule::all_operators); - assert_eq!(Op::LogicalNot, Op::from(result)); - } + #[test] + fn not_equal() { + let op = Operator::parse("!=").unwrap(); + assert!(op.is_not_equal()); + } - #[test] - fn bitwise_and() { - let result = parse_str("&", Rule::all_operators); - assert_eq!(Op::BitwiseAnd, Op::from(result)); - } + #[test] + fn plus() { + let op = Operator::parse("+").unwrap(); + assert!(op.is_plus()); + } - #[test] - fn bitwise_or() { - let result = parse_str("|", Rule::all_operators); - assert_eq!(Op::BitwiseOr, Op::from(result)); - } - - #[test] - fn bitwise_xor() { - let result = parse_str("^", Rule::all_operators); - assert_eq!(Op::BitwiseXor, Op::from(result)); - } - - #[test] - fn assign() { - let result = parse_str("=", Rule::all_operators); - assert_eq!(Op::Assign, Op::from(result)); - } + #[test] + fn shift_left() { + let op = Operator::parse("<<").unwrap(); + assert!(op.is_shift_left()); + } + #[test] + fn shift_right() { + let op = Operator::parse(">>").unwrap(); + assert!(op.is_shift_right()); } } diff --git a/parser/src/ast/precedence.rs b/parser/src/ast/precedence.rs index 80f56c7..7ea5337 100644 --- a/parser/src/ast/precedence.rs +++ b/parser/src/ast/precedence.rs @@ -43,12 +43,11 @@ pub fn climb<'a>(pair: Pair<'a, Rule>) -> Expression<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; + use parse::Parse; #[test] fn precedence_test() { - let result = parse_str("10 * 20 + 30", Rule::expression_test); - let expr = Expression::from(result); + let expr = Expression::parse("10 * 20 + 30").unwrap(); let infix0 = expr.infix().unwrap(); assert!(infix0.op().is_plus()); assert_eq!( diff --git a/parser/src/ast/property.rs b/parser/src/ast/property.rs index 7f942af..3f99029 100644 --- a/parser/src/ast/property.rs +++ b/parser/src/ast/property.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct Property<'a> { name: String, } +impl<'a> Parse<'a> for Property<'a> { + const RULE: Rule = Rule::property; +} + impl<'a> From> for Property<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::property); @@ -37,13 +42,10 @@ impl<'a> Property<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn property() { - let pair = parse_str("@marty_mcfly", Rule::property); - let property = Property::from(pair); - + let property = Property::parse("@marty_mcfly").unwrap(); assert_eq!(property.name(), "marty_mcfly"); } } diff --git a/parser/src/ast/string.rs b/parser/src/ast/string.rs index c014358..3b53338 100644 --- a/parser/src/ast/string.rs +++ b/parser/src/ast/string.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; use regex::{Captures, Regex}; @@ -14,6 +15,10 @@ pub struct StringLiteral<'a> { value: String, } +impl<'a> Parse<'a> for StringLiteral<'a> { + const RULE: Rule = Rule::string; +} + impl<'a> From> for StringLiteral<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::string); @@ -60,91 +65,70 @@ impl<'a> StringLiteral<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn basic() { - let pair = parse_str(r#""hello world""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""hello world""#).unwrap(); assert_eq!(value.value(), "hello world"); } #[test] fn vartical_tab_escape() { - let pair = parse_str(r#""\v""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\v""#).unwrap(); assert_eq!(value.value(), "\u{000b}"); } #[test] fn tab_escape() { - let pair = parse_str(r#""\t""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\t""#).unwrap(); assert_eq!(value.value(), "\t"); } #[test] fn carriage_return_escape() { - let pair = parse_str(r#""\r""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\r""#).unwrap(); assert_eq!(value.value(), "\r"); } #[test] fn newline_escape() { - let pair = parse_str(r#""\n""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\n""#).unwrap(); assert_eq!(value.value(), "\n"); } #[test] fn formfeed_escape() { - let pair = parse_str(r#""\f""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\f""#).unwrap(); assert_eq!(value.value(), "\u{000c}"); } #[test] fn backspace_escape() { - let pair = parse_str(r#""\b""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\b""#).unwrap(); assert_eq!(value.value(), "\u{0008}"); } #[test] fn alert_escape() { - let pair = parse_str(r#""\a""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\a""#).unwrap(); assert_eq!(value.value(), "\u{0007}"); } #[test] fn unicode_escape() { - let pair = parse_str(r#""\u26f5""#, Rule::string); - let value = StringLiteral::from(pair); - + let value = StringLiteral::parse(r#""\u26f5""#).unwrap(); assert_eq!(value.value(), "\u{26f5}"); } #[test] fn backslash_escape() { - let pair = parse_str(r#""\\""#, Rule::string); - let value = StringLiteral::from(pair); + let value = StringLiteral::parse(r#""\\""#).unwrap(); assert_eq!(value.value(), "\\"); } #[test] fn doublequote_escape() { - let pair = parse_str(r#""\""""#, Rule::string); - let value = StringLiteral::from(pair); + let value = StringLiteral::parse(r#""\""""#).unwrap(); assert_eq!(value.value(), r#"""#); } } diff --git a/parser/src/ast/type_name.rs b/parser/src/ast/type_name.rs index d09683c..27d5cf8 100644 --- a/parser/src/ast/type_name.rs +++ b/parser/src/ast/type_name.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct TypeName<'a> { pub name: String, } +impl<'a> Parse<'a> for TypeName<'a> { + const RULE: Rule = Rule::type_name; +} + impl<'a> From> for TypeName<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::type_name); @@ -30,12 +35,10 @@ impl<'a> TypeName<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn name() { - let pair = parse_str("DocBrown", Rule::type_name); - let type_name = TypeName::from(pair); + let type_name = TypeName::parse("DocBrown").unwrap(); assert_eq!(type_name.name(), "DocBrown"); } } diff --git a/parser/src/ast/unary.rs b/parser/src/ast/unary.rs index fc9de70..b35aa0f 100644 --- a/parser/src/ast/unary.rs +++ b/parser/src/ast/unary.rs @@ -1,5 +1,6 @@ use ast::{expression::Expression, operator::Operator}; use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -10,6 +11,10 @@ pub struct Unary<'a> { expression: Box>, } +impl<'a> Parse<'a> for Unary<'a> { + const RULE: Rule = Rule::unary; +} + impl<'a> From> for Unary<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::unary); @@ -41,12 +46,10 @@ impl<'a> Unary<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn unary() { - let result = parse_str("!123", Rule::unary); - let unary = Unary::from(result); + let unary = Unary::parse("!123").unwrap(); assert!(unary.op().is_logical_not()); assert_eq!( diff --git a/parser/src/ast/variable.rs b/parser/src/ast/variable.rs index f826c4a..359240b 100644 --- a/parser/src/ast/variable.rs +++ b/parser/src/ast/variable.rs @@ -1,4 +1,5 @@ use grammar::Rule; +use parse::Parse; use pest::iterators::Pair; use pest::Span; @@ -8,6 +9,10 @@ pub struct Variable<'a> { pub name: String, } +impl<'a> Parse<'a> for Variable<'a> { + const RULE: Rule = Rule::variable; +} + impl<'a> From> for Variable<'a> { fn from(pair: Pair<'a, Rule>) -> Self { assert_eq!(pair.as_rule(), Rule::variable); @@ -30,13 +35,10 @@ impl<'a> Variable<'a> { #[cfg(test)] mod test { use super::*; - use grammar::parse_str; #[test] fn variable() { - let pair = parse_str("marty_mcfly", Rule::variable); - let variable = Variable::from(pair); - + let variable = Variable::parse("marty_mcfly").unwrap(); assert_eq!(variable.name(), "marty_mcfly"); } } diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index 7ae92be..81a0a0f 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -38,7 +38,7 @@ boolean_false = @{ keyword_false } boolean_true = @{ keyword_true } braced = !{ "(" ~ newline* ~ expression ~ newline* ~ ")" } constructor = !{ type_name ~ "{" ~ argument_list? ~ "}" } -literal = !{ constructor | array | map | float | integer | string | atom | property | variable | braced | boolean | type_name } +literal = !{ constructor | array | map | float | integer | string | atom | property | type_name | variable | braced | boolean } property = ${ "@" ~ identifier } unary = ${ unary_operator ~ expression } variable = @{ identifier } @@ -87,7 +87,7 @@ keyword_false = { "false" } identifier_test = _{ soi ~ identifier ~ eoi } identifier = @{ !keyword ~ identifier_head ~ identifier_tail? } -identifier_head = @{ 'a'..'z' | "_" } +identifier_head = @{ 'A'..'Z' | 'a'..'z' | "_" } identifier_tail = @{ ('a'..'z' | 'A'..'Z' | "_" | '0'..'9')+ } type_name = @{ !keyword ~ type_name_head ~ type_name_tail? } type_name_head = @{ 'A'..'Z' } diff --git a/parser/src/grammar/mod.rs b/parser/src/grammar/mod.rs index c087127..0eb4181 100644 --- a/parser/src/grammar/mod.rs +++ b/parser/src/grammar/mod.rs @@ -6,16 +6,3 @@ pub struct Grammar; #[cfg(test)] mod test; - -use pest::iterators::Pair; -use pest::Parser; - -pub fn parse_str<'a>(source: &'a str, rule: Rule) -> Pair<'a, Rule> { - let result = Grammar::parse(rule, source); - if result.is_err() { - println!("{}", result.err().unwrap()); - panic!("Parses without failure"); - } else { - result.unwrap().next().unwrap() - } -} diff --git a/parser/src/grammar/test/array.rs b/parser/src/grammar/test/array.rs index 418d2e8..2ab7c2c 100644 --- a/parser/src/grammar/test/array.rs +++ b/parser/src/grammar/test/array.rs @@ -1,4 +1,3 @@ -use super::assert_parses_expression; use grammar::{Grammar, Rule}; #[test] diff --git a/parser/src/grammar/test/binary.rs b/parser/src/grammar/test/binary.rs index af497ce..5923573 100644 --- a/parser/src/grammar/test/binary.rs +++ b/parser/src/grammar/test/binary.rs @@ -1,4 +1,4 @@ -use grammar::{Grammar, Rule}; +// use grammar::{Grammar, Rule}; // #[test] // fn binary_operators() { diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 47d89a2..68ba2d6 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -16,4 +16,8 @@ mod parse; pub use ast::*; pub use error::ParseError; -pub use parse::parse_file; +pub use parse::Parse; + +pub fn parse_file<'a>(source: &'a str) -> Result, ParseError<'a>> { + File::parse(source) +} diff --git a/parser/src/parse.rs b/parser/src/parse.rs index 29d7f8b..daa118f 100644 --- a/parser/src/parse.rs +++ b/parser/src/parse.rs @@ -1,16 +1,18 @@ -use ast::File; use error::ParseError; use grammar::{Grammar, Rule}; use pest::{iterators::Pair, Parser}; -pub fn parse_file<'a>(source: &'a str) -> Result, ParseError<'a>> { - run_parser(source, Rule::file).and_then(|p| Ok(File::from(p))) -} +pub trait Parse<'a, Node = Self> +where + Node: From>, +{ + const RULE: Rule; -fn run_parser<'a>(source: &'a str, rule: Rule) -> Result, ParseError<'a>> { - let result = Grammar::parse(rule, source); - match result { - Ok(mut pairs) => Ok(pairs.next().unwrap()), - Err(pest_error) => Err(ParseError::from(pest_error)), + fn parse(source: &'a str) -> Result> { + let result = Grammar::parse(Self::RULE, source); + match result { + Ok(mut pairs) => Ok(Node::from(pairs.next().unwrap())), + Err(pest_error) => Err(ParseError::from(pest_error)), + } } }