aboutsummaryrefslogtreecommitdiffstats
path: root/modelica-parser-lalrpop/src
diff options
context:
space:
mode:
Diffstat (limited to 'modelica-parser-lalrpop/src')
-rw-r--r--modelica-parser-lalrpop/src/ast.rs70
-rw-r--r--modelica-parser-lalrpop/src/parser.lalrpop48
2 files changed, 70 insertions, 48 deletions
diff --git a/modelica-parser-lalrpop/src/ast.rs b/modelica-parser-lalrpop/src/ast.rs
index e367b10..52e91b8 100644
--- a/modelica-parser-lalrpop/src/ast.rs
+++ b/modelica-parser-lalrpop/src/ast.rs
@@ -9,7 +9,7 @@ use std::collections::HashMap;
pub enum ModelicaCode {
Class, // unimpl; generic
Model(ModelicaModel),
- Record, // unimpl
+ Record(ModelicaRecord),
Block(ModelicaBlock),
Connector(ModelicaConnector),
Type(ModelicaType),
@@ -38,29 +38,34 @@ pub struct ModelicaType {
pub struct ModelicaBlock {
pub name: String,
pub description: Option<String>,
- pub component_clauses: Vec<ComponentClause>,
- pub public_component_clauses: Vec<ComponentClause>,
- pub protected_component_clauses: Vec<ComponentClause>,
+ pub components: Vec<Component>,
+ pub public_components: Vec<Component>,
+ pub protected_components: Vec<Component>,
pub equations: Vec<SimpleEquation>,
pub connections: Vec<Connection>,
- pub extends: Vec<String>,
}
#[derive(Clone, PartialEq)]
pub struct ModelicaConnector {
pub name: String,
pub description: Option<String>,
- pub component_clauses: Vec<ComponentClause>,
+ pub components: Vec<Component>,
+}
+
+#[derive(Clone, PartialEq)]
+pub struct ModelicaRecord {
+ pub name: String,
+ pub description: Option<String>,
+ pub components: Vec<Component>,
}
#[derive(Clone, PartialEq)]
pub struct ModelicaModel {
pub name: String,
pub description: Option<String>,
- pub component_clauses: Vec<ComponentClause>,
+ pub components: Vec<Component>,
pub equations: Vec<SimpleEquation>,
pub connections: Vec<Connection>,
- pub extends: Vec<String>,
}
#[derive(Copy, Clone, PartialEq)]
@@ -158,32 +163,31 @@ pub enum BinOperator {
//// Helpers
-impl ModelicaModel {
-
- // This flattens the ComponentClause/ComponentDeclaration tree into a flat
- // list of Components
- // TODO: refactor this into an iterator `components()`?
- pub fn get_components(&self) -> Vec<Component> {
-
- let mut vars: Vec<Component> = vec![];
- for clause in &self.component_clauses {
- vars.extend(clause.declarations.iter().map(|ref dec|
- Component {
- prefix: clause.prefix.clone(),
- specifier: clause.specifier.clone(),
- name: dec.name.clone(),
- value: dec.value.clone(),
- mods: dec.mods.clone(),
- description: dec.description.clone(),
- }))
- }
- vars
+// This flattens the ComponentClause/ComponentDeclaration tree into a flat
+// list of Components
+pub fn collapse_components(clauses: &Vec<ComponentClause>) -> Vec<Component> {
+
+ let mut vars: Vec<Component> = vec![];
+ for clause in clauses {
+ vars.extend(clause.declarations.iter().map(|ref dec|
+ Component {
+ prefix: clause.prefix.clone(),
+ specifier: clause.specifier.clone(),
+ name: dec.name.clone(),
+ value: dec.value.clone(),
+ mods: dec.mods.clone(),
+ description: dec.description.clone(),
+ }))
}
+ vars
+}
+
+impl ModelicaModel {
pub fn get_constant_vars(&self) -> HashMap<String,Option<Expr>> {
let mut binds = HashMap::new();
// XXX: actually implement this...
- for c in &self.get_components() {
+ for c in &self.components {
match c.prefix {
Some(ComponentPrefix::Constant) => { binds.insert(c.name.clone(), Some(Expr::Integer(123))); },
Some(ComponentPrefix::Parameter) => { binds.insert(c.name.clone(), Some(Expr::Float(4.56))); },
@@ -199,8 +203,7 @@ impl ModelicaModel {
// if a var is on LHS and RHS of same equation
pub fn get_free_vars(&self) -> Vec<String> {
// Start with components, and remove constants and parameters
- let components = self.get_components();
- let vars = components.iter().filter(|v| match v.prefix {
+ let vars = self.components.iter().filter(|v| match v.prefix {
Some(ComponentPrefix::Constant) | Some(ComponentPrefix::Parameter) => false,
_ => true,
});
@@ -278,10 +281,7 @@ impl SimpleEquation {
impl Debug for ModelicaModel {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
try!(write!(fmt, "model {}\n", self.name));
- for e in self.extends.iter() {
- try!(write!(fmt, " extends {};\n", e));
- }
- for v in self.get_components().iter() {
+ for v in self.components.iter() {
try!(write!(fmt, " {:?};\n", v));
}
try!(write!(fmt, "equation\n"));
diff --git a/modelica-parser-lalrpop/src/parser.lalrpop b/modelica-parser-lalrpop/src/parser.lalrpop
index b05ad76..442baca 100644
--- a/modelica-parser-lalrpop/src/parser.lalrpop
+++ b/modelica-parser-lalrpop/src/parser.lalrpop
@@ -1,8 +1,9 @@
use std::str::FromStr;
use std::collections::HashMap;
-use ast::{ModelicaCode, ModelicaPackage, ModelicaBlock, ModelicaConnector, ModelicaType, ModelicaModel, ComponentDeclaration,
+use ast::{ModelicaCode, ModelicaPackage, ModelicaBlock, ModelicaConnector,
+ ModelicaType, ModelicaModel, ComponentDeclaration, ModelicaRecord,
ComponentClause, ComponentPrefix, Connection, SimpleEquation, Expr,
- BinOperator, MathUnaryFunc};
+ BinOperator, MathUnaryFunc, collapse_components};
// This is an incomplete, non-standards-compliant, minimum-viable parser
// Based on the Modelica 3.3r1 Spec
@@ -16,7 +17,8 @@ grammar;
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(),
+ r"[a-zA-Z_][a-zA-Z_0-9]*\.[a-zA-Z_0-9]+" => <>.to_string(),
+ r"[a-zA-Z_][a-zA-Z_0-9]*\.[a-zA-Z_0-9]+\.[a-zA-Z_0-9]" => <>.to_string(),
};
string_literal: String = {
@@ -39,13 +41,13 @@ pub boolean: bool = {
// Grammar
pub file: Vec<ModelicaCode> = {
- <chunks:modelica_code+> => chunks,
+ within_clause? <chunks:modelica_code+> => chunks,
};
pub modelica_code: ModelicaCode = {
model => ModelicaCode::Model(<>),
// TODO: class
- // TODO: record
+ record => ModelicaCode::Record(<>),
block => ModelicaCode::Block(<>),
connector => ModelicaCode::Connector(<>),
type_declaration => ModelicaCode::Type(<>),
@@ -55,6 +57,7 @@ pub modelica_code: ModelicaCode = {
pub package: ModelicaPackage = {
"package" <n:identifier> <desc:string_literal?>
+ extends_clause*
<children:modelica_code*>
"end" identifier ";" =>
ModelicaPackage {
@@ -71,7 +74,17 @@ pub connector: ModelicaConnector = {
ModelicaConnector {
name:n,
description:desc,
- component_clauses:cpc, },
+ components: { collapse_components(&cpc) } },
+};
+
+pub record: ModelicaRecord = {
+ "record" <n:identifier> <desc:string_literal?>
+ <cpc:component_clause*>
+ "end" identifier ";" =>
+ ModelicaRecord {
+ name:n,
+ description:desc,
+ components: { collapse_components(&cpc) } },
};
type_declaration: ModelicaType = {
@@ -85,6 +98,7 @@ type_declaration: ModelicaType = {
pub block: ModelicaBlock = {
"block" <n:identifier> <desc:string_literal?>
+ extends_clause*
<cpc:component_clause*>
<public:("public" <component_clause*>)?>
<protected:("protected" <component_clause*>)?>
@@ -95,16 +109,16 @@ pub block: ModelicaBlock = {
ModelicaBlock {
name:n,
description:desc,
- component_clauses:cpc,
- public_component_clauses: { public.unwrap_or(vec![]) },
- protected_component_clauses: { protected.unwrap_or(vec![]) },
+ components: { collapse_components(&cpc) },
+ public_components: { collapse_components(&public.unwrap_or(vec![])) },
+ protected_components: { collapse_components(&protected.unwrap_or(vec![])) },
connections:cc,
- equations:se,
- extends:vec![] },
+ equations:se },
};
pub model: ModelicaModel = {
"partial"? "model" <n:identifier> <desc:string_literal?>
+ extends_clause*
<cpc:component_clause*>
connector*
"equation"
@@ -114,10 +128,18 @@ pub model: ModelicaModel = {
ModelicaModel {
name:n,
description:desc,
- component_clauses:cpc,
+ components: { collapse_components(&cpc) },
connections:cc,
equations:se,
- extends:vec![] },
+ },
+};
+
+extends_clause: String = {
+ "extends" <identifier> ";" => <>,
+};
+
+within_clause: String = {
+ "within" <identifier> ";" => <>,
};
component_clause: ComponentClause = {