private function parseVariable(TokenStream $tokens, AstNode &$currNode): void
    {
        if (($token = $tokens->getCurrent()) === null) {
            return;
        }

        $variableNode = new AstNode(AstNodeTypes::VARIABLE, $token->value);
        $currNode->addChild($variableNode);
        $currNode = $variableNode;
        $tokens->next();

        // Check for the beginning of a rule list
        if ($tokens->nextIfType(TokenTypes::T_PUNCTUATION, '(')) {
            // Parse all variable rules
            do {
                $this->parseVariableRule($tokens, $variableNode);
            } while ($tokens->nextIfType(TokenTypes::T_PUNCTUATION, ','));

            $tokens->expect(TokenTypes::T_PUNCTUATION, ')', 'Expected closing parenthesis after rules, got %s');
            $tokens->next();
        }

        if ($tokens->test(TokenTypes::T_VARIABLE)) {
            throw new InvalidArgumentException('Cannot have consecutive variables without a delimiter');
        }

        $currNode = $currNode->parent;
    }