2011-02-12 3 views
1

우리가 형식으로 반 복잡한 표현 :
"25 + [변수 1]> [Variable2에]" 식 계산기/파이썬/루비

우리는 표현을 구문 분석하고를 사용하는 식 계산기가 필요합니다 콜백을 사용하여 변수 값을 요청하고 표현식의 전체 결과를 확인하십시오. 수천 개의 변수가 있기 때문에 콜백이어야합니다.

우리는 일반적인 수학 연산자가 필요하지만 "if"등과 같은 것도 필요합니다. 언어가 풍부할수록 좋습니다.

우리가 원하는 언어를 사용할 수 있습니다. 누구든지 어떤 제안이 있습니까?

+0

호스트 언어 란 무엇입니까? – dtb

+3

언어에 대한 정확한 사양이 없으면 언어 구현에 대한 일반적인 리소스를 제안 할 수 있습니다. 그리고 심지어 그것이 주어 지더라도, 우리는 컴파일러 건설 코스이기 때문에 도움이되는 소스를 알려줄 것입니다. – delnan

+0

'준결승'이 무슨 뜻입니까? 질문의 실제 상황은 무엇입니까? 아니면 숙제일까요? 그렇다면 적절한 방식으로 질문에 태그를 답니다. 감사합니다 – eat

답변

2

NCalc을 확인하십시오. 그것은. NET이고 귀하의 요구 사항을 지원해야합니다.

1

순수 표현식 평가자는 실제로 작성하기가 쉽습니다.

12 개의 언어에서 표현식 평가 기가 표시되는 SO 대답을 참조하십시오. 당신은이 중 하나를 적용 할 수 있어야한다 :

Code Golf: Mathematical expression evaluator (that respects PEMDAS)

편집 :이 분명하지 않았고,이 솔루션을 검토 박았 구만 누구든지. 예, 골프 규칙 (일반적으로 "가장 작은")을 충족시키기 위해 꽉 쥐어 짜낸 무리가 있지만 대부분은 일반 텍스트 버전의 알고리즘으로 매우 명확하게 설명됩니다.

+0

변수에 대한'if' 구조체 나 콜백과 같은 것들에 대해서는 확장 성이별로 없습니다. – Gabe

+0

동의합니다. 사람들은 처음에는저기서 많은 솔루션을 골프하려고 시도조차하지 않았습니다. –

+0

수정하기가 그리 어렵지 않습니다. "if (a, b, c)"는 구문 분석해야하는 구문 일뿐입니다. 파싱은 제공 솔루션의 일부였습니다. 변수에 대한 콜백은 변수가 감지되면 코드에 콜백을 추가해야한다는 것을 의미합니다. 당신은 분명히 이것들을 약간 커스터마이징해야한다. 요점은 그들이 매우 간단하다는 것입니다. 정확히 원하는 것을 수행하는 서브 루틴 패키지를 찾으려고 시도하는 것은별로 의미가 없습니다. 당신이 원하는 것을 정확히 코딩 할 수 있습니다. 이들은 일반적으로 100-200 라인입니다! OP가 이것들을 코딩 할 능력이 없다면, 패키지는 그를 도울 수 없을 것이다. –

0

음 ... 언어가 필요합니다. C#, VB.Net, IronPython, IronRuby 등이 있습니다.

단순한 정규식을 사용하여 열려있는 변수를 바꿉니다 (어쩌면 앞에서와 같이 string.Replace를 알고있을 수도 있습니다). 그런 다음 CodeDOM (C# 또는 VB.Net)을 사용하여 스크립트를 컴파일하거나 DLR (IronPython, IronRuby) . 코드를 캡슐화 (CodeDOM의 경우)하거나 DLR에 변수를 주입하는 데 사용하는 메소드 랩퍼에서 변수를 메소드 매개 변수로 추가하기 만하면됩니다. 두 팀 모두 우리 팀에서보다 적은 노력과 노력으로 사업을 수행했습니다.

콜백을 긴급히 요청할 때 ValueOf (string)와 같은 이름으로 프로그래밍 언어의 호스트와 통신하는 메서드를 추가하십시오. 10

재밌게 - 그래서 당신은

ValueOf ("A")> ValueOf ("B")를 작성할 수 있습니다.

0

http://code.google.com/p/bc-expression/

는 람다 또는 블록 콜백 통해 가변 룩업 핸들.

숫자, 문자열 및 부울 상수를 이해합니다.

단항 연산자 + -!

연산자 || ! & & < < == = => => + - */%

함께 그룹화()

표현식을 올린다 :: 구문 에러를 구문 오류가 있는지.

3

Mono.CSharp.Evaluator를 사용 해본 적이 있습니까? 적절히 설정된 InteractiveBaseClass와 함께 사용하면 아주 쉽게 멋지게 할 수있을 것입니다.

다음은 모노 2.11.1 알파를 사용한다는 점에 유의하십시오.

using System; 
using System.Diagnostics; 
using Mono.CSharp; 
using NUnit.Framework; 

public class MonoExpressionEvaluator 
{ 
    [Test] 
    public void ProofOfConcept() 
    { 
     Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter())); 
     evaluator.InteractiveBaseClass = typeof (Variables); 
     Variables.Variable1Callback =() => 5.1; 
     Variables.Variable2Callback =() => 30; 

     var result = evaluator.Evaluate("25 + Variable1 > Variable2"); 

     Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result); 
     Console.WriteLine(result); 
    } 

    public class Variables 
    { 
     internal static Func<double> Variable1Callback; 

     public static Double Variable1 { get { return Variable1Callback(); } } 

     internal static Func<double> Variable2Callback; 

     public static Double Variable2 { get { return Variable2Callback(); } } 
    } 
} 

실제 수치는 조금 느립니다. 우리가 분석하고 우리가 그것을 실행할 수 IL로 컴파일 할 수 있다면

[Test] 
public void BenchmarkEvaluate() 
{ 
    Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter())); 
    evaluator.InteractiveBaseClass = typeof(Variables); 
    Variables.Variable1Callback =() => 5.1; 
    Variables.Variable2Callback =() => 30; 

    var sw = Stopwatch.StartNew(); 
    for (int i = 1; i < 10000; i++) 
     evaluator.Evaluate("25 + Variable1 > Variable2"); 
    sw.Stop(); 

    Console.WriteLine(sw.Elapsed); 
} 

00:00:07.6035024

그것은 좋은 것 : 예를 들어, 내 I7-M620에이 10,000 번 실행 거의 팔초 소요 .NET 속도로,하지만 내

00:00:00.0003799

[Test] 
public void BenchmarkCompiledMethod() 
{ 
    Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter())); 
    evaluator.InteractiveBaseClass = typeof(Variables); 
    Variables.Variable1Callback =() => 5.1; 
    Variables.Variable2Callback =() => 30; 

    var method = evaluator.Compile("25 + Variable1 > Variable2"); 
    object result = null; 
    method(ref result); 
    Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result); 

    Variables.Variable2Callback =() => 31; 
    method(ref result); 
    Assert.AreEqual(25 + Variables.Variable1 > Variables.Variable2, result); 

    var sw = Stopwatch.StartNew(); 
    for (int i = 1; i < 10000; i++) 
     method(ref result); 
    sw.Stop(); 
    Console.WriteLine(sw.Elapsed); 
} 

아 ... 파이프 꿈의 비트처럼 들린다.

IF와 같은 Excel 구문이 필요합니까? 자신 만의 빌드!

[Test] 
    public void ProofOfConcept2() 
    { 
     Evaluator evaluator = new Evaluator(new CompilerContext(new CompilerSettings(), new ConsoleReportPrinter())); 
     evaluator.InteractiveBaseClass = typeof(Variables2); 
     Variables.Variable1Callback =() => 5.1; 
     Variables.Variable2Callback =() => 30; 

     var result = evaluator.Evaluate(@"IF(25 + Variable1 > Variable2, ""TRUE"", ""FALSE"")"); 

     Assert.AreEqual("TRUE", result); 
     Console.WriteLine(result); 
    } 

    public class Variables2 : Variables 
    { 
     public static T IF<T>(bool expr, T trueValue, T falseValue) 
     { 
      return expr ? trueValue : falseValue; 
     } 
    }