함수/명령 집합과 지정된 변수 집합이있는 수학식이 포함 된 문자열이 있으면 .NET에서 파서를 빠르게 작성하는 데 사용할 수있는 도구가 있습니까?수식 구문 분석
내가 예를 들어, 식을 분석하고 간단한 구성 요소로 나누기 간단한 파서를 구축하고 싶습니다 :
d*(abs(a-b)+sqrt(c))
이
f = abs(a-b)
및g = sqrt(c)
e = f + g
된다d*e
함수/명령 집합과 지정된 변수 집합이있는 수학식이 포함 된 문자열이 있으면 .NET에서 파서를 빠르게 작성하는 데 사용할 수있는 도구가 있습니까?수식 구문 분석
내가 예를 들어, 식을 분석하고 간단한 구성 요소로 나누기 간단한 파서를 구축하고 싶습니다 :
d*(abs(a-b)+sqrt(c))
이
f = abs(a-b)
및 g = sqrt(c)
e = f + g
된다d*e
veparser도 확인하십시오. 다음은 표현식 계산기를 작성하는 방법을 보여주는 샘플 코드입니다 (이 코드는 표현식을 구문 분석하고 출력을 직접 계산합니다). 이 샘플은 실행하는 대신 평가 트리를 저장하도록 수정할 수 있습니다.
using System;
using VeParser;
public class MathEvaluator : CharParser
{
protected override Parser GetRootParser()
{
Func<double, double, double> productFunc = (value1, value2) => value1 * value2;
Func<double, double, double> divideFunc = (value1, value2) => value1/value2;
Func<double, double, double> sumFunc = (value1, value2) => value1 + value2;
Func<double, double, double> subtractFunc = (value1, value2) => value1 - value2;
Func<double, double> negativeFunc = value => -value;
Func<double, double> posititveFunc = value => value;
var dot = token('.');
var op = token('(');
var cp = token(')');
var sumOp = create(sumFunc, token('+'));
var subtractOp = create(subtractFunc, token('-'));
var positiveOp = create(posititveFunc, token('+'));
var negativeOp = create(negativeFunc, token('-'));
var productOp = create(productFunc, token('*'));
var divideOp = create(divideFunc, token('/'));
// Numbers
var deciamlPlaceValue = 1M;
var decimalDot = run(() => { deciamlPlaceValue = 1; }, dot);
var digit = consume((n, d) => n * 10 + char.GetNumericValue(d), keep(Digit));
var decimalDigit = consume((n, d) => { deciamlPlaceValue = deciamlPlaceValue * 10; return (double)((decimal)n + ((decimal)char.GetNumericValue(d))/deciamlPlaceValue); }, keep(Digit));
var number = any(
/* float */ create(0, seq(zeroOrMore(digit), decimalDot, oneOrMore(decimalDigit))),
/* int */ create(0, oneOrMore(digit))
);
var expression = createReference();
var simpleExpression = createReference();
// Unary
var unaryOp = any(positiveOp, negativeOp);
var unaryExpression = update(d => d.action(d.value),
createNew(seq(set("action", unaryOp), set("value", expression))));
// Binary
var binaryOp = any(sumOp, subtractOp, productOp, divideOp);
var binaryExpressinoTree = update(x => x.value1, createNew(
seq(
set("value1", simpleExpression),
zeroOrMore(
update(d => { var r = base.CreateDynamicObject(); r.value1 = d.action(d.value1, d.value2); return r; },
seq(
set("action", binaryOp),
set("value2", simpleExpression))))
)));
var privilegedExpressoin = seq(op, expression, cp);
setReference(simpleExpression, any(privilegedExpressoin, unaryExpression, number));
setReference(expression, any(binaryExpressinoTree, simpleExpression));
return seq(expression, endOfFile());
}
public static object Eval(string expression)
{
MathEvaluator me = new MathEvaluator();
var result = me.Parse(expression.ToCharArray());
return result;
}
}
파서를 만들거나 해결책을 제시 하시겠습니까?
어느 쪽이든 nCalc을 확인하십시오. 문제를 해결할 필요가 있다면 바이너리를 가져 오십시오. 표현식 트리를 구문 분석하는 방법을 알아야 할 경우 원본을 가져옵니다.
Grammatica 파서 생성기에 대한 좋은 소식을 들었습니다. ANTLR도 널리 사용됩니다 (특히 Java의 경우).
BNF 문법을 정의하는 방법을 알고 있고 과거에 파서에 대해 배웠거나 파서를 작성했다고 가정합니다.
지금 당장 더 간단한 것이 필요합니다. 그러나 앞으로 몇 달 안에 귀하의 링크가 도움이 될 것입니다. 감사! – enzom83
글쎄, 나는 간단한 구문 분석기를 만들고 싶다. 효율은 중요하지 않지만 오히려 확장 성으로 새로운 명령을 쉽게 추가 할 수있다. nCalc 소스를 읽을 것이므로 새로운 것을 배울 것입니다. 감사! – enzom83