Dont hardcode functions
parent
eb7a236720
commit
0a937c75fb
|
@ -0,0 +1 @@
|
|||
nightly-2021-12-16
|
|
@ -1,12 +1,19 @@
|
|||
use crate::Tree;
|
||||
use crate::{Tree, Literal};
|
||||
|
||||
grammar<'s>();
|
||||
|
||||
|
||||
pub Tree: Tree = {
|
||||
"(" "+" <Tree*> ")" => Tree::Add(<>),
|
||||
"(" "-" <Tree+> ")" => Tree::Sub(<>),
|
||||
"(" "*" <Tree*> ")" => Tree::Mul(<>),
|
||||
"(" "/" <Tree+> ")" => Tree::Div(<>),
|
||||
r"[0-9]+(\.[0-9]+)?" => Tree::Val(<>.parse().unwrap()),
|
||||
pub(crate) Tree: Tree = {
|
||||
"(" <Tree+> ")" => Tree::Branch(<>),
|
||||
Literal => Tree::Leaf(<>),
|
||||
}
|
||||
|
||||
|
||||
Literal: Literal = {
|
||||
Sym => Literal::Sym(<>),
|
||||
Num => Literal::Num(<>),
|
||||
}
|
||||
|
||||
|
||||
Sym: String = { r"[A-Za-z!$%&*+\-./:<=>?@^_~][A-Za-z!$%&*+\-./:<=>?@^_~0-9]*" => <>.to_owned() }
|
||||
Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() }
|
616
src/grammar.rs
616
src/grammar.rs
|
@ -1,18 +1,18 @@
|
|||
// auto-generated: "lalrpop 0.19.6"
|
||||
// sha3: df1d4c73d92562a3473f57d776bdf582379e4cd2914b23c96b97e851e4c77
|
||||
use crate::Tree;
|
||||
// sha3: 7ba7fe6c5aa9717ac4d235512a3b2cf277d6214df69326d5888744c6ef49d74
|
||||
use crate::{Literal, Tree};
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate lalrpop_util as __lalrpop_util;
|
||||
#[allow(unused_imports)]
|
||||
use self::__lalrpop_util::state_machine as __state_machine;
|
||||
extern crate core;
|
||||
extern crate alloc;
|
||||
extern crate core;
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
mod __parse__Tree {
|
||||
#![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)]
|
||||
|
||||
use crate::Tree;
|
||||
use crate::{Tree, Literal};
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate lalrpop_util as __lalrpop_util;
|
||||
#[allow(unused_imports)]
|
||||
|
@ -24,53 +24,40 @@ mod __parse__Tree {
|
|||
pub(crate) enum __Symbol<'input>
|
||||
{
|
||||
Variant0(&'input str),
|
||||
Variant1(Tree),
|
||||
Variant2(alloc::vec::Vec<Tree>),
|
||||
Variant1(Literal),
|
||||
Variant2(f64),
|
||||
Variant3(String),
|
||||
Variant4(Tree),
|
||||
Variant5(alloc::vec::Vec<Tree>),
|
||||
}
|
||||
const __ACTION: &[i8] = &[
|
||||
// State 0
|
||||
11, 0, 0, 0, 0, 0, 12,
|
||||
2, 0, 8, 9,
|
||||
// State 1
|
||||
11, 14, 0, 0, 0, 0, 12,
|
||||
2, 0, 8, 9,
|
||||
// State 2
|
||||
11, 15, 0, 0, 0, 0, 12,
|
||||
2, 12, 8, 9,
|
||||
// State 3
|
||||
11, 0, 0, 0, 0, 0, 12,
|
||||
-6, -6, -6, -6,
|
||||
// State 4
|
||||
11, 0, 0, 0, 0, 0, 12,
|
||||
-2, -2, -2, -2,
|
||||
// State 5
|
||||
11, 17, 0, 0, 0, 0, 12,
|
||||
-1, -1, -1, -1,
|
||||
// State 6
|
||||
11, 18, 0, 0, 0, 0, 12,
|
||||
0, 0, 0, 0,
|
||||
// State 7
|
||||
11, 19, 0, 0, 0, 0, 12,
|
||||
-3, -3, -3, -3,
|
||||
// State 8
|
||||
11, 20, 0, 0, 0, 0, 12,
|
||||
-4, -4, -4, -4,
|
||||
// State 9
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
-7, -7, -7, -7,
|
||||
// State 10
|
||||
0, 0, 2, 3, 4, 5, 0,
|
||||
-8, -8, -8, -8,
|
||||
// State 11
|
||||
-7, -7, 0, 0, 0, 0, -7,
|
||||
// State 12
|
||||
-10, -10, 0, 0, 0, 0, -10,
|
||||
// State 13
|
||||
-4, -4, 0, 0, 0, 0, -4,
|
||||
// State 14
|
||||
-1, -1, 0, 0, 0, 0, -1,
|
||||
// State 15
|
||||
-11, -11, 0, 0, 0, 0, -11,
|
||||
// State 16
|
||||
-5, -5, 0, 0, 0, 0, -5,
|
||||
// State 17
|
||||
-2, -2, 0, 0, 0, 0, -2,
|
||||
// State 18
|
||||
-3, -3, 0, 0, 0, 0, -3,
|
||||
// State 19
|
||||
-6, -6, 0, 0, 0, 0, -6,
|
||||
-5, -5, -5, -5,
|
||||
];
|
||||
fn __action(state: i8, integer: usize) -> i8 {
|
||||
__ACTION[(state as usize) * 7 + integer]
|
||||
__ACTION[(state as usize) * 4 + integer]
|
||||
}
|
||||
const __EOF_ACTION: &[i8] = &[
|
||||
// State 0
|
||||
|
@ -80,53 +67,35 @@ mod __parse__Tree {
|
|||
// State 2
|
||||
0,
|
||||
// State 3
|
||||
0,
|
||||
-6,
|
||||
// State 4
|
||||
0,
|
||||
-2,
|
||||
// State 5
|
||||
0,
|
||||
-1,
|
||||
// State 6
|
||||
0,
|
||||
-9,
|
||||
// State 7
|
||||
0,
|
||||
-3,
|
||||
// State 8
|
||||
0,
|
||||
-4,
|
||||
// State 9
|
||||
-12,
|
||||
0,
|
||||
// State 10
|
||||
0,
|
||||
// State 11
|
||||
-7,
|
||||
// State 12
|
||||
0,
|
||||
// State 13
|
||||
-4,
|
||||
// State 14
|
||||
-1,
|
||||
// State 15
|
||||
0,
|
||||
// State 16
|
||||
-5,
|
||||
// State 17
|
||||
-2,
|
||||
// State 18
|
||||
-3,
|
||||
// State 19
|
||||
-6,
|
||||
];
|
||||
fn __goto(state: i8, nt: usize) -> i8 {
|
||||
match nt {
|
||||
0 => match state {
|
||||
1..=4 => 12,
|
||||
5..=8 => 15,
|
||||
_ => 9,
|
||||
},
|
||||
2 => match state {
|
||||
2 => 6,
|
||||
3 => 7,
|
||||
4 => 8,
|
||||
_ => 5,
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 5,
|
||||
3 => match state {
|
||||
1 => 9,
|
||||
2 => 10,
|
||||
_ => 6,
|
||||
},
|
||||
4 => 2,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
@ -134,11 +103,8 @@ mod __parse__Tree {
|
|||
const __TERMINAL: &[&str] = &[
|
||||
r###""(""###,
|
||||
r###"")""###,
|
||||
r###""*""###,
|
||||
r###""+""###,
|
||||
r###""-""###,
|
||||
r###""/""###,
|
||||
r###"r#"[0-9]+(\\.[0-9]+)?"#"###,
|
||||
r###"r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"#"###,
|
||||
];
|
||||
__TERMINAL.iter().enumerate().filter_map(|(index, terminal)| {
|
||||
let next_state = __action(__state, index);
|
||||
|
@ -191,7 +157,7 @@ mod __parse__Tree {
|
|||
|
||||
#[inline]
|
||||
fn error_action(&self, state: i8) -> i8 {
|
||||
__action(state, 7 - 1)
|
||||
__action(state, 4 - 1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -255,13 +221,10 @@ mod __parse__Tree {
|
|||
) -> Option<usize>
|
||||
{
|
||||
match *__token {
|
||||
Token(1, _) if true => Some(0),
|
||||
Token(2, _) if true => Some(1),
|
||||
Token(3, _) if true => Some(2),
|
||||
Token(4, _) if true => Some(3),
|
||||
Token(5, _) if true => Some(4),
|
||||
Token(6, _) if true => Some(5),
|
||||
Token(0, _) if true => Some(6),
|
||||
Token(2, _) if true => Some(0),
|
||||
Token(3, _) if true => Some(1),
|
||||
Token(0, _) if true => Some(2),
|
||||
Token(1, _) if true => Some(3),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -275,20 +238,20 @@ mod __parse__Tree {
|
|||
) -> __Symbol<'input>
|
||||
{
|
||||
match __token_index {
|
||||
0 | 1 | 2 | 3 | 4 | 5 | 6 => match __token {
|
||||
Token(1, __tok0) | Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(5, __tok0) | Token(6, __tok0) | Token(0, __tok0) if true => __Symbol::Variant0(__tok0),
|
||||
0 | 1 | 2 | 3 => match __token {
|
||||
Token(2, __tok0) | Token(3, __tok0) | Token(0, __tok0) | Token(1, __tok0) if true => __Symbol::Variant0(__tok0),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
pub struct TreeParser {
|
||||
pub(crate) struct TreeParser {
|
||||
builder: __lalrpop_util::lexer::MatcherBuilder,
|
||||
_priv: (),
|
||||
}
|
||||
|
||||
impl TreeParser {
|
||||
pub fn new() -> TreeParser {
|
||||
pub(crate) fn new() -> TreeParser {
|
||||
let __builder = super::__intern_token::new_builder();
|
||||
TreeParser {
|
||||
builder: __builder,
|
||||
|
@ -297,7 +260,7 @@ mod __parse__Tree {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn parse<
|
||||
pub(crate) fn parse<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
|
@ -353,17 +316,8 @@ mod __parse__Tree {
|
|||
__reduce7(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
|
||||
}
|
||||
8 => {
|
||||
__reduce8(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
|
||||
}
|
||||
9 => {
|
||||
__reduce9(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
|
||||
}
|
||||
10 => {
|
||||
__reduce10(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
|
||||
}
|
||||
11 => {
|
||||
// __Tree = Tree => ActionFn(0);
|
||||
let __sym0 = __pop_Variant1(__symbols);
|
||||
let __sym0 = __pop_Variant4(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action0::<>(input, __sym0);
|
||||
|
@ -386,18 +340,51 @@ mod __parse__Tree {
|
|||
'input,
|
||||
>(
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
|
||||
) -> (usize, Tree, usize)
|
||||
) -> (usize, Literal, usize)
|
||||
{
|
||||
match __symbols.pop() {
|
||||
Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r),
|
||||
_ => __symbol_type_mismatch()
|
||||
}
|
||||
}
|
||||
fn __pop_Variant3<
|
||||
'input,
|
||||
>(
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
|
||||
) -> (usize, String, usize)
|
||||
{
|
||||
match __symbols.pop() {
|
||||
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
|
||||
_ => __symbol_type_mismatch()
|
||||
}
|
||||
}
|
||||
fn __pop_Variant4<
|
||||
'input,
|
||||
>(
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
|
||||
) -> (usize, Tree, usize)
|
||||
{
|
||||
match __symbols.pop() {
|
||||
Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r),
|
||||
_ => __symbol_type_mismatch()
|
||||
}
|
||||
}
|
||||
fn __pop_Variant5<
|
||||
'input,
|
||||
>(
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
|
||||
) -> (usize, alloc::vec::Vec<Tree>, usize)
|
||||
{
|
||||
match __symbols.pop() {
|
||||
Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r),
|
||||
_ => __symbol_type_mismatch()
|
||||
}
|
||||
}
|
||||
fn __pop_Variant2<
|
||||
'input,
|
||||
>(
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
|
||||
) -> (usize, alloc::vec::Vec<Tree>, usize)
|
||||
) -> (usize, f64, usize)
|
||||
{
|
||||
match __symbols.pop() {
|
||||
Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
|
||||
|
@ -425,16 +412,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "+", ")" => ActionFn(10);
|
||||
assert!(__symbols.len() >= 3);
|
||||
let __sym2 = __pop_Variant0(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
// Literal = Sym => ActionFn(3);
|
||||
let __sym0 = __pop_Variant3(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym2.2.clone();
|
||||
let __nt = super::__action10::<>(input, __sym0, __sym1, __sym2);
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action3::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(3, 0)
|
||||
(1, 0)
|
||||
}
|
||||
pub(crate) fn __reduce1<
|
||||
'input,
|
||||
|
@ -446,17 +430,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "+", Tree+, ")" => ActionFn(11);
|
||||
assert!(__symbols.len() >= 4);
|
||||
let __sym3 = __pop_Variant0(__symbols);
|
||||
let __sym2 = __pop_Variant2(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
// Literal = Num => ActionFn(4);
|
||||
let __sym0 = __pop_Variant2(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym3.2.clone();
|
||||
let __nt = super::__action11::<>(input, __sym0, __sym1, __sym2, __sym3);
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action4::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(4, 0)
|
||||
(1, 0)
|
||||
}
|
||||
pub(crate) fn __reduce2<
|
||||
'input,
|
||||
|
@ -468,17 +448,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "-", Tree+, ")" => ActionFn(2);
|
||||
assert!(__symbols.len() >= 4);
|
||||
let __sym3 = __pop_Variant0(__symbols);
|
||||
let __sym2 = __pop_Variant2(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
// Num = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(6);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym3.2.clone();
|
||||
let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(4, 0)
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action6::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
|
||||
(1, 1)
|
||||
}
|
||||
pub(crate) fn __reduce3<
|
||||
'input,
|
||||
|
@ -490,16 +466,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "*", ")" => ActionFn(12);
|
||||
assert!(__symbols.len() >= 3);
|
||||
let __sym2 = __pop_Variant0(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
// Sym = r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"# => ActionFn(5);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym2.2.clone();
|
||||
let __nt = super::__action12::<>(input, __sym0, __sym1, __sym2);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(3, 0)
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action5::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
|
||||
(1, 2)
|
||||
}
|
||||
pub(crate) fn __reduce4<
|
||||
'input,
|
||||
|
@ -511,17 +484,16 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "*", Tree+, ")" => ActionFn(13);
|
||||
assert!(__symbols.len() >= 4);
|
||||
let __sym3 = __pop_Variant0(__symbols);
|
||||
let __sym2 = __pop_Variant2(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
// Tree = "(", Tree+, ")" => ActionFn(1);
|
||||
assert!(__symbols.len() >= 3);
|
||||
let __sym2 = __pop_Variant0(__symbols);
|
||||
let __sym1 = __pop_Variant5(__symbols);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym3.2.clone();
|
||||
let __nt = super::__action13::<>(input, __sym0, __sym1, __sym2, __sym3);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(4, 0)
|
||||
let __end = __sym2.2.clone();
|
||||
let __nt = super::__action1::<>(input, __sym0, __sym1, __sym2);
|
||||
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
|
||||
(3, 3)
|
||||
}
|
||||
pub(crate) fn __reduce5<
|
||||
'input,
|
||||
|
@ -533,17 +505,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = "(", "/", Tree+, ")" => ActionFn(4);
|
||||
assert!(__symbols.len() >= 4);
|
||||
let __sym3 = __pop_Variant0(__symbols);
|
||||
let __sym2 = __pop_Variant2(__symbols);
|
||||
let __sym1 = __pop_Variant0(__symbols);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
// Tree = Literal => ActionFn(2);
|
||||
let __sym0 = __pop_Variant1(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym3.2.clone();
|
||||
let __nt = super::__action4::<>(input, __sym0, __sym1, __sym2, __sym3);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(4, 0)
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action2::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
|
||||
(1, 3)
|
||||
}
|
||||
pub(crate) fn __reduce6<
|
||||
'input,
|
||||
|
@ -555,13 +523,13 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(5);
|
||||
let __sym0 = __pop_Variant0(__symbols);
|
||||
// Tree+ = Tree => ActionFn(7);
|
||||
let __sym0 = __pop_Variant4(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action5::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
|
||||
(1, 0)
|
||||
let __nt = super::__action7::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
|
||||
(1, 4)
|
||||
}
|
||||
pub(crate) fn __reduce7<
|
||||
'input,
|
||||
|
@ -573,75 +541,22 @@ mod __parse__Tree {
|
|||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree* = => ActionFn(8);
|
||||
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
|
||||
let __end = __start.clone();
|
||||
let __nt = super::__action8::<>(input, &__start, &__end);
|
||||
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
|
||||
(0, 1)
|
||||
}
|
||||
pub(crate) fn __reduce8<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__lookahead_start: Option<&usize>,
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
|
||||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree* = Tree+ => ActionFn(9);
|
||||
let __sym0 = __pop_Variant2(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action9::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
|
||||
(1, 1)
|
||||
}
|
||||
pub(crate) fn __reduce9<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__lookahead_start: Option<&usize>,
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
|
||||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree+ = Tree => ActionFn(6);
|
||||
let __sym0 = __pop_Variant1(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym0.2.clone();
|
||||
let __nt = super::__action6::<>(input, __sym0);
|
||||
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
|
||||
(1, 2)
|
||||
}
|
||||
pub(crate) fn __reduce10<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__lookahead_start: Option<&usize>,
|
||||
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
|
||||
_: core::marker::PhantomData<(&'input (), &'s ())>,
|
||||
) -> (usize, usize)
|
||||
{
|
||||
// Tree+ = Tree+, Tree => ActionFn(7);
|
||||
// Tree+ = Tree+, Tree => ActionFn(8);
|
||||
assert!(__symbols.len() >= 2);
|
||||
let __sym1 = __pop_Variant1(__symbols);
|
||||
let __sym0 = __pop_Variant2(__symbols);
|
||||
let __sym1 = __pop_Variant4(__symbols);
|
||||
let __sym0 = __pop_Variant5(__symbols);
|
||||
let __start = __sym0.0.clone();
|
||||
let __end = __sym1.2.clone();
|
||||
let __nt = super::__action7::<>(input, __sym0, __sym1);
|
||||
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
|
||||
(2, 2)
|
||||
let __nt = super::__action8::<>(input, __sym0, __sym1);
|
||||
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
|
||||
(2, 4)
|
||||
}
|
||||
}
|
||||
pub use self::__parse__Tree::TreeParser;
|
||||
pub(crate) use self::__parse__Tree::TreeParser;
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
mod __intern_token {
|
||||
#![allow(unused_imports)]
|
||||
use crate::Tree;
|
||||
use crate::{Tree, Literal};
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate lalrpop_util as __lalrpop_util;
|
||||
#[allow(unused_imports)]
|
||||
|
@ -651,12 +566,9 @@ mod __intern_token {
|
|||
pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder {
|
||||
let __strs: &[(&str, bool)] = &[
|
||||
("^([0-9]+(\\.[0-9]+)?)", false),
|
||||
("^([!\\$-\\&\\*-\\+\\--/:<-Z\\^-_a-z\\~][!\\$-\\&\\*-\\+\\--:<-Z\\^-_a-z\\~]*)", false),
|
||||
("^(\\()", false),
|
||||
("^(\\))", false),
|
||||
("^(\\*)", false),
|
||||
("^(\\+)", false),
|
||||
("^(\\-)", false),
|
||||
("^(/)", false),
|
||||
(r"^(\s*)", true),
|
||||
];
|
||||
__lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap()
|
||||
|
@ -665,262 +577,92 @@ mod __intern_token {
|
|||
pub(crate) use self::__lalrpop_util::lexer::Token;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action0<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, __0, _): (usize, Tree, usize),
|
||||
) -> Tree
|
||||
{
|
||||
fn __action0<'input, 's>(input: &'input str, (_, __0, _): (usize, Tree, usize)) -> Tree {
|
||||
__0
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action1<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
fn __action1<'input, 's>(
|
||||
input: &'input str,
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
Tree::Add(__0)
|
||||
) -> Tree {
|
||||
Tree::Branch(__0)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action2<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
Tree::Sub(__0)
|
||||
fn __action2<'input, 's>(input: &'input str, (_, __0, _): (usize, Literal, usize)) -> Tree {
|
||||
Tree::Leaf(__0)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action3<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
Tree::Mul(__0)
|
||||
fn __action3<'input, 's>(input: &'input str, (_, __0, _): (usize, String, usize)) -> Literal {
|
||||
Literal::Sym(__0)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action4<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
(_, _, _): (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
Tree::Div(__0)
|
||||
fn __action4<'input, 's>(input: &'input str, (_, __0, _): (usize, f64, usize)) -> Literal {
|
||||
Literal::Num(__0)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action5<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, __0, _): (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
Tree::Val(__0.parse().unwrap())
|
||||
fn __action5<'input, 's>(input: &'input str, (_, __0, _): (usize, &'input str, usize)) -> String {
|
||||
__0.to_owned()
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action6<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
fn __action6<'input, 's>(input: &'input str, (_, __0, _): (usize, &'input str, usize)) -> f64 {
|
||||
__0.parse().unwrap()
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action7<'input, 's>(
|
||||
input: &'input str,
|
||||
(_, __0, _): (usize, Tree, usize),
|
||||
) -> alloc::vec::Vec<Tree>
|
||||
{
|
||||
) -> alloc::vec::Vec<Tree> {
|
||||
alloc::vec![__0]
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action7<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
fn __action8<'input, 's>(
|
||||
input: &'input str,
|
||||
(_, v, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
(_, e, _): (usize, Tree, usize),
|
||||
) -> alloc::vec::Vec<Tree>
|
||||
{
|
||||
{ let mut v = v; v.push(e); v }
|
||||
) -> alloc::vec::Vec<Tree> {
|
||||
{
|
||||
let mut v = v;
|
||||
v.push(e);
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action8<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__lookbehind: &usize,
|
||||
__lookahead: &usize,
|
||||
) -> alloc::vec::Vec<Tree>
|
||||
{
|
||||
alloc::vec![]
|
||||
pub trait __ToTriple<'input, 's> {
|
||||
fn to_triple(
|
||||
value: Self,
|
||||
) -> Result<
|
||||
(usize, Token<'input>, usize),
|
||||
__lalrpop_util::ParseError<usize, Token<'input>, &'static str>,
|
||||
>;
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action9<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
(_, v, _): (usize, alloc::vec::Vec<Tree>, usize),
|
||||
) -> alloc::vec::Vec<Tree>
|
||||
{
|
||||
v
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action10<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__0: (usize, &'input str, usize),
|
||||
__1: (usize, &'input str, usize),
|
||||
__2: (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
let __start0 = __1.2.clone();
|
||||
let __end0 = __2.0.clone();
|
||||
let __temp0 = __action8(
|
||||
input,
|
||||
&__start0,
|
||||
&__end0,
|
||||
);
|
||||
let __temp0 = (__start0, __temp0, __end0);
|
||||
__action1(
|
||||
input,
|
||||
__0,
|
||||
__1,
|
||||
__temp0,
|
||||
__2,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action11<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__0: (usize, &'input str, usize),
|
||||
__1: (usize, &'input str, usize),
|
||||
__2: (usize, alloc::vec::Vec<Tree>, usize),
|
||||
__3: (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
let __start0 = __2.0.clone();
|
||||
let __end0 = __2.2.clone();
|
||||
let __temp0 = __action9(
|
||||
input,
|
||||
__2,
|
||||
);
|
||||
let __temp0 = (__start0, __temp0, __end0);
|
||||
__action1(
|
||||
input,
|
||||
__0,
|
||||
__1,
|
||||
__temp0,
|
||||
__3,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action12<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__0: (usize, &'input str, usize),
|
||||
__1: (usize, &'input str, usize),
|
||||
__2: (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
let __start0 = __1.2.clone();
|
||||
let __end0 = __2.0.clone();
|
||||
let __temp0 = __action8(
|
||||
input,
|
||||
&__start0,
|
||||
&__end0,
|
||||
);
|
||||
let __temp0 = (__start0, __temp0, __end0);
|
||||
__action3(
|
||||
input,
|
||||
__0,
|
||||
__1,
|
||||
__temp0,
|
||||
__2,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn __action13<
|
||||
'input,
|
||||
's,
|
||||
>(
|
||||
input: &'input str,
|
||||
__0: (usize, &'input str, usize),
|
||||
__1: (usize, &'input str, usize),
|
||||
__2: (usize, alloc::vec::Vec<Tree>, usize),
|
||||
__3: (usize, &'input str, usize),
|
||||
) -> Tree
|
||||
{
|
||||
let __start0 = __2.0.clone();
|
||||
let __end0 = __2.2.clone();
|
||||
let __temp0 = __action9(
|
||||
input,
|
||||
__2,
|
||||
);
|
||||
let __temp0 = (__start0, __temp0, __end0);
|
||||
__action3(
|
||||
input,
|
||||
__0,
|
||||
__1,
|
||||
__temp0,
|
||||
__3,
|
||||
)
|
||||
}
|
||||
|
||||
pub trait __ToTriple<'input, 's, > {
|
||||
fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError<usize, Token<'input>, &'static str>>;
|
||||
}
|
||||
|
||||
impl<'input, 's, > __ToTriple<'input, 's, > for (usize, Token<'input>, usize) {
|
||||
fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError<usize, Token<'input>, &'static str>> {
|
||||
impl<'input, 's> __ToTriple<'input, 's> for (usize, Token<'input>, usize) {
|
||||
fn to_triple(
|
||||
value: Self,
|
||||
) -> Result<
|
||||
(usize, Token<'input>, usize),
|
||||
__lalrpop_util::ParseError<usize, Token<'input>, &'static str>,
|
||||
> {
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
impl<'input, 's, > __ToTriple<'input, 's, > for Result<(usize, Token<'input>, usize), &'static str> {
|
||||
fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError<usize, Token<'input>, &'static str>> {
|
||||
impl<'input, 's> __ToTriple<'input, 's> for Result<(usize, Token<'input>, usize), &'static str> {
|
||||
fn to_triple(
|
||||
value: Self,
|
||||
) -> Result<
|
||||
(usize, Token<'input>, usize),
|
||||
__lalrpop_util::ParseError<usize, Token<'input>, &'static str>,
|
||||
> {
|
||||
match value {
|
||||
Ok(v) => Ok(v),
|
||||
Err(error) => Err(__lalrpop_util::ParseError::User { error }),
|
||||
|
|
265
src/main.rs
265
src/main.rs
|
@ -1,21 +1,13 @@
|
|||
#![feature(let_else)]
|
||||
|
||||
mod grammar;
|
||||
|
||||
use debug2::dbg;
|
||||
|
||||
#[derive(Debug, debug2::Debug, PartialEq)]
|
||||
pub enum Tree {
|
||||
Val(f64),
|
||||
Add(Vec<Tree>),
|
||||
Sub(Vec<Tree>),
|
||||
Mul(Vec<Tree>),
|
||||
Div(Vec<Tree>),
|
||||
}
|
||||
|
||||
use rustyline::validate::{
|
||||
MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
|
||||
};
|
||||
use rustyline::{Editor, Result};
|
||||
use rustyline::Editor;
|
||||
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Completer, Helper, Highlighter, Hinter)]
|
||||
struct InputValidator {
|
||||
|
@ -23,84 +15,215 @@ struct InputValidator {
|
|||
}
|
||||
|
||||
impl Validator for InputValidator {
|
||||
fn validate(&self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
|
||||
fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result<ValidationResult> {
|
||||
self.brackets.validate(ctx)
|
||||
}
|
||||
}
|
||||
use debug2::dbg;
|
||||
|
||||
#[derive(Debug, debug2::Debug, PartialEq)]
|
||||
enum Tree {
|
||||
Leaf(Literal),
|
||||
Branch(Vec<Tree>),
|
||||
}
|
||||
|
||||
#[derive(Debug, debug2::Debug, PartialEq)]
|
||||
enum Literal {
|
||||
Sym(String),
|
||||
Num(f64),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RTError(String);
|
||||
|
||||
fn err<T>(s: String) -> Result<T, RTError> {
|
||||
Err(RTError(s))
|
||||
}
|
||||
|
||||
type Func = fn(&[Value]) -> Result<Value, RTError>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Value {
|
||||
Num(f64),
|
||||
Func(Func),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Value {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Num(n) => n.fmt(f),
|
||||
Self::Func(_) => f.write_str("#<procedure>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
fn as_num(&self) -> Result<f64, RTError> {
|
||||
if let Self::Num(n) = self {
|
||||
Ok(*n)
|
||||
} else {
|
||||
Err(RTError("Expected a number".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn as_func(&self) -> Result<Func, RTError> {
|
||||
if let Self::Func(f) = self {
|
||||
Ok(*f)
|
||||
} else {
|
||||
Err(RTError("Expected a function".to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Env {
|
||||
vars: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
|
||||
|
||||
// let tree = grammar::TreeParser::new().parse(&src);
|
||||
|
||||
// let t = dbg!(tree.unwrap());
|
||||
|
||||
// println!("{}", eval(&t));
|
||||
|
||||
let mut rl = Editor::new();
|
||||
rl.set_helper(Some(InputValidator {
|
||||
brackets: MatchingBracketValidator::new(),
|
||||
}));
|
||||
|
||||
let mut env = default_env();
|
||||
|
||||
while let Ok(line) = rl.readline("> ") {
|
||||
rl.add_history_entry(&line);
|
||||
|
||||
let tree = grammar::TreeParser::new().parse(&line).unwrap();
|
||||
dbg!(&tree);
|
||||
println!("< {}", eval(&tree))
|
||||
println!("< {:?}", eval(&tree, &env))
|
||||
}
|
||||
}
|
||||
|
||||
fn eval(t: &Tree) -> f64 {
|
||||
match t {
|
||||
Tree::Val(v) => *v,
|
||||
Tree::Add(vs) => vs.iter().map(eval).sum(),
|
||||
Tree::Mul(vs) => vs.iter().map(eval).product(),
|
||||
Tree::Sub(vs) => eval(&vs[0]) - vs[1..].iter().map(eval).sum::<f64>(),
|
||||
Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::<f64>(),
|
||||
fn eval(t: &Tree, env: &Env) -> Result<Value, RTError> {
|
||||
Ok(match t {
|
||||
Tree::Leaf(l) => match l {
|
||||
Literal::Sym(s) => match env.vars.get(s) {
|
||||
Some(&v) => v,
|
||||
None => return err(format!("Undefined variable `{}`", s)),
|
||||
},
|
||||
Literal::Num(v) => Value::Num(*v),
|
||||
},
|
||||
Tree::Branch(args) => {
|
||||
let Some(fun) = args.get(0) else { return err("No argument given".to_owned()) };
|
||||
let fun = eval(fun, env)?.as_func()?;
|
||||
let args = args
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|a| eval(a, env))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
return fun(&args);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// fn eval(t: &Tree) -> f64 {
|
||||
// match t {
|
||||
// Tree::Val(v) => *v,
|
||||
// Tree::Add(vs) => vs.iter().map(eval).sum(),
|
||||
// Tree::Mul(vs) => vs.iter().map(eval).product(),
|
||||
// Tree::Sub(vs) => eval(&vs[0]) - vs[1..].iter().map(eval).sum::<f64>(),
|
||||
// Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::<f64>(),
|
||||
// }
|
||||
// }
|
||||
|
||||
fn default_env() -> Env {
|
||||
let mut vars = HashMap::new();
|
||||
// vars.insert("+".to_owned(), prims::add);
|
||||
// vars.insert("-".to_owned(), prims::sub);
|
||||
// vars.insert("*".to_owned(), prims::mul);
|
||||
// vars.insert("/".to_owned(), prims::div);
|
||||
|
||||
for (name, fun) in [
|
||||
("*", prims::mul as Func),
|
||||
("+", prims::add as Func),
|
||||
("-", prims::sub as Func),
|
||||
("/", prims::div as Func),
|
||||
] {
|
||||
vars.insert(name.to_owned(), Value::Func(fun));
|
||||
}
|
||||
|
||||
Env { vars }
|
||||
}
|
||||
|
||||
mod prims {
|
||||
use crate::{RTError, Value};
|
||||
|
||||
pub(crate) fn add(args: &[Value]) -> Result<Value, RTError> {
|
||||
args.iter()
|
||||
.map(Value::as_num)
|
||||
.try_fold(0.0, |a, b| Ok(a + b?))
|
||||
.map(Value::Num)
|
||||
}
|
||||
|
||||
pub(crate) fn mul(args: &[Value]) -> Result<Value, RTError> {
|
||||
args.iter()
|
||||
.map(Value::as_num)
|
||||
.try_fold(1.0, |a, b| Ok(a * b?))
|
||||
.map(Value::Num)
|
||||
}
|
||||
|
||||
pub(crate) fn div(args: &[Value]) -> Result<Value, RTError> {
|
||||
let init = args
|
||||
.get(0)
|
||||
.ok_or_else(|| RTError("`div` needs at least one argument".to_owned()))?
|
||||
.as_num()?;
|
||||
let rest = mul(&args[1..])?.as_num().unwrap();
|
||||
Ok(Value::Num(init / rest))
|
||||
}
|
||||
|
||||
pub(crate) fn sub(args: &[Value]) -> Result<Value, RTError> {
|
||||
let init = args
|
||||
.get(0)
|
||||
.ok_or_else(|| RTError("`sub` needs at least one argument".to_owned()))?
|
||||
.as_num()?;
|
||||
let rest = add(&args[1..])?.as_num().unwrap();
|
||||
Ok(Value::Num(init - rest))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
|
||||
#[test]
|
||||
fn simple_math_space() {
|
||||
let t = grammar::TreeParser::new()
|
||||
.parse("( + 1 2 ( / 2 3 4 5) )")
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
t,
|
||||
Tree::Add(vec![
|
||||
Tree::Val(1.0),
|
||||
Tree::Val(2.0),
|
||||
Tree::Div(vec![
|
||||
Tree::Val(2.0),
|
||||
Tree::Val(3.0),
|
||||
Tree::Val(4.0),
|
||||
Tree::Val(5.0),
|
||||
])
|
||||
])
|
||||
);
|
||||
}
|
||||
// #[test]
|
||||
// fn simple_math_space() {
|
||||
// let t = grammar::TreeParser::new()
|
||||
// .parse("( + 1 2 ( / 2 3 4 5) )")
|
||||
// .unwrap();
|
||||
// assert_eq!(
|
||||
// t,
|
||||
// Tree::Add(vec![
|
||||
// Tree::Val(1.0),
|
||||
// Tree::Val(2.0),
|
||||
// Tree::Div(vec![
|
||||
// Tree::Val(2.0),
|
||||
// Tree::Val(3.0),
|
||||
// Tree::Val(4.0),
|
||||
// Tree::Val(5.0),
|
||||
// ])
|
||||
// ])
|
||||
// );
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn simple_math_dence() {
|
||||
let t = grammar::TreeParser::new()
|
||||
.parse("(+ 1 2 (/ 2 3 4 5))")
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
t,
|
||||
Tree::Add(vec![
|
||||
Tree::Val(1.0),
|
||||
Tree::Val(2.0),
|
||||
Tree::Div(vec![
|
||||
Tree::Val(2.0),
|
||||
Tree::Val(3.0),
|
||||
Tree::Val(4.0),
|
||||
Tree::Val(5.0),
|
||||
])
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
// #[test]
|
||||
// fn simple_math_dence() {
|
||||
// let t = grammar::TreeParser::new()
|
||||
// .parse("(+ 1 2 (/ 2 3 4 5))")
|
||||
// .unwrap();
|
||||
// assert_eq!(
|
||||
// t,
|
||||
// Tree::Add(vec![
|
||||
// Tree::Val(1.0),
|
||||
// Tree::Val(2.0),
|
||||
// Tree::Div(vec![
|
||||
// Tree::Val(2.0),
|
||||
// Tree::Val(3.0),
|
||||
// Tree::Val(4.0),
|
||||
// Tree::Val(5.0),
|
||||
// ])
|
||||
// ])
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
|
Loading…
Reference in New Issue