1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
use std::str::FromStr;
// XXX: use modelica_ast::{ModelicaModel, Component, ComponentPrefix, Connection, SimpleEquation, Bin};
use modelica_ast::*;
// This is an incomplete, non-standards-compliant, minimum-viable parser
grammar;
// Lexical Tokens
pub identifier: String = {
r"[a-zA-Z_][a-zA-Z_0-9]*" => <>.to_string(),
};
string_literal: String = {
r#""[^"\\]*""# => <>.to_string(),
//<s:r#""[^"\\]*""#> => &s[1..s.len()-1],
};
pub integer: i64 = {
r"[+-]?\d+" => i64::from_str(<>).unwrap(),
};
pub float: f64 = {
r"[+-]?\d+\.\d*([eE][-+]?\d+)?" => f64::from_str(<>).unwrap(),
};
// Grammar
pub model: ModelicaModel = {
"model" <n:identifier> <cd:component_declaration*> "equation" <cc:connect_clause*> <se:simple_equation*> "end" identifier ";" =>
ModelicaModel { name:n, components: cd, connections: cc, equations: se, extends: vec![] },
};
component_declaration: Component = {
<prefix:component_prefix?> <specifier:identifier> <name:identifier> string_literal? ";" =>
Component { prefix:prefix, specifier:specifier, name:name},
<prefix:component_prefix?> <specifier:identifier> <name:identifier> "=" <value:expr> string_literal? ";" =>
Component { prefix:prefix, specifier:specifier, name:name},
};
component_prefix: ComponentPrefix = {
"flow" => ComponentPrefix::Flow,
"stream" => ComponentPrefix::Stream,
"input" => ComponentPrefix::Input,
"output" => ComponentPrefix::Output,
"discrete" => ComponentPrefix::Discrete,
"parameter" => ComponentPrefix::Parameter,
"constant" => ComponentPrefix::Constant,
};
simple_equation: SimpleEquation = {
<lhs:expr> "=" <rhs:expr> ";" => SimpleEquation {lhs:lhs, rhs:rhs},
};
connect_clause: Connection = {
"connect" "(" <a:identifier> "," <b:identifier> ")" ";" =>
Connection { a: a.to_string(), b: b.to_string()},
};
// This weird expr/factor/term hierarchy is for binary operator precedence
expr: Expr = {
<lhs:expr> "+" <rhs:factor> =>
Expr::BinExpr(BinOperator::Add, Box::new(lhs), Box::new(rhs)),
<lhs:expr> "-" <rhs:factor> =>
Expr::BinExpr(BinOperator::Subtract, Box::new(lhs), Box::new(rhs)),
factor,
};
factor: Expr = {
<lhs:factor> "*" <rhs:term> =>
Expr::BinExpr(BinOperator::Multiply, Box::new(lhs), Box::new(rhs)),
<lhs:factor> "/" <rhs:term> =>
Expr::BinExpr(BinOperator::Divide, Box::new(lhs), Box::new(rhs)),
<lhs:factor> "^" <rhs:term> =>
Expr::BinExpr(BinOperator::Divide, Box::new(lhs), Box::new(rhs)),
"-" <t:term> =>
Expr::BinExpr(BinOperator::Multiply, Box::new(Expr::Integer(-1)), Box::new(t)),
term,
};
term: Expr = {
integer => Expr::Integer(<>),
float => Expr::Float(<>),
identifier => Expr::Ident(<>),
"der" "(" <e:expr> ")" => Expr::Der(Box::new(e)),
"abs" "(" <e:expr> ")" => Expr::Abs(Box::new(e)),
"(" <e:expr> ")" => e,
};
|