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