diff options
author | bnewbold <bnewbold@robocracy.org> | 2016-12-19 00:47:20 -0800 |
---|---|---|
committer | bnewbold <bnewbold@robocracy.org> | 2016-12-19 00:47:20 -0800 |
commit | d60554fce09f8be1bb4d96a83db49577dfbf550d (patch) | |
tree | bc45dfb807e057f1fb4d092805771fd7298f001f /modelica-parser-lalrpop | |
parent | aefce10b8f05dc52017beb1d422ce7b2b97bd6a5 (diff) | |
download | modelthing-d60554fce09f8be1bb4d96a83db49577dfbf550d.tar.gz modelthing-d60554fce09f8be1bb4d96a83db49577dfbf550d.zip |
parser: more progress
Diffstat (limited to 'modelica-parser-lalrpop')
-rw-r--r-- | modelica-parser-lalrpop/src/ast.rs | 70 | ||||
-rw-r--r-- | modelica-parser-lalrpop/src/parser.lalrpop | 48 |
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 = { |