3

最后,来自这个问题,问题仍然存在,这个子解析器......

private static void Factor(Scanner scanner, ref TermNode currentTree, ref Token currentToken)
{
    Exponent(scanner, ref currentTree, ref currentToken);

    while (currentToken is OperatorToken && ((OperatorToken)currentToken).OperatorChar == '^') // So long as the token is ^
    {
        TermNode node = new TermNode(currentTree, null, currentToken);
        currentTree = null;
        scanner.MoveNext();
        currentToken = scanner.Current;
        Exponent(scanner, ref currentTree, ref currentToken);
        node.RightChild = currentTree;
        currentTree = node;
    }
}

...没有正确处理指数运算符(“^”)。这是因为它是右结合的。上面的代码处理它就好像它是关联的。

例如:文本e^x^2被解释为(e^x)^2。但是,正确的“解释”应该是e^(x^2).

我已经尝试过这样的事情:

if (/* The current token is ^ */)
{
    TermNode node = new TermNode(tree, null, currentToken);
    tree = null;
    scanner.MoveNext();
    currentToken = scanner.Current;
    Exponent(ref tree);
    node.RightChild = tree;
    tree = node;
}
while (/* The current token is ^  */)
{
    TermNode detachedExponent = tree.RightChild;
    TermNode oldTree = tree;
    Token token = currentToken;
    tree.RightChild = null;
    tree = null;
    scanner.MoveNext();
    currentToken = scanner.Current;
    Exponent(ref tree);
    oldTree.RightChild = new TermNode(distachedExponent, tree, token);
    tree = oldTree;
}

这只适用于两个连续的“^”-表达式。不是类似的东西e^x^y^z(这e^(x^(y^z))e^((x^y)^z)解析器声称的不同......我错过了什么?

4

1 回答 1

1

当你拥有a^b并且你看到^c时,你将它注入到顶层的 RHS 中^,创建a^(b^c),并留下你自己得到的完整表达式。然后,当您看到^d时,您再次将其注入到顶层的 RHS 中^,创建a^((b^c)^d). 您不应该将其注入到顶层的 RHS 中^,而是注入到最右边/最内层的^表达式中。为此,只需在单独的变量中跟踪该表达式。然后,修改子表达式的属性,而不是修改顶级表达式的RightChild属性。

于 2015-07-27T17:38:37.743 回答