解析缺少乘法符号的数学表达式

来自这个问题 ,我现在想编写一个解析器的实现。

// 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 ; 

并修改手写的递归下降parrser。

因此,您需要修改“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”,如果subparser成功则返回“true”,如果找不到它应该解析的内容则返回“false”,如果它在解析中途失败则抛出exception。

查看有组织的方法来构建实现这些想法的递归下降解析器 。