User Guide
semantic_analysis_visitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief \copybrief nmodl::visitor::SemanticAnalysisVisitor
13  */
14 
15 /**
16  * \addtogroup visitor_classes
17  * \{
18  */
19 
20 /**
21  * \class SemanticAnalysisVisitor
22  * \brief %Visitor to check some semantic rules on the ast
23  *
24  * Current checks:
25  *
26  * 1. Check that a function or a procedure containing a TABLE statement contains only one argument
27  * (mandatory in mod2c).
28  * 2. Check that destructor blocks are only inside mod file that are point_process.
29  * 3. A TABLE statement in functions cannot have name list, and should have one in procedures.
30  * 4. Check if ion variables from a `USEION` statement are not declared in `CONSTANT` block.
31  * 5. Check if an independent variable is not 't'.
32  * 6. Check that mutex are not badly use
33  * 7. Check than function table got at least one argument.
34  * 8. Check that at most one derivative block is present.
35  * 9. Check that RANDOM variable is mentioned only as first arg in random function.
36  */
37 #include "ast/ast.hpp"
38 #include "visitors/ast_visitor.hpp"
39 
40 namespace nmodl {
41 namespace visitor {
42 
44  private:
45  // if semantic analysis check has failed
46  bool check_fail = false;
47  // symbol table for the program
49  /// true if accelerator backend is used for code generation
50  bool accel_backend = false;
51  /// true if the procedure or the function contains only one argument
53  /// true if we are in a procedure block
54  bool in_procedure = false;
55  /// true if we are in a function block
56  bool in_function = false;
57  /// true if the mod file is of type point process
58  bool is_point_process = false;
59  /// true if we are inside a mutex locked part
60  bool in_mutex = false;
61 
62  /// Check number of DERIVATIVE blocks
63  void visit_program(const ast::Program& node) override;
64 
65  /// Store if we are in a procedure and if the arity of this is 1
66  void visit_procedure_block(const ast::ProcedureBlock& node) override;
67 
68  /// Store if we are in a function and if the arity of this is 1
69  void visit_function_block(const ast::FunctionBlock& node) override;
70 
71  /// Visit a table statement and check that the arity of the block were 1
72  void visit_table_statement(const ast::TableStatement& node) override;
73 
74  /// Visit destructor and check that the file is of type POINT_PROCESS or ARTIFICIAL_CELL
75  void visit_destructor_block(const ast::DestructorBlock& node) override;
76 
77  /// Visit independent block and check if one of the variable is not t
78  void visit_independent_block(const ast::IndependentBlock& node) override;
79 
80  /// Visit function table to check that number of args > 0
81  void visit_function_table_block(const ast::FunctionTableBlock& node) override;
82 
83  /// Look if protect is inside a locked block
84  void visit_protect_statement(const ast::ProtectStatement& node) override;
85 
86  /// Look if MUTEXLOCK is inside a locked block
87  void visit_mutex_lock(const ast::MutexLock& node) override;
88 
89  /// Look if MUTEXUNLOCK is outside a locked block
90  void visit_mutex_unlock(const ast::MutexUnlock& node) override;
91 
92  /// Only use of random_var is as first arg in random function.
93  void visit_name(const ast::Name& node) override;
94 
95  /// random function first arg must be random_var
96  void visit_function_call(const ast::FunctionCall& node) override;
97 
98  public:
101  bool check(const ast::Program& node);
102 };
103 
104 /** \} */ // end of visitor_classes
105 
106 } // namespace visitor
107 } // namespace nmodl
nmodl::visitor::SemanticAnalysisVisitor::SemanticAnalysisVisitor
SemanticAnalysisVisitor(bool accel_backend=false)
Definition: semantic_analysis_visitor.hpp:99
nmodl::visitor::ConstAstVisitor
Concrete constant visitor for all AST classes.
Definition: ast_visitor.hpp:166
nmodl::ast::FunctionBlock
TODO.
Definition: function_block.hpp:39
nmodl::visitor::SemanticAnalysisVisitor::in_mutex
bool in_mutex
true if we are inside a mutex locked part
Definition: semantic_analysis_visitor.hpp:60
nmodl::visitor::SemanticAnalysisVisitor::in_function
bool in_function
true if we are in a function block
Definition: semantic_analysis_visitor.hpp:56
nmodl::ast::FunctionTableBlock
TODO.
Definition: function_table_block.hpp:39
nmodl::visitor::SemanticAnalysisVisitor::accel_backend
bool accel_backend
true if accelerator backend is used for code generation
Definition: semantic_analysis_visitor.hpp:50
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::visitor::SemanticAnalysisVisitor::visit_procedure_block
void visit_procedure_block(const ast::ProcedureBlock &node) override
Store if we are in a procedure and if the arity of this is 1.
Definition: semantic_analysis_visitor.cpp:77
nmodl::ast::MutexLock
Represent MUTEXLOCK statement in NMODL.
Definition: mutex_lock.hpp:38
nmodl::ast::TableStatement
Represents TABLE statement in NMODL.
Definition: table_statement.hpp:39
nmodl::visitor::SemanticAnalysisVisitor::visit_name
void visit_name(const ast::Name &node) override
Only use of random_var is as first arg in random function.
Definition: semantic_analysis_visitor.cpp:95
nmodl::visitor::SemanticAnalysisVisitor::visit_table_statement
void visit_table_statement(const ast::TableStatement &node) override
Visit a table statement and check that the arity of the block were 1.
Definition: semantic_analysis_visitor.cpp:181
nmodl::visitor::SemanticAnalysisVisitor::program_symtab
symtab::SymbolTable * program_symtab
Definition: semantic_analysis_visitor.hpp:48
nmodl::visitor::SemanticAnalysisVisitor::visit_function_call
void visit_function_call(const ast::FunctionCall &node) override
random function first arg must be random_var
Definition: semantic_analysis_visitor.cpp:151
nmodl::visitor::SemanticAnalysisVisitor::check
bool check(const ast::Program &node)
Definition: semantic_analysis_visitor.cpp:27
nmodl::ast::FunctionCall
TODO.
Definition: function_call.hpp:38
nmodl::visitor::SemanticAnalysisVisitor::in_procedure
bool in_procedure
true if we are in a procedure block
Definition: semantic_analysis_visitor.hpp:54
nmodl::ast::DestructorBlock
Represents a DESTRUCTOR block in the NMODL.
Definition: destructor_block.hpp:53
nmodl::ast::ProtectStatement
TODO.
Definition: protect_statement.hpp:38
nmodl::visitor::SemanticAnalysisVisitor::visit_function_block
void visit_function_block(const ast::FunctionBlock &node) override
Store if we are in a function and if the arity of this is 1.
Definition: semantic_analysis_visitor.cpp:86
nmodl::ast::MutexUnlock
Represent MUTEXUNLOCK statement in NMODL.
Definition: mutex_unlock.hpp:38
nmodl::visitor::SemanticAnalysisVisitor::visit_independent_block
void visit_independent_block(const ast::IndependentBlock &node) override
Visit independent block and check if one of the variable is not t.
Definition: semantic_analysis_visitor.cpp:215
nmodl::visitor::SemanticAnalysisVisitor::check_fail
bool check_fail
Definition: semantic_analysis_visitor.hpp:46
nmodl::visitor::SemanticAnalysisVisitor::visit_mutex_unlock
void visit_mutex_unlock(const ast::MutexUnlock &node) override
Look if MUTEXUNLOCK is outside a locked block.
Definition: semantic_analysis_visitor.cpp:262
nmodl::visitor::SemanticAnalysisVisitor::visit_program
void visit_program(const ast::Program &node) override
Check number of DERIVATIVE blocks.
Definition: semantic_analysis_visitor.cpp:66
nmodl::symtab::SymbolTable
Represent symbol table for a NMODL block.
Definition: symbol_table.hpp:57
nmodl::visitor::SemanticAnalysisVisitor::visit_protect_statement
void visit_protect_statement(const ast::ProtectStatement &node) override
Look if protect is inside a locked block.
Definition: semantic_analysis_visitor.cpp:239
ast.hpp
Auto generated AST classes declaration.
nmodl::visitor::SemanticAnalysisVisitor::visit_function_table_block
void visit_function_table_block(const ast::FunctionTableBlock &node) override
Visit function table to check that number of args > 0.
Definition: semantic_analysis_visitor.cpp:228
nmodl::visitor::SemanticAnalysisVisitor
Definition: semantic_analysis_visitor.hpp:43
nmodl::ast::ProcedureBlock
TODO.
Definition: procedure_block.hpp:39
nmodl::visitor::SemanticAnalysisVisitor::one_arg_in_procedure_function
bool one_arg_in_procedure_function
true if the procedure or the function contains only one argument
Definition: semantic_analysis_visitor.hpp:52
nmodl::visitor::SemanticAnalysisVisitor::is_point_process
bool is_point_process
true if the mod file is of type point process
Definition: semantic_analysis_visitor.hpp:58
nmodl::ast::IndependentBlock
Represents a INDEPENDENT block in the NMODL.
Definition: independent_block.hpp:46
nmodl::visitor::SemanticAnalysisVisitor::visit_destructor_block
void visit_destructor_block(const ast::DestructorBlock &node) override
Visit destructor and check that the file is of type POINT_PROCESS or ARTIFICIAL_CELL.
Definition: semantic_analysis_visitor.cpp:204
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::visitor::SemanticAnalysisVisitor::visit_mutex_lock
void visit_mutex_lock(const ast::MutexLock &node) override
Look if MUTEXLOCK is inside a locked block.
Definition: semantic_analysis_visitor.cpp:250
ast_visitor.hpp
Concrete visitor for all AST classes.