def parse(code)
      # Split the code into lines and parse them one by one
      @code = code.lines.to_a

      # Current line index
      @i = -1

      # Current character index
      @j = 0

      # Initialize root node
      @root = [:root, nil, {}, [], -1]

      # Get all nodes starting from the root element and return output
      # nodes and definitions
      root @root

      # Check whether nodes inside definitions have a custom definition
      @definitions.each do |name, node|
        @current_def = name
        apply_definitions node
      end
      @current_def = nil

      # Check whether nodes have a custom definition
      apply_definitions @root

      # Return root element
      [@root, @definitions]
    end
def parse(code)
      # Split the code into lines and parse them one by one
      @code = code.lines.to_a

      # Current line index
      @i = -1

      # Current character index
      @j = 0

      # Initialize root node
      @root = [:root, nil, {}, [], -1]

      # Get all nodes starting from the root element and return output
      # nodes and definitions
      root @root

      # Check whether nodes inside definitions have a custom definition
      @definitions.each do |name, node|
        @current_def = name
        apply_definitions node
      end
      @current_def = nil

      # Check whether nodes have a custom definition
      apply_definitions @root

      # Return root element
      [@root, @definitions]
    end
All node Objects (Array) must follow the next convention in order
 to make parsing faster

 [:node_type, :value, :attributes, :children, :indent]

 Initialize the parsing process by splitting the code into lines and
 instantiationg parser variables with their default values

 @param code [String] Opulent code that needs to be analyzed

 @return Nodes array