parser_context.h 5.88 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
        PARSER_GENERIC_JSON, // This will parse the content as generic JSON
41 42
        PARSER_DHCP6,        // This will parse the content as DHCP6 config
        // DHCP6 config subparsers
43
        SUBPARSER_DHCP6,
44 45 46 47 48 49
        SUBPARSER_INTERFACES6,
        SUBPARSER_SUBNET6,
        SUBPARSER_POOL6,
        SUBPARSER_PD_POOL,
        SUBPARSER_HOST_RESERVATION6,
        // Common DHCP subparsers
50
        SUBPARSER_OPTION_DEF,
51 52
        SUBPARSER_OPTION_DATA,
        SUBPARSER_HOOKS_LIBRARY,
53 54 55 56 57
          // SUBPARSER_CONTROL_SOCKET,
          // SUBPARSER_D2_CLIENT,
          // SUBPARSER_LEASE_EXPIRATION,
        // JSON value subparser
        SUBPARSER_JSON
58
    } ParserType;
59

60 61 62 63 64 65 66
    /// @brief Default constructor.
    Parser6Context();

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

    /// @brief JSON elements being parsed.
67
    std::vector<isc::data::ElementPtr> stack_;
68 69

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

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

75 76
    /// @brief Method called after the last tokens are scanned.
    void scanEnd();
77

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

81 82
    /// @brief Run the parser on the string specified.
    ///
83 84
    /// @param str string to be parsed
    /// @param parser_type specifies expected content (either DHCP6 or generic JSON)
85
    /// @return true on success.
86 87
    isc::data::ConstElementPtr parseString(const std::string& str,
                                           ParserType parser_type);
88

89
    /// @brief Run the parser on the file specified.
90 91
    isc::data::ConstElementPtr parseFile(const std::string& filename,
                                         ParserType parser_type);
92

93 94 95 96
    /// @brief Error handler
    ///
    /// @param loc location within the parsed file when experienced a problem.
    /// @param what string explaining the nature of the error.
97
    void error(const isc::dhcp::location& loc, const std::string& what);
98 99 100 101

    /// @brief Error handler
    ///
    /// This is a simplified error reporting tool for possible future
102
    /// cases when the Dhcp6Parser is not able to handle the packet.
103
    void error(const std::string& what);
104 105 106

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

111 112 113 114 115 116
    /// @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);

117 118 119 120 121 122 123 124 125 126 127 128
    /// @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,
129 130
        LEASE_DATABASE,
        HOSTS_DATABASE,
131 132 133 134
        MAC_SOURCES,
        HOST_RESERVATION_IDENTIFIERS,
        HOOKS_LIBRARIES,
        SUBNET6,
135
        OPTION_DEF,
136 137 138 139 140 141 142 143
        OPTION_DATA,
        CLIENT_CLASSES,
        SERVER_ID,
        DHCP_DDNS,
        /// subnet6
        POOLS,
        PD_POOLS,
        RESERVATIONS,
144 145
        /// client-classes
        CLIENT_CLASS,
146 147 148 149 150 151
        /// Logging
        LOGGERS,
        /// loggers
        OUTPUT_OPTIONS
    } ParserContext;    

152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    /// @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_;

167
    /// @brief Lexer state stack
168 169
    std::vector<struct yy_buffer_state*> states_;;

170 171 172 173 174 175
    /// @brief sFile (aka FILE)
    FILE* sfile_;

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

176 177 178 179 180 181 182 183 184 185
    /// @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();

186 187 188
    /// @brief Get the syntactix context name
    const std::string context_name();

189 190 191 192 193 194
 private:
    /// @brief Flag determining scanner debugging.
    bool trace_scanning_;

    /// @brief Flag determing parser debugging.
    bool trace_parsing_;
195 196 197

    /// @brief Syntactic context stack
    std::vector<ParserContext> cstack_;
198 199 200

    /// @brief Common part of parseXXX
    isc::data::ConstElementPtr parseCommon();
201 202 203 204 205 206
};

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

#endif