From eda539ebc4989727b6444fa3d1c9a3bf745866f7 Mon Sep 17 00:00:00 2001 From: raffitz Date: Wed, 24 Mar 2021 00:27:43 +0000 Subject: [PATCH] Add parser --- src/main.rs | 189 +++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 97 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3dd1163..a63b7e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; -use logos::{Lexer, Logos}; +use logos::Logos; +use pomelo::pomelo; use std::fs; use std::io::{Error, ErrorKind, Read}; @@ -17,101 +18,88 @@ fn io_error(err: Error, path: &str) -> String { } } -fn read_var(lex: &mut Lexer) -> Option { - lex.slice().chars().next() -} +pomelo! { + %include { + use logos::{Lexer, Logos}; + + #[derive(Debug, PartialEq)] + pub enum FunctionType{ + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Sign, + Abs, + Sqrt, + Exp, + Log(f64), + } -#[derive(Debug, PartialEq)] -enum FunctionType{ - Sin, - Cos, - Tan, - Asin, - Acos, - Atan, - Sign, - Abs, - Sqrt, - Exp, - Log(f64), -} + fn read_var(lex: &mut Lexer) -> Option { + lex.slice().chars().next() + } + } + + + %token #[derive(Logos, Debug, PartialEq)] + pub enum Token {}; + + %type #[regex("s|x|y|z|r|ρ|θ|φ", read_var)] Var char; + + %type #[token("e", |_| std::f64::consts::E)] #[token("pi", |_| std::f64::consts::PI)] #[regex("pi/2\\s", |_| std::f64::consts::FRAC_PI_2)] #[regex("pi/3\\s", |_| std::f64::consts::FRAC_PI_3)] #[regex("pi/4\\s", |_| std::f64::consts::FRAC_PI_4)] #[regex("pi/6\\s", |_| std::f64::consts::FRAC_PI_6)] #[regex("pi/8\\s", |_| std::f64::consts::FRAC_PI_8)] #[token("2pi", |_| std::f64::consts::TAU)] #[token("π", |_| std::f64::consts::PI)] #[regex("π/2\\s", |_| std::f64::consts::FRAC_PI_2)] #[regex("π/3\\s", |_| std::f64::consts::FRAC_PI_3)] #[regex("π/4\\s", |_| std::f64::consts::FRAC_PI_4)] #[regex("π/6\\s", |_| std::f64::consts::FRAC_PI_6)] #[regex("π/8\\s", |_| std::f64::consts::FRAC_PI_8)] #[token("2π", |_| std::f64::consts::TAU)] #[token("tau", |_| std::f64::consts::TAU)] #[token("τ", |_| std::f64::consts::TAU)] #[regex("√2\\s", |_| std::f64::consts::SQRT_2)] #[regex(r"[+-]?(?:\d*\.)?\d+", |lex| lex.slice().parse())] Float f64; + + %type #[token("+")] Sum; + %type #[token("-")] Subtraction; + %type #[token("/")] Quotient; + %type #[token("*")] Product; + %type #[token("^")] Power; -#[derive(Logos, Debug, PartialEq)] -enum Token { - #[regex("s|x|y|z|r|ρ|θ|φ", read_var)] - Var(char), - - #[token("e", |_| std::f64::consts::E)] - #[token("pi", |_| std::f64::consts::PI)] - #[regex("pi/2\\s", |_| std::f64::consts::FRAC_PI_2)] - #[regex("pi/3\\s", |_| std::f64::consts::FRAC_PI_3)] - #[regex("pi/4\\s", |_| std::f64::consts::FRAC_PI_4)] - #[regex("pi/6\\s", |_| std::f64::consts::FRAC_PI_6)] - #[regex("pi/8\\s", |_| std::f64::consts::FRAC_PI_8)] - #[token("2pi", |_| std::f64::consts::TAU)] - #[token("π", |_| std::f64::consts::PI)] - #[regex("π/2\\s", |_| std::f64::consts::FRAC_PI_2)] - #[regex("π/3\\s", |_| std::f64::consts::FRAC_PI_3)] - #[regex("π/4\\s", |_| std::f64::consts::FRAC_PI_4)] - #[regex("π/6\\s", |_| std::f64::consts::FRAC_PI_6)] - #[regex("π/8\\s", |_| std::f64::consts::FRAC_PI_8)] - #[token("2π", |_| std::f64::consts::TAU)] - #[token("tau", |_| std::f64::consts::TAU)] - #[token("τ", |_| std::f64::consts::TAU)] - #[regex("√2\\s", |_| std::f64::consts::SQRT_2)] - #[regex(r"[+-]?(?:\d*\.)?\d+", |lex| lex.slice().parse())] - Float(f64), - - #[regex("\\+|-|/|\\*|\\^", read_var)] - Operator(char), - - #[regex("=|<|>|≤|≥", read_var)] - #[regex("<=", |_| '≤')] - #[regex(">=", |_| '≥')] - Qualifier(char), - - #[regex("⋀|⋁|⊻|⊼|⊽", read_var)] - #[regex("⋂|∧|and|AND|&&", |_| '⋀')] - #[regex("∪|∨|v|or|OR|\\|\\|", |_| '⋁')] - #[regex("⩒|⩛|⊕|⩡|xor|XOR", |_| '⊻')] - #[regex("⩃|nand|NAND", |_| '⊼')] - #[regex("⩂|nor|NOR", |_| '⊽')] - Junction(char), - - #[token("sin", |_| FunctionType::Sin)] - #[token("cos", |_| FunctionType::Cos)] - #[token("tan", |_| FunctionType::Tan)] - #[token("asin", |_| FunctionType::Asin)] - #[token("acos", |_| FunctionType::Acos)] - #[token("atan", |_| FunctionType::Atan)] - #[token("sign", |_| FunctionType::Sign)] - #[token("abs", |_| FunctionType::Abs)] - #[token("sqrt", |_| FunctionType::Sqrt)] - #[token("√", |_| FunctionType::Sqrt)] - #[token("exp", |_| FunctionType::Exp)] - #[token("ln", |_| FunctionType::Log(1.0))] - #[token("log", |_| FunctionType::Log(std::f64::consts::LN_10))] - Function(FunctionType), - - #[token("(")] - LParen, - - #[token(")")] - RParen, - - #[token("\n")] - LineEnd, - - #[regex("#.*\\n", logos::skip)] - #[regex("//.*\\n", logos::skip)] - #[regex(r"[ \t\f]+", logos::skip)] - Whitespace, - - #[error] - Error, + %type #[regex("=|<|>|≤|≥", read_var)] #[regex("<=", |_| '≤')] #[regex(">=", |_| '≥')] Qualifier char; + + %type #[regex("⋀|⋁|⊻|⊼|⊽", read_var)] #[regex("⋂|∧|and|AND|&&", |_| '⋀')] #[regex("∪|∨|v|or|OR|\\|\\|", |_| '⋁')] #[regex("⩒|⩛|⊕|⩡|xor|XOR", |_| '⊻')] #[regex("⩃|nand|NAND", |_| '⊼')] #[regex("⩂|nor|NOR", |_| '⊽')] Junction char; + + %type #[token("sin", |_| FunctionType::Sin)] #[token("cos", |_| FunctionType::Cos)] #[token("tan", |_| FunctionType::Tan)] #[token("asin", |_| FunctionType::Asin)] #[token("acos", |_| FunctionType::Acos)] #[token("atan", |_| FunctionType::Atan)] #[token("sign", |_| FunctionType::Sign)] #[token("abs", |_| FunctionType::Abs)] #[token("sqrt", |_| FunctionType::Sqrt)] #[token("√", |_| FunctionType::Sqrt)] #[token("exp", |_| FunctionType::Exp)] #[token("ln", |_| FunctionType::Log(1.0))] #[token("log", |_| FunctionType::Log(std::f64::consts::LN_10))] Function FunctionType; + + %type #[token("(")] LParen; + %type #[token(")")] RParen; + + %type #[regex(r"\n+")] LineEnd; + + %type #[regex("\\\\n", logos::skip)] #[regex("#.*\\n", logos::skip)] #[regex("//.*\\n", logos::skip)] #[regex(r"[ \t\f]+", logos::skip)] #[error] Error; + + %left Junction; + %nonassoc Qualifier; + %left Sum Subtraction; + %left Product Quotient; + %right Power; + %right Function; + %left LineEnd; + + input ::= limit LineEnd limit LineEnd limit LineEnd metajuncture; + input ::= limit LineEnd limit LineEnd limit LineEnd metajuncture LineEnd; + input ::= LineEnd limit LineEnd limit LineEnd limit LineEnd metajuncture LineEnd; + input ::= LineEnd limit LineEnd limit LineEnd limit LineEnd metajuncture; + limit ::= expr Qualifier Var Qualifier expr; + quality ::= expr Qualifier expr; + juncture ::= quality; + juncture ::= juncture Junction juncture; + metajuncture ::= juncture; + metajuncture ::= metajuncture LineEnd metajuncture; + + expr ::= expr Sum expr; + expr ::= expr Subtraction expr; + expr ::= expr Product expr; + expr ::= expr Quotient expr; + expr ::= expr Power expr; + expr ::= Function expr; + expr ::= LParen expr RParen; + expr ::= Var; + expr ::= Float; } -fn main() { +fn main() -> Result<(), ()> { let matches = App::new(crate_name!()) .version(crate_version!()) .author(crate_authors!()) @@ -151,20 +139,27 @@ fn main() { ) .get_matches(); - let scale = matches.value_of("scale").map(|s| s.parse::().unwrap()); + //let scale = matches.value_of("scale").map(|s| s.parse::().unwrap()); let mut object_description = fs::File::open(matches.value_of("FILE").unwrap()).unwrap(); let mut data = String::new(); - if let Ok(size) = object_description.read_to_string(&mut data) { - let lex = Token::lexer(&data); + if let Ok(_) = object_description.read_to_string(&mut data) { + let lex = parser::Token::lexer(&data); + + let mut p = parser::Parser::new(); for token in lex { - print!("{:?} ", token); + p.parse(token)?; + //print!("{:?} ", token); } - println!("\nRead {} bytes, scale is {}", size, scale.unwrap_or(1)); + let tree = p.end_of_input()?; + println!("{:?}",tree); + //println!("\nRead {} bytes, scale is {}", size, scale.unwrap_or(1)); } + Ok(()) + //println!("Scale was read and is <{}>", scale.unwrap_or(1)); }