mossadal/math-parser

How to extract all variables from an expression?

Opened this issue · 0 comments

I needed something like the expression tree in math.js (https://mathjs.org/docs/expressions/expression_trees.html) to extract all variables from an expression. Like:

$formula = '(a+b)*c';
$variables = magic($formula);
print_r($variables);  // ['a','b','c']

Unfortunately, it wasn't that straightforward to implement (without getting deep into the code/lexer stuff). Like everyone in 2023 I struggled my way through AI and finally got a working VariableCollector class based on the Evaluate class.

I leave the following AI-generated answer as a starting point for someone who is looking for an approach to solve it. If there is a better way, please add it here.


Based on the provided code, you can create a VariableCollector class by extending the Evaluator class and overriding the visitVariableNode() method. This method is called when a VariableNode is visited during the traversal of the Abstract Syntax Tree (AST).

Here's what your VariableCollector class would look like:

namespace MathParser\Interpreting;

use MathParser\Parsing\Nodes\VariableNode;

class VariableCollector extends Evaluator
{
    private $variables = [];

    public function visitVariableNode(VariableNode $node)
    {
        $name = $node->getName();

        if (!in_array($name, $this->variables)) {
            $this->variables[] = $name;
        }
    }

    public function getVariables()
    {
        return $this->variables;
    }
}

In this class, the visitVariableNode method adds the variable name to the $variables array if it's not already there. The getVariables method returns the collected variables.

To use the VariableCollector class, you would do the following:

$collector = new VariableCollector();
$AST->accept($collector);

$variables = $collector->getVariables();
print_r($variables);

This will print an array of unique variable names that were found in the expression Source 2.

Please note that this example assumes that your variable names are single characters. If you use multi-character variable names, you will need to create a custom Lexer, as described in previous responses.


Source: https://www.phind.com/search?cache=xs6ryq72b7ofro516tfah9s5 -> last answer