User Guide
main_nmodl.cpp
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 #include <fstream>
9 #include <streambuf>
10 
11 #include <CLI/CLI.hpp>
12 
13 #include "ast/ast.hpp"
14 #include "config/config.h"
15 #include "lexer/nmodl_lexer.hpp"
16 #include "parser/nmodl_driver.hpp"
17 #include "utils/logger.hpp"
18 
19 /**
20  * \file
21  *
22  * \brief Example of standalone lexer program for NMODL
23  *
24  * This example demonstrate basic usage of scanner and driver classes.
25  * We parse user provided nmodl file and print individual token with
26  * it's value and location.
27  */
28 
29 namespace nmodl {
30 
31 using parser::NmodlDriver;
32 using parser::NmodlLexer;
34 using Token = parser::NmodlParser::token;
36 
37 
38 void tokenize(const std::string& mod_text) {
39  std::istringstream in(mod_text);
40 
41  /// lexer instance use driver object for error reporting
43 
44  /// lexer instance with stream to read-in tokens
45  NmodlLexer scanner(driver, &in);
46 
47  auto get_token_type = [](TokenType token) {
48  return parser::NmodlParser::by_type(token).type_get();
49  };
50 
51  /// parse nmodl text and print token until EOF
52  while (true) {
53  SymbolType sym = scanner.next_token();
54  auto token_type = sym.type_get();
55 
56  if (token_type == get_token_type(Token::END)) {
57  break;
58  }
59 
60  /**
61  * Lexer returns different ast types base on token type. We
62  * retrieve token object from each instance and print it.
63  * Note that value is of ast type i.e. ast::Name* etc.
64  */
65  /// token with name ast class
66  if (token_type == get_token_type(Token::NAME) ||
67  token_type == get_token_type(Token::METHOD) ||
68  token_type == get_token_type(Token::SUFFIX) ||
69  token_type == get_token_type(Token::VALENCE) ||
70  token_type == get_token_type(Token::DEL) || token_type == get_token_type(Token::DEL2)) {
71  auto value = sym.value.as<ast::Name>();
72  std::cout << *(value.get_token()) << std::endl;
73  }
74  /// token with prime ast class
75  else if (token_type == get_token_type(Token::PRIME)) {
76  auto value = sym.value.as<ast::PrimeName>();
77  std::cout << *(value.get_token()) << std::endl;
78  }
79  /// token with integer ast class
80  else if (token_type == get_token_type(Token::INTEGER)) {
81  auto value = sym.value.as<ast::Integer>();
82  std::cout << *(value.get_token()) << std::endl;
83  }
84  /// token with double/float ast class
85  else if (token_type == get_token_type(Token::REAL)) {
86  auto value = sym.value.as<ast::Double>();
87  std::cout << *(value.get_token()) << std::endl;
88  }
89  /// token with string ast class
90  else if (token_type == get_token_type(Token::STRING)) {
91  auto value = sym.value.as<ast::String>();
92  std::cout << *(value.get_token()) << std::endl;
93  }
94  /// token with string data type
95  else if (token_type == get_token_type(Token::VERBATIM) ||
96  token_type == get_token_type(Token::BLOCK_COMMENT) ||
97  token_type == get_token_type(Token::LINE_PART)) {
98  auto str = sym.value.as<std::string>();
99  std::cout << str << std::endl;
100  }
101  /// all remaining tokens has ModToken* as a vaue
102  else {
103  auto token = sym.value.as<ModToken>();
104  std::cout << token << std::endl;
105  }
106  }
107 }
108 
109 } // namespace nmodl
110 
111 
112 int main(int argc, const char* argv[]) {
113  CLI::App app{fmt::format("NMODL-Lexer : Standalone Lexer for NMODL Code({})",
115 
116  std::vector<std::string> mod_files;
117  std::vector<std::string> mod_texts;
118 
119  app.add_option("file", mod_files, "One or more NMODL files")->check(CLI::ExistingFile);
120  app.add_option("--text", mod_texts, "One or more NMODL constructs as text");
121 
122  CLI11_PARSE(app, argc, argv);
123 
124  for (const auto& file: mod_files) {
125  nmodl::logger->info("Processing file : {}", file);
126  std::ifstream f(file);
127  std::string mod{std::istreambuf_iterator<char>{f}, {}};
128  nmodl::tokenize(mod);
129  }
130 
131  for (const auto& text: mod_texts) {
132  nmodl::logger->info("Processing text : {}", text);
133  nmodl::tokenize(text);
134  }
135 
136  return 0;
137 }
nmodl::TokenType
parser::NmodlParser::token_type TokenType
Definition: main_nmodl.cpp:35
nmodl::parser::NmodlDriver
Class that binds all pieces together for parsing nmodl file.
Definition: nmodl_driver.hpp:67
nmodl::Token
parser::NmodlParser::token Token
Definition: main_nmodl.cpp:34
nmodl::ast::Integer::value
int value
Value of integer.
Definition: integer.hpp:52
nmodl::ast::Double
Represents a double variable.
Definition: double.hpp:53
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::tokenize
void tokenize(const std::string &mod_text)
Definition: main_nmodl.cpp:38
nmodl::ast::Integer
Represents an integer variable.
Definition: integer.hpp:49
nmodl::logger
logger_type logger
Definition: logger.cpp:34
nmodl::ast::PrimeName::value
std::shared_ptr< String > value
Name of prime variable.
Definition: prime_name.hpp:51
nmodl_lexer.hpp
nmodl::ast::String::value
std::string value
Value of string.
Definition: string.hpp:55
driver
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
nmodl::parser::NmodlLexer
Represent Lexer/Scanner class for NMODL language parsing.
Definition: nmodl_lexer.hpp:60
nmodl::ast::PrimeName
Represents a prime variable (for ODE)
Definition: prime_name.hpp:48
nmodl::Version::to_string
static std::string to_string()
return version string (version + git id) as a string
Definition: config.h:39
ast.hpp
Auto generated AST classes declaration.
nmodl::parser::NmodlLexer::next_token
virtual NmodlParser::symbol_type next_token()
Function for lexer to scan token (replacement for yylex())
main
int main(int argc, const char *argv[])
Definition: main_nmodl.cpp:112
logger.hpp
Implement logger based on spdlog library.
nmodl::SymbolType
parser::NmodlParser::symbol_type SymbolType
Definition: main_nmodl.cpp:33
nmodl::ast::Double::value
std::string value
Value of double.
Definition: double.hpp:56
nmodl_driver.hpp
symbol_type
void symbol_type(const std::string &name, T &value)
Definition: modtoken.cpp:32
config.h
Version information and units file path.
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::token_type
TokenType token_type(const std::string &name)
Return token type for given token name.
Definition: token_mapping.cpp:284
nmodl::ast::Name::value
std::shared_ptr< String > value
Value of name.
Definition: name.hpp:47
nmodl::ModToken
Represent token returned by scanner.
Definition: modtoken.hpp:50
nmodl::ast::String
Represents a string.
Definition: string.hpp:52