Correct associative operator in parser parser expression
Finally, based on this question , the problem remains that this sub-parameter ...
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;
}
}
... does not handle the exponential operator ("^") correctly. This is due to the fact that it is correct associative. The above code treats it as if it were still associative.
For example: The text is e^x^2
interpreted as (e^x)^2
. However, the correct "interpretation" will be e^(x^2)
.
I've already tried something like this:
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;
}
This only works for two consecutive "^" expressions. Not something like e^x^y^z
(which would be e^(x^(y^z))
, not e^((x^y)^z)
like parser assertions ... What am I missing?
source to share
When you have a^b
, and you see ^c
, you enter it into the top-level RHS ^
, creating a^(b^c)
and leaving yourself as a result of full expression. When you see it ^d
, you re-enter it into the top-level RHS by ^
creating a^((b^c)^d)
. You don't have to type it in the top level RHS ^
, but in a correct / internal expression ^
. To do this, just keep track of this expression in a separate variable. Then, instead of changing the top-level expression property RightChild
, change the child.
source to share