Antares Simulator
Power System Simulator
NodeChecker.h
1 /*
2  * Copyright 2007-2025, RTE (https://www.rte-france.com)
3  * See AUTHORS.txt
4  * SPDX-License-Identifier: MPL-2.0
5  * This file is part of Antares-Simulator,
6  * Adequacy and Performance assessment for interconnected energy networks.
7  *
8  * Antares_Simulator is free software: you can redistribute it and/or modify
9  * it under the terms of the Mozilla Public Licence 2.0 as published by
10  * the Mozilla Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Antares_Simulator is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * Mozilla Public Licence 2.0 for more details.
17  *
18  * You should have received a copy of the Mozilla Public Licence 2.0
19  * along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
20  */
21 
22 #pragma once
23 #include <fmt/format.h>
24 #include <optional>
25 #include <ranges>
26 
27 #include <antares/expressions/nodes/NodesForwardDeclaration.h>
28 #include <antares/expressions/visitors/NodeVisitor.h>
29 #include <antares/io/inputs/model-converter/ForbiddenNodes.h>
30 
31 namespace Antares::IO::Inputs::ModelConverter
32 {
34 {
35 public:
36  explicit NodeChecker(const ForbiddenNodes& forbid, const std::string& expression);
37  [[nodiscard]] std::string name() const override;
38 
39  void visit(const Expressions::Nodes::SumNode*) override;
40  void visit(const Expressions::Nodes::SubtractionNode*) override;
41  void visit(const Expressions::Nodes::MultiplicationNode*) override;
42  void visit(const Expressions::Nodes::DivisionNode*) override;
43  void visit(const Expressions::Nodes::EqualNode*) override;
44  void visit(const Expressions::Nodes::LessThanOrEqualNode*) override;
45  void visit(const Expressions::Nodes::GreaterThanOrEqualNode*) override;
46  void visit(const Expressions::Nodes::NegationNode*) override;
47  void visit(const Expressions::Nodes::LiteralNode*) override;
48  void visit(const Expressions::Nodes::VariableNode*) override;
49  void visit(const Expressions::Nodes::ParameterNode*) override;
50  void visit(const Expressions::Nodes::PortFieldNode*) override;
51  void visit(const Expressions::Nodes::PortFieldSumNode*) override;
52  void visit(const Expressions::Nodes::TimeShiftNode*) override;
53  void visit(const Expressions::Nodes::TimeIndexNode*) override;
54  void visit(const Expressions::Nodes::TimeSumNode*) override;
55  void visit(const Expressions::Nodes::AllTimeSumNode*) override;
56  void visit(const Expressions::Nodes::FunctionNode*) override;
57 
58 private:
59  template<Expressions::Nodes::FunctionNodeType func>
60  void checkConsistencyWithParents(const std::string& childName) const;
61  template<class Child>
62  void checkConsistencyWithParents(const std::string& childName) const;
63 
64  template<class Parent>
65  void checkChildren(const std::string& parentName,
66  const std::vector<Expressions::Nodes::Node*>& children,
67  bool validateConsistencyWithParents);
68  template<Expressions::Nodes::FunctionNodeType func>
69  void checkChildren(const std::string& parentName,
70  const std::vector<Expressions::Nodes::Node*>& children,
71  bool validateConsistencyWithParents);
72  template<class NodeType>
73  void handleComparisonNode(const std::string& op,
74  const std::vector<Expressions::Nodes::Node*>& children);
75 
76  //--
77 
78  const ForbiddenNodes& forbid_;
79  std::vector<std::pair<std::string, std::type_index>> parentsStack_;
80  const std::string& expression_;
81 };
82 
84 {
85  std::string expression;
86  std::string childName;
87  std::optional<std::string> parentName;
88 };
89 
90 class BadContextComposition final: public std::invalid_argument
91 {
92 public:
93  static std::string BuildMessage(const BadExpression& context)
94  {
95  if (context.parentName.has_value())
96  {
97  return fmt::format("'{}' is not allowed to contain '{}' in this context '{}'",
98  context.parentName.value(),
99  context.childName,
100  context.expression);
101  }
102  return fmt::format("'{}' is not allowed in this context '{}'",
103  context.childName,
104  context.expression);
105  }
106 
107  explicit BadContextComposition(const BadExpression& context):
108  invalid_argument(BuildMessage(context))
109  {
110  }
111 };
112 
113 template<typename Child>
114 void NodeChecker::checkConsistencyWithParents(const std::string& childName) const
115 {
116  if (forbid_.isForbidden<Child>())
117  {
118  throw BadContextComposition(
119  {.expression = expression_, .childName = childName, .parentName = std::nullopt});
120  }
121  for (const auto& [parentName, typeIndex]: std::ranges::reverse_view(parentsStack_))
122  {
123  if (forbid_.isForbiddenFor<Child>(typeIndex))
124  {
125  throw BadContextComposition(
126  {.expression = expression_, .childName = childName, .parentName = parentName});
127  }
128  }
129 }
130 
131 template<Expressions::Nodes::FunctionNodeType func>
132 void NodeChecker::checkConsistencyWithParents(const std::string& childName) const
133 {
134  if (forbid_.isForbidden<func>())
135  {
136  throw BadContextComposition(
137  {.expression = expression_, .childName = childName, .parentName = std::nullopt});
138  }
139  for (const auto& [parentName, typeIndex]: std::ranges::reverse_view(parentsStack_))
140  {
141  if (forbid_.isForbiddenFor<func>(typeIndex))
142  {
143  throw BadContextComposition(
144  {.expression = expression_, .childName = childName, .parentName = parentName});
145  }
146  }
147 }
148 
149 template<typename Parent>
150 void NodeChecker::checkChildren(const std::string& parentName,
151  const std::vector<Expressions::Nodes::Node*>& children,
152  bool validateConsistencyWithParents)
153 {
154  if (validateConsistencyWithParents)
155  {
156  checkConsistencyWithParents<Parent>(parentName);
157  }
158  parentsStack_.emplace_back(parentName, typeid(Parent));
159 
160  for (const auto* child: children)
161  {
162  dispatch(child);
163  }
164  parentsStack_.pop_back();
165 }
166 
167 template<Expressions::Nodes::FunctionNodeType func>
168 void NodeChecker::checkChildren(const std::string& parentName,
169  const std::vector<Expressions::Nodes::Node*>& children,
170  bool validateConsistencyWithParents)
171 {
172  if (validateConsistencyWithParents)
173  {
174  checkConsistencyWithParents<func>(parentName);
175  }
176  parentsStack_.emplace_back(
177  parentName,
178  typeid(std::integral_constant<Expressions::Nodes::FunctionNodeType, func>));
179 
180  for (const auto* child: children)
181  {
182  dispatch(child);
183  }
184  parentsStack_.pop_back();
185 }
186 
187 template<typename NodeType>
188 void NodeChecker::handleComparisonNode(const std::string& op,
189  const std::vector<Expressions::Nodes::Node*>& children)
190 {
191  checkChildren<NodeType>("expression with " + op, children, true);
192 }
193 
194 } // namespace Antares::IO::Inputs::ModelConverter
Represents a AllTimeSumNode node in a syntax tree.
Definition: AllTimeSumNode.h:31
Represents a division node in a syntax tree.
Definition: DivisionNode.h:31
Represents an equality comparison node in a syntax tree.
Definition: EqualNode.h:31
AST node representing a function expression (max, min, pow, ...).
Definition: FunctionNode.h:63
Represents a greater than or equal comparison node in a syntax tree.
Definition: GreaterThanOrEqualNode.h:31
Represents a less than or equal comparison node in a syntax tree.
Definition: LessThanOrEqualNode.h:31
Represents a literal node in a syntax tree, storing a double value.
Definition: LiteralNode.h:11
Represents a multiplication node in a syntax tree.
Definition: MultiplicationNode.h:31
Represents a negation node in a syntax tree.
Definition: NegationNode.h:31
Represents a parameter node in a syntax tree, storing a string value.
Definition: ParameterNode.h:14
Represents a port field node in a syntax tree.
Definition: PortFieldNode.h:32
Represents a port field node where the expression is a sum.
Definition: PortFieldSumNode.h:32
Represents a subtraction node in a syntax tree.
Definition: SubtractionNode.h:31
Definition: SumNode.h:29
Definition: TimeIndexNode.h:28
Definition: TimeShiftNode.h:29
Definition: TimeSumNode.h:28
Represents a variable node in a syntax tree, storing a string value.
Definition: VariableNode.h:20
void dispatch(const Nodes::Node *node, Args... args)
Definition: NodeVisitor.h:94