use std::str::FromStr; use ast::{ModelicaModel, ComponentDeclaration, ComponentClause, ComponentPrefix, Connection, SimpleEquation, Expr, BinOperator, MathUnaryFunc}; // This is an incomplete, non-standards-compliant, minimum-viable parser // Based on the Modelica 3.3r1 Spec grammar; // === Lexical Tokens === // Roughly (but possibly not exactly) follows B.1 pub identifier: String = { r"[a-zA-Z_][a-zA-Z_0-9]*" => <>.to_string(), }; string_literal: String = { r#""[^"\\]*""# => <>.to_string(), // => &s[1..s.len()-1], }; pub integer: i64 = { r"[+-]?\d+" => i64::from_str(<>).unwrap(), }; pub float: f64 = { r"[+-]?\d+\.\d*([eE][-+]?\d+)?" => f64::from_str(<>).unwrap(), }; pub boolean: bool = { "true" => true, "false" => false, }; // Grammar pub model: ModelicaModel = { "model" "equation" "end" identifier ";" => ModelicaModel { name:n, description:desc, component_clauses:cpc, connections:cc, equations:se, extends:vec![] }, }; value_declaration: Expr = { "=" => value }; units_declaration: String = { "(" "unit" "=" ")" => units }; component_clause: ComponentClause = { ";" => ComponentClause { prefix:prefix, specifier:specifier, declarations:declarations }, }; component_declaration: ComponentDeclaration = { (",")? => ComponentDeclaration { name:name, description:desc, value:value, units:units, quantity:None }, }; component_prefix: ComponentPrefix = { "flow" => ComponentPrefix::Flow, "stream" => ComponentPrefix::Stream, "input" => ComponentPrefix::Input, "output" => ComponentPrefix::Output, "discrete" => ComponentPrefix::Discrete, "parameter" => ComponentPrefix::Parameter, "constant" => ComponentPrefix::Constant, }; simple_equation: SimpleEquation = { ":=" ";" => SimpleEquation {lhs:lhs, rhs:rhs}, "=" ";" => SimpleEquation {lhs:lhs, rhs:rhs}, }; connect_clause: Connection = { "connect" "(" "," ")" ";" => Connection { a: a.to_string(), b: b.to_string()}, }; // This weird expr/factor/term hierarchy is for binary operator precedence expr: Expr = { "+" => Expr::BinExpr(BinOperator::Add, Box::new(lhs), Box::new(rhs)), "-" => Expr::BinExpr(BinOperator::Subtract, Box::new(lhs), Box::new(rhs)), factor, }; factor: Expr = { "*" => Expr::BinExpr(BinOperator::Multiply, Box::new(lhs), Box::new(rhs)), "/" => Expr::BinExpr(BinOperator::Divide, Box::new(lhs), Box::new(rhs)), "^" => Expr::BinExpr(BinOperator::Divide, Box::new(lhs), Box::new(rhs)), "-" => Expr::BinExpr(BinOperator::Multiply, Box::new(Expr::Integer(-1)), Box::new(t)), term, }; // TODO: elementwise operators (".+", "./", ".*", ".-") term: Expr = { integer => Expr::Integer(<>), float => Expr::Float(<>), identifier => Expr::Ident(<>), "der" "(" ")" => Expr::Der(Box::new(e)), "abs" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Abs, Box::new(e)), "sqrt" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Sqrt, Box::new(e)), "sin" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Sin, Box::new(e)), "cos" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Cos, Box::new(e)), "tan" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Tan, Box::new(e)), "asin" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Asin, Box::new(e)), "acos" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Acos, Box::new(e)), "atan" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Atan, Box::new(e)), "sinh" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Sinh, Box::new(e)), "cosh" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Cosh, Box::new(e)), "tanh" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Tanh, Box::new(e)), "exp" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Exp, Box::new(e)), "log" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Log, Box::new(e)), "log10" "(" ")" => Expr::MathUnaryExpr(MathUnaryFunc::Log10, Box::new(e)), "(" ")" => e, };