次の非常に便利なステップは、解析ツリーを構築することです。

中置パーサーを作成することで、これらのいずれかを作成できます。これを行うには、単純な再帰降下パーサーを作成するか、大きな銃を持ち込んでパーサー ジェネレーターを使用します。どちらの場合でも、形式的な文法を構築するのに役立ちます。
expression: additive
additive: multiplicative ([+-] multiplicative)*
multiplicative: primary ('*' primary)*
primary: variable
| number
| '(' expression ')'
この文法は2x
構文を処理しませんが、簡単に追加できるはずです。
文法規則での再帰の巧妙な使用に注目してください。 primary
変数、数値、および括弧で囲まれた式のみをキャプチャし、演算子に遭遇すると停止します。 記号で区切られたmultiplicative
1 つ以上の式を解析しますが、または記号に遭遇すると停止します。 とで区切られた1 つ以上の式を解析しますが、 に遭遇すると停止します。したがって、再帰スキームによって演算子の優先順位が決まります。primary
*
+
-
additive
multiplicative
+
-
)
以下で行ったように、手動で予測パーサーを実装することはそれほど難しくありません( ideone.com の完全な例を参照してください)。
function parse()
{
global $tokens;
reset($tokens);
$ret = parseExpression();
if (current($tokens) !== FALSE)
die("Stray token at end of expression\n");
return $ret;
}
function popToken()
{
global $tokens;
$ret = current($tokens);
if ($ret !== FALSE)
next($tokens);
return $ret;
}
function parseExpression()
{
return parseAdditive();
}
function parseAdditive()
{
global $tokens;
$expr = parseMultiplicative();
for (;;) {
$next = current($tokens);
if ($next !== FALSE && $next->type == "operator" &&
($next->op == "+" || $next->op == "-"))
{
next($tokens);
$left = $expr;
$right = parseMultiplicative();
$expr = mkOperatorExpr($next->op, $left, $right);
} else {
return $expr;
}
}
}
function parseMultiplicative()
{
global $tokens;
$expr = parsePrimary();
for (;;) {
$next = current($tokens);
if ($next !== FALSE && $next->type == "operator" &&
$next->op == "*")
{
next($tokens);
$left = $expr;
$right = parsePrimary();
$expr = mkOperatorExpr($next->op, $left, $right);
} else {
return $expr;
}
}
}
function parsePrimary()
{
$tok = popToken();
if ($tok === FALSE)
die("Unexpected end of token list\n");
if ($tok->type == "variable")
return mkVariableExpr($tok->name);
if ($tok->type == "number")
return mkNumberExpr($tok->value);
if ($tok->type == "operator" && $tok->op == "(") {
$ret = parseExpression();
$tok = popToken();
if ($tok->type == "operator" && $tok->op == ")")
return $ret;
else
die("Missing end parenthesis\n");
}
die("Unexpected $tok->type token\n");
}
さて、これで素敵な構文木とそれに付随するきれいな画像ができました。それで?あなたの目標 (今のところ) は、単純に項を組み合わせてフォームの結果を得ることかもしれません:
n1*a + n2*b + n3*c + n4*d + ...
その部分はお任せします。構文解析木を使用すると、物事がより簡単になります。