diff options
Diffstat (limited to 'modelica-parser-lalrpop/src')
| -rw-r--r-- | modelica-parser-lalrpop/src/ast.rs | 16 | ||||
| -rw-r--r-- | modelica-parser-lalrpop/src/parser.lalrpop | 69 | 
2 files changed, 60 insertions, 25 deletions
| diff --git a/modelica-parser-lalrpop/src/ast.rs b/modelica-parser-lalrpop/src/ast.rs index addb90f..e367b10 100644 --- a/modelica-parser-lalrpop/src/ast.rs +++ b/modelica-parser-lalrpop/src/ast.rs @@ -7,7 +7,7 @@ use std::collections::HashMap;  // A valid .mo file will be a sequence of these  #[derive(Clone, PartialEq)]  pub enum ModelicaCode { -    Class,      // unimpl +    Class,      // unimpl; generic      Model(ModelicaModel),      Record,     // unimpl      Block(ModelicaBlock), @@ -39,8 +39,8 @@ pub struct ModelicaBlock {      pub name: String,      pub description: Option<String>,      pub component_clauses: Vec<ComponentClause>, -    pub public_component_clauses: Option<Vec<ComponentClause>>, -    pub protected_component_clauses: Option<Vec<ComponentClause>>, +    pub public_component_clauses: Vec<ComponentClause>, +    pub protected_component_clauses: Vec<ComponentClause>,      pub equations: Vec<SimpleEquation>,      pub connections: Vec<Connection>,      pub extends: Vec<String>, @@ -88,7 +88,7 @@ pub struct ComponentDeclaration {      pub dimensions: Option<Vec<i64>>,      pub value: Option<Expr>,      pub quantity: Option<String>, -    pub units: Option<String>, +    pub mods: HashMap<String, Expr>,      pub description: Option<String>,  } @@ -99,7 +99,7 @@ pub struct Component {      pub specifier: String,      pub name: String,      pub value: Option<Expr>, -    pub units: Option<String>, +    pub mods: HashMap<String, Expr>,      pub description: Option<String>,  } @@ -120,6 +120,7 @@ pub enum Expr {      Integer(i64),      Float(f64),      Boolean(bool), +    StringLiteral(String),      Ident(String),      Der(Box<Expr>),      Sign(Box<Expr>), @@ -172,7 +173,7 @@ impl ModelicaModel {                      specifier: clause.specifier.clone(),                      name: dec.name.clone(),                      value: dec.value.clone(), -                    units: dec.units.clone(), +                    mods: dec.mods.clone(),                      description: dec.description.clone(),              }))          } @@ -237,7 +238,7 @@ impl Expr {      pub fn identifiers(&self) -> Vec<String> {          use self::Expr::*;          match *self { -            Integer(_) | Float(_) | Boolean(_) => vec![], +            Integer(_) | Float(_) | Boolean(_) | StringLiteral(_) => vec![],              Ident(ref s) => vec![s.clone()],              Der(ref e) | Sign(ref e) => e.identifiers(),              MathUnaryExpr(_, ref e) => e.identifiers(), @@ -342,6 +343,7 @@ impl Debug for Expr {              Integer(e) => write!(fmt, "{}", e),              Float(e) => write!(fmt, "{}", e),              Boolean(e) => write!(fmt, "{}", e), +            StringLiteral(ref e) => write!(fmt, "\"{}\"", e),              Ident(ref e) => write!(fmt, "{}", e),              Der(ref e) => write!(fmt, "der({:?})", e),              Sign(ref e) => write!(fmt, "sign({:?})", e), 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]), | 
