parser_context.h 5.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef PARSER_CONTEXT_H
#define PARSER_CONTEXT_H
#include <string>
#include <map>
#include <vector>
#include <dhcp6/dhcp6_parser.h>
#include <dhcp6/parser_context_decl.h>
#include <exceptions/exceptions.h>

// Tell Flex the lexer's prototype ...
17
#define YY_DECL isc::dhcp::Dhcp6Parser::symbol_type parser6_lex (Parser6Context& driver)
18 19 20 21 22 23 24

// ... and declare it for the parser's sake.
YY_DECL;

namespace isc {
namespace dhcp {

25 26
/// @brief Evaluation error exception raised when trying to parse.
class Dhcp6ParseError : public isc::Exception {
27
public:
28
    Dhcp6ParseError(const char* file, size_t line, const char* what) :
29 30 31 32 33 34 35 36
        isc::Exception(file, line, what) { };
};


/// @brief Evaluation context, an interface to the expression evaluation.
class Parser6Context
{
public:
37

38 39
    /// @brief Defines currently support the content supported
    typedef enum {
40 41
        PARSER_GENERIC_JSON, // This will parse the content as generic JSON
        PARSER_DHCP6 // This will parse the content as DHCP6 config
42
    } ParserType;
43

44 45 46 47 48 49 50
    /// @brief Default constructor.
    Parser6Context();

    /// @brief destructor
    virtual ~Parser6Context();

    /// @brief JSON elements being parsed.
51
    std::vector<isc::data::ElementPtr> stack_;
52 53

    /// @brief Method called before scanning starts on a string.
54
    void scanStringBegin(const std::string& str, ParserType type);
55

56
    /// @brief Method called before scanning starts on a file.
Francis Dupont's avatar
Francis Dupont committed
57
    void scanFileBegin(FILE * f, const std::string& filename, ParserType type);
58

59 60
    /// @brief Method called after the last tokens are scanned.
    void scanEnd();
61

Francis Dupont's avatar
Francis Dupont committed
62
    /// @brief Divert input to an include file.
63
    void includeFile(const std::string& filename);
Francis Dupont's avatar
Francis Dupont committed
64

65 66
    /// @brief Run the parser on the string specified.
    ///
67 68
    /// @param str string to be parsed
    /// @param parser_type specifies expected content (either DHCP6 or generic JSON)
69
    /// @return true on success.
70 71
    isc::data::ConstElementPtr parseString(const std::string& str,
                                           ParserType parser_type);
72

73
    /// @brief Run the parser on the file specified.
74 75
    isc::data::ConstElementPtr parseFile(const std::string& filename,
                                         ParserType parser_type);
76

77 78 79 80
    /// @brief Error handler
    ///
    /// @param loc location within the parsed file when experienced a problem.
    /// @param what string explaining the nature of the error.
81
    void error(const isc::dhcp::location& loc, const std::string& what);
82 83 84 85

    /// @brief Error handler
    ///
    /// This is a simplified error reporting tool for possible future
86
    /// cases when the Dhcp6Parser is not able to handle the packet.
87
    void error(const std::string& what);
88 89 90

    /// @brief Fatal error handler
    ///
91 92
    /// This is for should not happen but fatal errors.
    /// Used by YY_FATAL_ERROR macro so required to be static.
93 94
    static void fatal(const std::string& what);

95 96 97 98 99 100
    /// @brief Convert position
    ///
    /// Convert a bison location into an element position
    /// (take the begin, the end is lost)
    isc::data::Element::Position loc2pos(isc::dhcp::location& loc);

101 102 103 104 105 106 107 108 109 110 111 112
    /// @brief Defines syntactic contexts for lexical tie-ins
    typedef enum {
        /// at toplevel
        NO_KEYWORD,
        CONFIG,
        /// in config
        DHCP6,
        // not yet DHCP4,
        // not yet DHCP_DDNS,
        LOGGING,
        /// Dhcp6
        INTERFACES_CONFIG,
113 114
        LEASE_DATABASE,
        HOSTS_DATABASE,
115 116 117 118 119 120 121 122 123 124 125 126
        MAC_SOURCES,
        HOST_RESERVATION_IDENTIFIERS,
        HOOKS_LIBRARIES,
        SUBNET6,
        OPTION_DATA,
        CLIENT_CLASSES,
        SERVER_ID,
        DHCP_DDNS,
        /// subnet6
        POOLS,
        PD_POOLS,
        RESERVATIONS,
127 128
        /// client-classes
        CLIENT_CLASS,
129 130 131 132 133 134
        /// Logging
        LOGGERS,
        /// loggers
        OUTPUT_OPTIONS
    } ParserContext;    

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
    /// @brief File name
    std::string file_;

    /// @brief File name stack
    std::vector<std::string> files_;

    /// @brief Location of the current token
    ///
    /// The lexer will keep updating it. This variable will be useful
    /// for logging errors.
    isc::dhcp::location loc_;

    /// @brief Location stack
    std::vector<isc::dhcp::location> locs_;

150
    /// @brief Lexer state stack
151 152
    std::vector<struct yy_buffer_state*> states_;;

153 154 155 156 157 158
    /// @brief sFile (aka FILE)
    FILE* sfile_;

    /// @brief sFile (aka FILE) stack
    std::vector<FILE*> sfiles_;

159 160 161 162 163 164 165 166 167 168
    /// @brief Current syntactic context
    ParserContext ctx_;

    /// @brief Enter a new syntactic context
    void enter(const ParserContext& ctx);

    /// @brief Leave a syntactic context
    /// @throw isc::Unexpected if unbalanced
    void leave();

169 170 171
    /// @brief Get the syntactix context name
    const std::string context_name();

172 173 174 175 176 177
 private:
    /// @brief Flag determining scanner debugging.
    bool trace_scanning_;

    /// @brief Flag determing parser debugging.
    bool trace_parsing_;
178 179 180

    /// @brief Syntactic context stack
    std::vector<ParserContext> cstack_;
181 182 183

    /// @brief Common part of parseXXX
    isc::data::ConstElementPtr parseCommon();
184 185 186 187 188 189
};

}; // end of isc::eval namespace
}; // end of isc namespace

#endif