gpt4 book ai didi

c# - 解析缺少乘号的数学表达式

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:28 25 4
gpt4 key购买 nike

来自this question ,我现在想编写解析器的实现。

// Handles * and / 
private static void Summand(Scanner scanner, ref TermNode currentTree, ref Token currentToken)
{
Factor(scanner, ref currentTree, ref currentToken);

while (currentToken is OperatorToken && _multiplicationOperators.Contains(((OperatorToken)currentToken).OperatorChar)) // So long as the token is * or /
{
TermNode node = new TermNode(currentTree, null, currentToken);
currentTree = null;
scanner.MoveNext();
currentToken = scanner.Current;
Factor(scanner, ref currentTree, ref currentToken); // Handles ^
node.RightChild = currentTree;
currentTree = node;
}
}

// I think this one might be wrong...
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;
}
}

private static void Exponent(Scanner scanner, ref TermNode currentTree, ref Token currentToken)
{
if (currentToken is BracketToken)
{
BracketToken bracketToken = (BracketToken)currentToken;
if (bracketToken.IsOpening)
{
scanner.MoveNext();
currentToken = scanner.Current;
Term(scanner, ref currentTree, ref currentToken);
if (currentToken is BracketToken && !((BracketToken)currentToken).IsOpening)
{
scanner.MoveNext();
currentToken = scanner.Current;
}
else
throw new ParseException("Unbalanced brackets!");
}
}
else
{
node = new TermNode(null, null, currentToken);

if (currentToken is OperatorToken)
{
currentTree = null;
scanner.MoveNext();
currentToken = scanner.Current;
Exponent(scanner, ref currentTree, ref currentToken, false);
node.RightChild = currentTree;
currentTree = node;
}
else if (currentToken is VariableToken || currentToken is ConstantToken)
{
currentTree = node;
scanner.MoveNext();
currentToken = scanner.Current;
}
else if (currentToken is FunctionToken)
{
currentTree = null;
scanner.MoveNext();
currentToken = scanner.Current;
Exponent(scanner, ref currentTree, ref currentToken, false);
node.RightChild = currentTree;
currentTree = node;
}
}

}

现在我想知道我将如何更改此方法以允许诸如 3(a+b) 之类的表达式...以及此方法和函数是否是正确的方法来实现这一目标。

最佳答案

这只是一个修改您的(未声明的)语法的案例:

Summand = Factor | Summand "*" Factor | Summand "/" Factor ;

Summand = Factor | Summand Factor | Summand "/" Factor ; 

并修改手写的递归下降解析器。

因此您需要修改“Summand”,使其不检查显式乘法运算符,而是继续检查除法运算符。

所以代码看起来像这样:

private static void Summand(Scanner scanner, ref TermNode currentTree, ref Token currentToken)
{
Factor(scanner, ref currentTree, ref currentToken);
while (true) // repeat for each implicit multiply or explicit divide
{
if (currentToken is OperatorToken && ((OperatorToken)currentToken).OperatorChar == '/')
{ // handle divide
TermNode node = new TermNode(currentTree, null, currentToken);
currentTree = null;
scanner.MoveNext();
currentToken = scanner.Current;
Factor(scanner, ref currentTree, ref currentToken);
node.RightChild = currentTree;
currentTree = node;
}
else { // handle possible multiplication
TermNode multiplicand = node ;
Factor(scanner, ref currentTree, ref currentToken)
if (Factor_failed) return; // no implicit product
currentTree = new TermNode(multiplicand, currentTree, maketoken("*"));

}
} //while
} // Summand

您的解析器缺少的是来自每个子解析器的信号,该信号指示子解析器无法找到请求解析的内容。 (你需要实现“Factor_failed”的想法。)这不同于它发现的证据表明它被请求解析的东西在那里,但不是有效的语法。我建议您将每个返回类型更改为“bool”,如果子解析器成功则返回“true”,如果找不到它应该解析的证据则返回“false”,如果解析到一半失败则抛出异常。

查看 organized way to build recursive descent parsers实现了这些想法。

关于c# - 解析缺少乘号的数学表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31631677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com