aboutsummaryrefslogtreecommitdiffstats
path: root/modelica-parser-lalrpop/src/parser.lalrpop
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-12-17 18:34:47 -0800
committerbnewbold <bnewbold@robocracy.org>2016-12-17 18:34:47 -0800
commit9f82aceb9fbdb42f332d68f4a423123bd0788b2c (patch)
treec082b9795be8e9e9d286c8f8f1345d22f3ec1b59 /modelica-parser-lalrpop/src/parser.lalrpop
parentf6364ebcac0d0a88a3cc6812fd2120c97b42cc26 (diff)
downloadmodelthing-9f82aceb9fbdb42f332d68f4a423123bd0788b2c.tar.gz
modelthing-9f82aceb9fbdb42f332d68f4a423123bd0788b2c.zip
refactor modelica parser into separate crate
Diffstat (limited to 'modelica-parser-lalrpop/src/parser.lalrpop')
-rw-r--r--modelica-parser-lalrpop/src/parser.lalrpop97
1 files changed, 97 insertions, 0 deletions
diff --git a/modelica-parser-lalrpop/src/parser.lalrpop b/modelica-parser-lalrpop/src/parser.lalrpop
new file mode 100644
index 0000000..cdd15b4
--- /dev/null
+++ b/modelica-parser-lalrpop/src/parser.lalrpop
@@ -0,0 +1,97 @@
+use std::str::FromStr;
+use ast::{ModelicaModel,Component, ComponentPrefix, Connection,
+ SimpleEquation, Expr, BinOperator};
+
+// This is an incomplete, non-standards-compliant, minimum-viable parser
+
+grammar;
+
+// Lexical Tokens
+
+pub identifier: String = {
+ r"[a-zA-Z_][a-zA-Z_0-9]*" => <>.to_string(),
+};
+
+string_literal: String = {
+ r#""[^"\\]*""# => <>.to_string(),
+ //<s:r#""[^"\\]*""#> => &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(),
+};
+
+
+// Grammar
+
+pub model: ModelicaModel = {
+ "model" <n:identifier> <cd:component_declaration*> "equation" <cc:connect_clause*> <se:simple_equation*> "end" identifier ";" =>
+ ModelicaModel { name:n, components: cd, connections: cc, equations: se, extends: vec![] },
+};
+
+value_declaration: Expr = {
+ "=" <value:expr> => value
+};
+
+units_declaration: String = {
+ "(" "unit" "=" <units:string_literal> ")" => units
+};
+
+component_declaration: Component = {
+ <prefix:component_prefix?> <specifier:identifier> <name:identifier> <units:units_declaration?> <value:value_declaration?> <desc:string_literal?> ";" =>
+ Component { prefix:prefix, specifier:specifier, name:name, description:desc, value:value, units:units },
+};
+
+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 = {
+ <lhs:expr> "=" <rhs:expr> ";" => SimpleEquation {lhs:lhs, rhs:rhs},
+};
+
+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 = {
+ <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: 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)),
+ <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: 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,
+};
+