diff options
Diffstat (limited to 'modelica-parser-lalrpop/src/parser.lalrpop')
-rw-r--r-- | modelica-parser-lalrpop/src/parser.lalrpop | 69 |
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]), |