Commit 858c9e72 authored by Christopher Silva's avatar Christopher Silva

work on formula parser

parent 69b80d85
......@@ -111,6 +111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "formula"
version = "0.1.0"
dependencies = [
"once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -238,6 +239,11 @@ name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "once_cell"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "opaque-debug"
version = "0.2.3"
......@@ -487,6 +493,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
......
......@@ -9,3 +9,4 @@ edition = "2018"
[dependencies]
pest = "2.1.3"
pest_derive = "2.1.0"
once_cell = "1.4.0"
#[macro_use]
extern crate pest_derive;
use once_cell::sync::Lazy;
use pest::Parser;
use pest::error::Error;
use pest::iterators::{Pair, Pairs};
use pest::prec_climber::{Operator, PrecClimber, Assoc};
#[derive(Parser)]
#[grammar = "formula.pest"]
pub struct FormulaParser;
fn main() {
let formula = FormulaParser::parse(Rule::formula, "=(2+2)*3");
println!("{:#?}", formula);
static PREC_CLIMBER: Lazy<PrecClimber<Rule>> = Lazy::new(|| {
use Rule::*;
use Assoc::*;
PrecClimber::new(vec![
Operator::new(add, Left) | Operator::new(subtract, Left),
Operator::new(multiply, Left) | Operator::new(divide, Left),
Operator::new(power, Right),
])
});
let formula = FormulaParser::parse(Rule::formula, "=rc[-2]*rc[-1]");
// in the real deal, this would get a reference to the sheet
// to be able to get cell values and run functions
fn evaluate_formula(input: &str, placeholder: f32) -> Result<f32, Error<Rule>> {
fn eval(expression: Pairs<Rule>, placeholder: f32) -> f32 {
PREC_CLIMBER.climb(
expression,
|pair: Pair<Rule>| match pair.as_rule() {
Rule::number => pair.as_str().parse::<f32>().unwrap(),
Rule::parenExpr => eval(pair.into_inner(), placeholder),
Rule::function => placeholder,
Rule::position => placeholder,
_ => unreachable!(),
},
|lhs: f32, op: Pair<Rule>, rhs: f32| match op.as_rule() {
Rule::add => lhs + rhs,
Rule::subtract => lhs - rhs,
Rule::multiply => lhs * rhs,
Rule::divide => lhs / rhs,
Rule::power => lhs.powf(rhs),
_ => unreachable!(),
}
)
}
let pairs = FormulaParser::parse(Rule::expr, input)?;
println!("{:#?}", pairs);
Ok(eval(pairs, placeholder))
}
fn main() {
let formula = evaluate_formula("rc[-2]*rc[-1]", 7.0);
println!("{:#?}", formula);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment