diff --git a/src/parser/nmodl.yy b/src/parser/nmodl.yy index 5867f396d2..7d37328d90 100644 --- a/src/parser/nmodl.yy +++ b/src/parser/nmodl.yy @@ -618,7 +618,6 @@ units : { unit : "(" { scanner.scan_unit(); } ")" { - // @todo Empty units should be handled in semantic analysis auto unit = scanner.get_unit(); auto text = unit->eval(); $$ = new ast::Unit(unit); diff --git a/src/visitors/semantic_analysis_visitor.cpp b/src/visitors/semantic_analysis_visitor.cpp index eecfb74262..3af41ed196 100644 --- a/src/visitors/semantic_analysis_visitor.cpp +++ b/src/visitors/semantic_analysis_visitor.cpp @@ -2,8 +2,10 @@ #include "ast/function_block.hpp" #include "ast/procedure_block.hpp" #include "ast/program.hpp" +#include "ast/string.hpp" #include "ast/suffix.hpp" #include "ast/table_statement.hpp" +#include "ast/unit.hpp" #include "utils/logger.hpp" #include "visitors/visitor_utils.hpp" @@ -66,5 +68,14 @@ void SemanticAnalysisVisitor::visit_destructor_block(const ast::DestructorBlock& /// --> } +void SemanticAnalysisVisitor::visit_unit(const ast::Unit& node) { + /// <-- This code is for check 3 + if (node.get_name()->get_value().empty()) { + logger->warn("SemanticAnalysisVisitor:: An unit cannot be created without name."); + check_fail = true; + } + /// --> +} + } // namespace visitor } // namespace nmodl diff --git a/src/visitors/semantic_analysis_visitor.hpp b/src/visitors/semantic_analysis_visitor.hpp index 54574f584b..92cdb0e641 100644 --- a/src/visitors/semantic_analysis_visitor.hpp +++ b/src/visitors/semantic_analysis_visitor.hpp @@ -26,6 +26,7 @@ * 1. Check that a function or a procedure containing a TABLE statement contains only one argument * (mandatory in mod2c). * 2. Check that destructor blocks are only inside mod file that are point_process + * 3. Check that unit always have a name */ #include "ast/ast.hpp" #include "visitors/ast_visitor.hpp" @@ -56,6 +57,9 @@ class SemanticAnalysisVisitor: public ConstAstVisitor { /// Visit destructor and check that the file is of type POINT_PROCESS or ARTIFICIAL_CELL void visit_destructor_block(const ast::DestructorBlock& node) override; + /// Visit an unit and check that name is not empty + void visit_unit(const ast::Unit& node) override; + public: SemanticAnalysisVisitor() = default;