aboutsummaryrefslogtreecommitdiffstats
path: root/modelica-parser-lalrpop/src/parser.lalrpop
diff options
context:
space:
mode:
Diffstat (limited to 'modelica-parser-lalrpop/src/parser.lalrpop')
-rw-r--r--modelica-parser-lalrpop/src/parser.lalrpop69
1 files changed, 51 insertions, 18 deletions
diff --git a/modelica-parser-lalrpop/src/parser.lalrpop b/modelica-parser-lalrpop/src/parser.lalrpop
index 447c51f..b05ad76 100644
--- a/modelica-parser-lalrpop/src/parser.lalrpop
+++ b/modelica-parser-lalrpop/src/parser.lalrpop
@@ -1,4 +1,5 @@
use std::str::FromStr;
+use std::collections::HashMap;
use ast::{ModelicaCode, ModelicaPackage, ModelicaBlock, ModelicaConnector, ModelicaType, ModelicaModel, ComponentDeclaration,
ComponentClause, ComponentPrefix, Connection, SimpleEquation, Expr,
BinOperator, MathUnaryFunc};
@@ -6,18 +7,20 @@ use ast::{ModelicaCode, ModelicaPackage, ModelicaBlock, ModelicaConnector, Model
// 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(),
+ r"[a-zA-Z_][a-zA-Z_0-9]*\.[a-zA-Z_0-9]*" => <>.to_string(),
};
string_literal: String = {
r#""[^"\\]*""# => <>.to_string(),
- //<s:r#""[^"\\]*""#> => &s[1..s.len()-1],
};
pub integer: i64 = {
@@ -71,7 +74,7 @@ pub connector: ModelicaConnector = {
component_clauses:cpc, },
};
-pub type_declaration: ModelicaType = {
+type_declaration: ModelicaType = {
"type" <n:identifier> <desc:string_literal?>
"=" <cpd:component_declaration> ";" =>
ModelicaType {
@@ -93,16 +96,17 @@ pub block: ModelicaBlock = {
name:n,
description:desc,
component_clauses:cpc,
- public_component_clauses:public,
- protected_component_clauses:protected,
+ public_component_clauses: { public.unwrap_or(vec![]) },
+ protected_component_clauses: { protected.unwrap_or(vec![]) },
connections:cc,
equations:se,
extends:vec![] },
};
pub model: ModelicaModel = {
- "model" <n:identifier> <desc:string_literal?>
+ "partial"? "model" <n:identifier> <desc:string_literal?>
<cpc:component_clause*>
+ connector*
"equation"
<cc:connect_clause*>
<se:simple_equation*>
@@ -116,24 +120,21 @@ pub model: ModelicaModel = {
extends:vec![] },
};
-value_declaration: Expr = {
- "=" <value:expr> => value
-};
-
-units_declaration: String = {
- "(" "unit" "=" <units:string_literal> ")" => units
-};
-
component_clause: ComponentClause = {
- <prefix:component_prefix?> <specifier:identifier> <declarations:component_declaration+> ";" =>
- ComponentClause { prefix:prefix, specifier:specifier, declarations:declarations },
+ <prefix:component_prefix?>
+ <specifier:identifier>
+ <declarations:component_declaration+> ";" =>
+ ComponentClause {
+ prefix:prefix,
+ specifier:specifier,
+ declarations:declarations },
};
component_declaration: ComponentDeclaration = {
<name:identifier>
<ad:array_dimensions?>
- <units:units_declaration?>
- <value:value_declaration?>
+ <mods:class_mod?>
+ <value:assignment_mod?>
<desc:string_literal?>
(",")? =>
ComponentDeclaration {
@@ -141,10 +142,40 @@ component_declaration: ComponentDeclaration = {
dimensions:ad,
description:desc,
value:value,
- units:units,
+ mods: { mods.unwrap_or(HashMap::new()) },
quantity:None },
};
+// component_assigns happen in:
+// component declarations
+// argument lists
+// class_modifications (parens) happen in the above plus:
+// annotations
+// extends
+// RHS of single-line class defs
+
+assignment_mod: Expr = {
+ "=" <expr> => <>,
+};
+
+class_mod: HashMap<String, Expr> = {
+ "(" <calist:(<component_assign> ","?)+> ")" => {
+ let mut out: HashMap<String, Expr> = HashMap::new();
+ for ca in calist {
+ out.insert(ca.0, ca.1);
+ }
+ out
+ }
+};
+
+component_assign: (String, Expr) = {
+ <i:identifier> "=" <e:expr> => (i, e),
+};
+
+annotation: () = {
+ "annotation" class_mod? => (),
+};
+
// TODO: this is very partial/cludgy
array_dimensions: Vec<i64> = {
"[" <dimensions:(<integer> ","?)+> "]" => dimensions,
@@ -198,6 +229,7 @@ term: Expr = {
boolean => Expr::Boolean(<>),
float => Expr::Float(<>),
identifier => Expr::Ident(<>),
+ string_literal => Expr::StringLiteral(<>),
"der" "(" <e:expr> ")" => Expr::Der(Box::new(e)),
"abs" "(" <e:expr> ")" => Expr::MathUnaryExpr(MathUnaryFunc::Abs, Box::new(e)),
"sqrt" "(" <e:expr> ")" => Expr::MathUnaryExpr(MathUnaryFunc::Sqrt, Box::new(e)),
@@ -216,6 +248,7 @@ term: Expr = {
"(" <e:expr> ")" => e,
// Obviously a hack here, only supporting up to 4 elements in an array
"[" <e:expr> "]" => Expr::Array(vec![e]),
+ "[" <e1:expr> ";" <e2:expr> "]" => Expr::Array(vec![e1, e2]),
"[" <e1:expr> "," <e2:expr> "]" => Expr::Array(vec![e1, e2]),
"[" <e1:expr> "," <e2:expr> "," <e3:expr> "]" => Expr::Array(vec![e1, e2, e3]),
"[" <e1:expr> "," <e2:expr> "," <e3:expr> "," <e4:expr> "]" => Expr::Array(vec![e1, e2, e3, e4]),