diff options
Diffstat (limited to 'src/modelica_parser.lalrpop')
-rw-r--r-- | src/modelica_parser.lalrpop | 106 |
1 files changed, 49 insertions, 57 deletions
diff --git a/src/modelica_parser.lalrpop b/src/modelica_parser.lalrpop index 09036bd..9cb2c1c 100644 --- a/src/modelica_parser.lalrpop +++ b/src/modelica_parser.lalrpop @@ -1,4 +1,6 @@ -// XXX: use std::str::FromStr; +use std::str::FromStr; +// XXX: use modelica_ast::{Model, Component, ComponentPrefix, Connection, SimpleEquation, Bin}; +use modelica_ast::*; // This is an incomplete, non-standards-compliant, minimum-viable parser @@ -6,90 +8,80 @@ grammar; // Lexical Tokens -identifier: () = { - r"[a-zA-Z_][a-zA-Z_0-9]*", +pub identifier: String = { + r"[a-zA-Z_][a-zA-Z_0-9]*" => <>.to_string(), }; -string_literal: () = { - r#""[^"\\]*""#, +string_literal: String = { + r#""[^"\\]*""# => <>.to_string(), //<s:r#""[^"\\]*""#> => &s[1..s.len()-1], }; -pub integer: () = { - r"[+-]?\d+", +pub integer: i64 = { + r"[+-]?\d+" => i64::from_str(<>).unwrap(), }; -float: () = { - r"[+-]?\d+\.\d*([eE][-+]?\d+)?", +pub float: f64 = { + r"[+-]?\d+\.\d*([eE][-+]?\d+)?" => f64::from_str(<>).unwrap(), }; // Grammar -pub model: () = { - "model" identifier component_declaration* "equation" equation_entry* "end" identifier ";", +pub model: Model = { + "model" <n:identifier> <cd:component_declaration*> "equation" <cc:connect_clause*> <se:simple_equation*> "end" identifier ";" => + Model { name:n, components: cd, connections: cc, equations: se, extends: vec![] }, }; -equation_entry: () = { - simple_equation, - connect_clause, +component_declaration: Component = { + <prefix:component_prefix?> <specifier:identifier> <name:identifier> string_literal? ";" => + Component { prefix:prefix, specifier:specifier, name:name}, }; -component_declaration: () = { - component_prefix? identifier identifier string_literal? ";", +component_prefix: ComponentPrefix = { + "flow" => ComponentPrefix::Flow, + "stream" => ComponentPrefix::Stream, + "input" => ComponentPrefix::Input, + "output" => ComponentPrefix::Output, + "discrete" => ComponentPrefix::Discrete, + "parameter" => ComponentPrefix::Parameter, + "constant" => ComponentPrefix::Constant, }; -component_prefix: () = { - "flow", - "stream", - "input", - "output", - "discrete", - "parameter", - "constant", +simple_equation: SimpleEquation = { + <lhs:expr> "=" <rhs:expr> ";" => SimpleEquation {lhs:lhs, rhs:rhs}, }; -simple_equation: () = { - expr "=" expr ";", -}; - -connect_clause: () = { - "connect" "(" identifier "," identifier ")" ";", +connect_clause: Connection = { + "connect" "(" <a:identifier> "," <b:identifier> ")" ";" => + Connection { a: a.to_string(), b: b.to_string()}, }; // This weird expr/factor/term hierarchy is for binary operator precedence -expr: () = { - expr "+" factor, - expr "-" factor, +expr: Expr = { + <lhs:expr> "+" <rhs:factor> => + Expr::BinExpr(BinOperator::Add, Box::new(lhs), Box::new(rhs)), + <lhs:expr> "-" <rhs:factor> => + Expr::BinExpr(BinOperator::Subtract, Box::new(lhs), Box::new(rhs)), factor, }; -factor: () = { - factor "*" term, - factor "/" term, - "-" term, +factor: Expr = { + <lhs:factor> "*" <rhs:term> => + Expr::BinExpr(BinOperator::Multiply, Box::new(lhs), Box::new(rhs)), + <lhs:factor> "/" <rhs:term> => + Expr::BinExpr(BinOperator::Divide, Box::new(lhs), Box::new(rhs)), + "-" <t:term> => + Expr::BinExpr(BinOperator::Multiply, Box::new(Expr::Integer(-1)), Box::new(t)), term, }; -term: () = { - integer, - float, - identifier, - "der" "(" expr ")", - "abs" "(" expr ")", - "(" expr ")", -}; - -binary_op: () = { - "+", - "-", - "*", - "/", -}; - -//// Meta/High-Level - -pub file: () = { - model, +term: Expr = { + integer => Expr::Integer(<>), + float => Expr::Float(<>), + identifier => Expr::Ident(<>), + "der" "(" <e:expr> ")" => Expr::Der(Box::new(e)), + "abs" "(" <e:expr> ")" => Expr::Abs(Box::new(e)), + "(" <e:expr> ")" => e, }; |