Line data Source code
1 : // Author(s): Wieger Wesselink 2 : // Copyright: see the accompanying file COPYING or copy at 3 : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. 6 : // (See accompanying file LICENSE_1_0.txt or copy at 7 : // http://www.boost.org/LICENSE_1_0.txt) 8 : // 9 : /// \file mcrl2/core/dparser.h 10 : /// \brief add your file description here. 11 : 12 : #ifndef MCRL2_CORE_DPARSER_H 13 : #define MCRL2_CORE_DPARSER_H 14 : 15 : #include <cstddef> 16 : #include <sstream> 17 : #include <string> 18 : 19 : // prototypes 20 : struct D_ParseNode; 21 : struct D_ParserTables; 22 : struct D_Parser; 23 : struct d_loc_t; 24 : typedef void (*D_SyntaxErrorFn)(struct D_Parser *); 25 : typedef struct D_ParseNode *(*D_AmbiguityFn)(struct D_Parser *, 26 : int n, struct D_ParseNode **v); 27 : 28 : 29 : 30 : namespace mcrl2 { 31 : 32 : namespace core { 33 : 34 : namespace detail 35 : { 36 : 37 : std::string add_context(const d_loc_t* loc, const std::string& message); 38 : 39 : template <class T> // note, T is only a dummy 40 : struct dparser_error_message_count 41 : { 42 : static std::size_t value; 43 : static std::size_t max_value; 44 : }; 45 : 46 : template <class T> 47 : std::size_t dparser_error_message_count<T>::value = 0; 48 : 49 : template <class T> 50 : std::size_t dparser_error_message_count<T>::max_value = 1; 51 : 52 : inline 53 3117 : void reset_dparser_error_message_count() 54 : { 55 3117 : dparser_error_message_count<std::size_t>::value = 0; 56 3117 : } 57 : 58 : inline 59 1 : void increment_dparser_error_message_count() 60 : { 61 1 : dparser_error_message_count<std::size_t>::value++; 62 1 : } 63 : 64 : inline 65 1 : std::size_t get_dparser_error_message_count() 66 : { 67 1 : return dparser_error_message_count<std::size_t>::value; 68 : } 69 : 70 : inline 71 1 : std::size_t get_dparser_max_error_message_count() 72 : { 73 1 : return dparser_error_message_count<std::size_t>::max_value; 74 : } 75 : 76 : inline 77 3117 : void set_dparser_max_error_message_count(std::size_t n) 78 : { 79 3117 : dparser_error_message_count<std::size_t>::max_value = n; 80 3117 : } 81 : 82 : } // namespace detail 83 : 84 : /// \brief Wrapper for D_ParseNode 85 : struct parse_node 86 : { 87 : D_ParseNode* node; 88 : D_Parser* parser = nullptr; 89 : 90 562621 : explicit parse_node(D_ParseNode* n, D_Parser* parser_ = nullptr) 91 562621 : : node(n), parser(parser_) 92 562621 : {} 93 : 94 : int symbol() const; 95 : int child_count() const; 96 : 97 : // 0 <= i < child_count() 98 : parse_node child(int i) const; 99 : parse_node find_in_tree(int symbol) const; 100 : std::string string() const; 101 : std::string tree() const; 102 : int column() const; 103 : int line() const; 104 : std::string pathname() const; 105 : std::string add_context(const std::string& message) const; 106 : 107 191633 : explicit operator bool() const 108 : { 109 191633 : return node != nullptr; 110 : } 111 : 112 : ~parse_node(); 113 : }; 114 : 115 : /// \brief Wrapper for D_ParserTables 116 : struct parser_table 117 : { 118 : D_ParserTables& m_table; 119 : 120 3117 : explicit parser_table(D_ParserTables& table) 121 3117 : : m_table(table) 122 3117 : { } 123 : 124 : // Prints a tree of 125 : std::string tree(const core::parse_node& node) const; 126 : 127 : // Returns the number of symbols in the table 128 : unsigned int symbol_count() const; 129 : 130 : // Returns the name of the i-th symbol 131 : std::string symbol_name(unsigned int i) const; 132 : 133 : std::string symbol_name(const parse_node& node) const; 134 : 135 : // Returns the 'start symbol' of the i-th symbol 136 : int start_symbol(unsigned int i) const; 137 : 138 : // Returns true if the i-th symbol is of type D_SYMBOL_NTERM 139 : bool is_term_symbol(unsigned int i) const; 140 : 141 : unsigned int start_symbol_index(const std::string& name) const; 142 : 143 : void print() const; 144 : }; 145 : 146 : /// \brief Wrapper for D_Parser and its corresponding D_ParserTables 147 : struct parser 148 : { 149 : parser_table m_table; 150 : D_Parser* m_parser; 151 : std::size_t m_max_error_message_count; 152 : 153 : explicit parser(D_ParserTables& tables, D_AmbiguityFn ambiguity_fn = nullptr, D_SyntaxErrorFn syntax_error_fn = nullptr, std::size_t max_error_message_count = 1); 154 : 155 : ~parser(); 156 : 157 : const parser_table& symbol_table() const; 158 : 159 : unsigned int start_symbol_index(const std::string& name) const; 160 : 161 : /// \brief Parses a string. N.B. The user is responsible for destruction of the returned 162 : /// value by calling destroy_parse_node!!! 163 : parse_node parse(const std::string& text, unsigned int start_symbol_index = 0, bool partial_parses = false); 164 : 165 : void print_symbol_table() const; 166 : 167 : std::string indent(unsigned int count) const; 168 : 169 : std::string truncate(const std::string& s, unsigned int max_size = 20) const; 170 : 171 : void print_tree(const parse_node& node, unsigned int level = 0) const; 172 : 173 : void destroy_parse_node(const parse_node& node); 174 : 175 : void custom_parse_error(const std::string& message) const; 176 : 177 : /// \brief Callback function for nodes in the parse tree 178 : void announce(D_ParseNode& node_ref); 179 : 180 0 : void print_node(std::ostream& out, const parse_node& node) const 181 : { 182 0 : out << "symbol = " << symbol_table().symbol_name(node) << std::endl 183 0 : << "string = " << node.string() << std::endl 184 0 : << "child_count = " << node.child_count(); 185 0 : for (int i = 0; i < node.child_count(); i++) 186 : { 187 0 : out << std::endl 188 0 : << "child " << i << " = " << symbol_table().symbol_name(node.child(i)) 189 0 : << " " << node.child(i).string(); 190 : } 191 0 : } 192 : 193 : std::string print_node(const parse_node& node) const 194 : { 195 : std::ostringstream out; 196 : print_node(out, node); 197 : return out.str(); 198 : } 199 : }; 200 : 201 : } // namespace core 202 : 203 : } // namespace mcrl2 204 : 205 : #endif // MCRL2_CORE_DPARSER_H