c# - 数学表达式解析器中的右结合运算符

标签 c# parsing associative infix-notation infix-operator

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

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) 就像解析器声明的那样...我错过了什么?

最佳答案

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

关于c# - 数学表达式解析器中的右结合运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31657508/

相关文章:

c++ - 有限状态机解析器

php - 哈希表和关联数组的 "key"和 "value"术语是否可以互换使用?

javascript - 从 CasperJS 中的嵌套 JavaScript 对象获取值

Javascript XML 数据到关联数组

c# - "()=>"的目的是什么

c# - Uri 为 WPF 样式 uri 抛出无效端口

c# - 在 wpf c# 中单击更改按钮图像

c# - 按属性名从列表中选择常量

java - 如何解析不规则使用引号的 CSV 文件?

c - yacc 在归约过程中丢失了值