추가 나는 간단한 수학 파서 클래스를 찾았지만 같은 논리 연산, 또는 식을 지원하지 않습니다수학 파서 - 논리, 비교 및 조건 연산자
: 여기(a > b) ? (x^2) : (a/3.56)
파서입니다 이 질문의 중간에
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Calcultra
{
class Parser
{
// The available operators for use in mathematical expressions.
private string[] _operators = { "-", "+", "/", "*", "^" };
// The mathematical operations performed by the operators.
private Func<double, double, double>[] _operations = {
(a1, a2) => a1 - a2,
(a1, a2) => a1 + a2,
(a1, a2) => a1/a2,
(a1, a2) => a1 * a2,
(a1, a2) => Math.Pow(a1, a2)
};
/**
* Parses and evaluates a mathematical expression and returns the result.
*/
public double Eval(string expression)
{
List<string> tokens = getTokens(expression);
Stack<double> operandStack = new Stack<double>();
Stack<string> operatorStack = new Stack<string>();
int tokenIndex = 0;
while (tokenIndex < tokens.Count)
{
string token = tokens[tokenIndex];
if (token == "(")
{
string subExpr = getSubExpression(tokens, ref tokenIndex);
operandStack.Push(Eval(subExpr));
continue;
}
if (token == ")")
{
throw new ArgumentException("Mis-matched parentheses in expression");
}
// If this is an operator.
if (Array.IndexOf(_operators, token) >= 0)
{
while (operatorStack.Count > 0 && Array.IndexOf(_operators, token) < Array.IndexOf(_operators, operatorStack.Peek()))
{
string op = operatorStack.Pop();
double arg2 = operandStack.Pop();
double arg1 = operandStack.Pop();
operandStack.Push(_operations[Array.IndexOf(_operators, op)](arg1, arg2));
}
operatorStack.Push(token);
}
else
{
operandStack.Push(double.Parse(token));
}
tokenIndex += 1;
}
while (operatorStack.Count > 0)
{
string op = operatorStack.Pop();
double arg2 = operandStack.Pop();
double arg1 = operandStack.Pop();
operandStack.Push(_operations[Array.IndexOf(_operators, op)](arg1, arg2));
}
return operandStack.Pop();
}
/**
* Why even write a description for this function.
*/
private string getSubExpression(List<string> tokens, ref int index)
{
StringBuilder subExpr = new StringBuilder();
int parenlevels = 1;
index += 1;
while (index < tokens.Count && parenlevels > 0)
{
string token = tokens[index];
if (tokens[index] == "(")
{
parenlevels += 1;
}
if (tokens[index] == ")")
{
parenlevels -= 1;
}
if (parenlevels > 0)
{
subExpr.Append(token);
}
index += 1;
}
if ((parenlevels > 0))
{
throw new ArgumentException("Mis-matched parentheses in expression");
}
return subExpr.ToString();
}
/**
* Tokenizes the given mathematical expression.
*/
private List<string> getTokens(string expression)
{
string operators = "()^*/+-";
List<string> tokens = new List<string>();
StringBuilder sb = new StringBuilder();
foreach (char c in expression.Replace(" ", string.Empty))
{
if (operators.IndexOf(c) >= 0)
{
if ((sb.Length > 0))
{
tokens.Add(sb.ToString());
sb.Length = 0;
}
tokens.Add(c.ToString());
}
else
{
sb.Append(c);
}
}
if ((sb.Length > 0))
{
tokens.Add(sb.ToString());
}
return tokens;
}
}
}
나는 코드를 이해하기 위해 좀 더 노력하고, 정말 파악 주요 부분은 다음과 같습니다
// If this is an operator.
if (Array.IndexOf(_operators, token) >= 0)
{
while (operatorStack.Count > 0 && Array.IndexOf(_operators, token) < Array.IndexOf(_operators, operatorStack.Peek()))
{
string op = operatorStack.Pop();
double arg2 = operandStack.Pop();
double arg1 = operandStack.Pop();
operandStack.Push(_operations[Array.IndexOf(_operators, op)](arg1, arg2));
}
operatorStack.Push(token);
}
else
{
operandStack.Push(double.Parse(token));
}
,536,
나는 연산자를 확인하고, 인수 사이의 연산을 피연산자 스택에 푸시하는 것을 본다. 여기서 내가 조건문을 검사하는 곳이라고 생각하고, ?
과 :
심볼을 확인하고, 3 개의 서브 표현식 모두를 얻고, 조건식을 평가하고 마지막 두 개의 서브 표현식 중 하나를 선택하여 피연산자 스택에 푸시해야합니다. 적어도 그것이 내가 그것을 이해하는 방법입니다. 나는 비록 비교에 관해서 해야할지 잘 모르겠다.
내가 비슷한 질문이 실현 : Adding Conditionals & Functions to a Math Parser
하지만 내 코드가 수행 뭐죠 적응하는 방법을 알아낼 수 없습니다 C# .NET을 사용하고 있습니다. 나는 당신이 나를위한 코드를 작성하는 것을 요구하지는 않는다. (많은 xP를 불평하지는 않을 것이지만) 나는 시작점이 정말로 필요하다. 이 작업을 수행하기 위해 수행해야 할 단계는 무엇입니까?
대신 기본 컴파일러를 사용할 수 있습니다. [CodeDOM] (http://msdn.microsoft.com/en-us/library/650ax5cx (v = vs.110) .aspx) – Dmitry