数学表达式解析器中的右结合运算符
Right associative operator in a mathematical expression parser
最后,来自 ,问题仍然存在,这个子解析器...
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
。但是,正确的 "interpretation" 应该是 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
,你把它注入顶层^
的RHS,创建a^(b^c)
,然后离开你自己与由此产生的完整表达。当您看到 ^d
时,您再次将其注入顶层 ^
的 RHS,创建 a^((b^c)^d)
。您不应该将其注入到顶级 ^
的 RHS 中,而是注入到 right/inner-most ^
表达式中。为此,只需在单独的变量中跟踪该表达式即可。然后,不修改顶级表达式的 RightChild
属性,而是修改子表达式的
最后,来自
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
。但是,正确的 "interpretation" 应该是 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
,你把它注入顶层^
的RHS,创建a^(b^c)
,然后离开你自己与由此产生的完整表达。当您看到 ^d
时,您再次将其注入顶层 ^
的 RHS,创建 a^((b^c)^d)
。您不应该将其注入到顶级 ^
的 RHS 中,而是注入到 right/inner-most ^
表达式中。为此,只需在单独的变量中跟踪该表达式即可。然后,不修改顶级表达式的 RightChild
属性,而是修改子表达式的