diff --git a/json_parser_utils.cpp b/json_parser_utils.cpp
index be34323..25b2e9a 100644
--- a/json_parser_utils.cpp
+++ b/json_parser_utils.cpp
@@ -16,18 +16,217 @@
 
 #include "json_parser_utils.hpp"
 
+#include <charconv>
+#include <regex>
+
 namespace phosphor::power::json_parser_utils
 {
 
-std::vector<uint8_t> parseHexByteArray(const nlohmann::json& element)
+const std::map<std::string, std::string> NO_VARIABLES{};
+
+static std::regex VARIABLE_REGEX{R"(\$\{([A-Za-z0-9_]+)\})"};
+
+uint8_t parseBitPosition(const nlohmann::json& element,
+                         const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if ((value < 0) || (value > 7))
+    {
+        throw std::invalid_argument{"Element is not a bit position"};
+    }
+    return static_cast<uint8_t>(value);
+}
+
+uint8_t parseBitValue(const nlohmann::json& element,
+                      const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if ((value < 0) || (value > 1))
+    {
+        throw std::invalid_argument{"Element is not a bit value"};
+    }
+    return static_cast<uint8_t>(value);
+}
+
+bool parseBoolean(const nlohmann::json& element,
+                  const std::map<std::string, std::string>& variables)
+{
+    if (element.is_boolean())
+    {
+        return element.get<bool>();
+    }
+
+    if (element.is_string() && !variables.empty())
+    {
+        std::string value = parseString(element, true, variables);
+        if (value == "true")
+        {
+            return true;
+        }
+        else if (value == "false")
+        {
+            return false;
+        }
+    }
+
+    throw std::invalid_argument{"Element is not a boolean"};
+}
+
+double parseDouble(const nlohmann::json& element,
+                   const std::map<std::string, std::string>& variables)
+{
+    if (element.is_number())
+    {
+        return element.get<double>();
+    }
+
+    if (element.is_string() && !variables.empty())
+    {
+        std::string strValue = parseString(element, true, variables);
+        const char* first = strValue.data();
+        const char* last = strValue.data() + strValue.size();
+        double value;
+        auto [ptr, ec] = std::from_chars(first, last, value);
+        if ((ptr == last) && (ec == std::errc()))
+        {
+            return value;
+        }
+    }
+
+    throw std::invalid_argument{"Element is not a double"};
+}
+
+uint8_t parseHexByte(const nlohmann::json& element,
+                     const std::map<std::string, std::string>& variables)
+{
+    std::string value = parseString(element, true, variables);
+    bool isHex = (value.compare(0, 2, "0x") == 0) && (value.size() > 2) &&
+                 (value.size() < 5) &&
+                 (value.find_first_not_of("0123456789abcdefABCDEF", 2) ==
+                  std::string::npos);
+    if (!isHex)
+    {
+        throw std::invalid_argument{"Element is not hexadecimal string"};
+    }
+    return static_cast<uint8_t>(std::stoul(value, nullptr, 0));
+}
+
+std::vector<uint8_t> parseHexByteArray(
+    const nlohmann::json& element,
+    const std::map<std::string, std::string>& variables)
 {
     verifyIsArray(element);
     std::vector<uint8_t> values;
     for (auto& valueElement : element)
     {
-        values.emplace_back(parseHexByte(valueElement));
+        values.emplace_back(parseHexByte(valueElement, variables));
     }
     return values;
 }
 
+int8_t parseInt8(const nlohmann::json& element,
+                 const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if ((value < INT8_MIN) || (value > INT8_MAX))
+    {
+        throw std::invalid_argument{"Element is not an 8-bit signed integer"};
+    }
+    return static_cast<int8_t>(value);
+}
+
+int parseInteger(const nlohmann::json& element,
+                 const std::map<std::string, std::string>& variables)
+{
+    if (element.is_number_integer())
+    {
+        return element.get<int>();
+    }
+
+    if (element.is_string() && !variables.empty())
+    {
+        std::string strValue = parseString(element, true, variables);
+        const char* first = strValue.data();
+        const char* last = strValue.data() + strValue.size();
+        int value;
+        auto [ptr, ec] = std::from_chars(first, last, value);
+        if ((ptr == last) && (ec == std::errc()))
+        {
+            return value;
+        }
+    }
+
+    throw std::invalid_argument{"Element is not an integer"};
+}
+
+std::string parseString(const nlohmann::json& element, bool isEmptyValid,
+                        const std::map<std::string, std::string>& variables)
+{
+    if (!element.is_string())
+    {
+        throw std::invalid_argument{"Element is not a string"};
+    }
+    std::string value = element.get<std::string>();
+    internal::expandVariables(value, variables);
+    if (value.empty() && !isEmptyValid)
+    {
+        throw std::invalid_argument{"Element contains an empty string"};
+    }
+    return value;
+}
+
+uint8_t parseUint8(const nlohmann::json& element,
+                   const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if ((value < 0) || (value > UINT8_MAX))
+    {
+        throw std::invalid_argument{"Element is not an 8-bit unsigned integer"};
+    }
+    return static_cast<uint8_t>(value);
+}
+
+unsigned int parseUnsignedInteger(
+    const nlohmann::json& element,
+    const std::map<std::string, std::string>& variables)
+{
+    int value = parseInteger(element, variables);
+    if (value < 0)
+    {
+        throw std::invalid_argument{"Element is not an unsigned integer"};
+    }
+    return static_cast<unsigned int>(value);
+}
+
+namespace internal
+{
+
+void expandVariables(std::string& value,
+                     const std::map<std::string, std::string>& variables)
+{
+    if (variables.empty())
+    {
+        return;
+    }
+
+    std::smatch results;
+    while (std::regex_search(value, results, VARIABLE_REGEX))
+    {
+        if (results.size() != 2)
+        {
+            throw std::runtime_error{
+                "Unexpected regular expression match result while parsing string"};
+        }
+        const std::string& variable = results[1];
+        auto it = variables.find(variable);
+        if (it == variables.end())
+        {
+            throw std::invalid_argument{"Undefined variable: " + variable};
+        }
+        value.replace(results.position(0), results.length(0), it->second);
+    }
+}
+
+} // namespace internal
+
 } // namespace phosphor::power::json_parser_utils
