문제

가장 좋은 점은 다음과 같은 표현을 평가하는 것입니다.
(A 및 B) 또는 (A 및 C) 또는 (B 및 C 아님)
또는
(a && b) || (a && c) || (! b && c)

런타임에 위의 표현식을 다음으로 변환 할 계획이었습니다.
(true and false) 또는 (참과 거짓) 또는 (거짓과 참)
또는
(true && false) || (true && false) || (! false && true)

조건 : 1) 논리적 표현은 런타임까지 알려져 있지 않습니다. 2) 숫자 변수와 해당 값은 런타임까지 알려져 있지 않습니다. 3) 가변 값은 결코 무효가되지 않습니다.

나는 입력을 기반으로 런타임에 생성하는 클래스와 방법을 사용하여 간단한 조립을 만들 수 있다는 것을 알고 있지만 더 나은 방법이 있습니다. 나는 전에 이것을 해냈다. 문자열 빌더를 사용하여 코드를 작성한 다음 컴파일러를 호출하십시오. 그런 다음 어셈블리를로드하고 방법을 호출합니다.

제안?

감사.

도움이 되었습니까?

해결책

.NET3.5를 사용하는 경우 텍스트를 구문 분석하고 표현식 클래스를 사용하여 추상적 인 sytax 트리를 만들 수 있습니다. 그런 다음 적절한 Lambdaexpression 인스턴스를 작성하여 대의원으로 컴파일 한 다음 실행할 수 있습니다.

이런 종류의 상당히 간단한 그레이머를 위해 파서와 구문 트리 빌더를 구성하는 것은 매우 흥미로운 연습이며 컴파일러를 호출하는 것보다 다소 빠르게 실행됩니다 (그리고 내 관점에서도 깔끔합니다).

.NET3.5를 사용하지 않는 경우 해석 된 추상 구문 트리를 직접 구현하는 것도 복잡하지 않습니다.

다른 팁

경고 : 당신이 말하는 두 가지 조건이 반드시 동등한 것은 아닙니다. C#의 && 운영자는 단락 평가를 사용하지만 논리적으로 And VB의 운영자는 그렇지 않습니다. 진술이 동등한 지 확인하려면 사용자를 번역하십시오. And 에게 AndAlso 그리고 사용자 Or 에게 OrElse.

간단한 표현의 경우 차이가 없을 것입니다. 그러나 조건에 부작용이 발생하거나 둘 사이의 성능 차이가 우려되는 경우 중요 할 수 있습니다.

다음과 같이 쉽게 할 수 있습니다.

  1. 부울 표현식을 입력으로 취하고 디픽스 목록을 생성하는 파서 생성기 (위에서 언급 한 ANTLR과 같은).
  2. 리버스 폴란드 표기법 스택을 평가하는 코드.

문법은 다음과 같이 보입니다.

program: exprList ;

exprList: expr { Append($1); }
    | expr OR exprList { Append(OR); }
    | expr AND exprList { Append(AND); }
    | NOT exprList { Append(NOT); }
    | ( exprList ) { /* Do nothing */ }
    ;

expr: var { Append($1); }
    | TRUE { Append(True); }
    | FALSE { Append(False); }
    ;

평가하려면 다음을 수행합니다.

for each item in list
    if item is symbol or truth value, push onto RPN stack
    else if item is AND, push (pop() AND pop())
    else if item is OR, push (pop() OR pop())
    else if item is NOT, push (NOT pop())

result = pop()

기호의 경우 런타임에 진실 값을 대체해야합니다.

당신이 사용할 수있는 https://github.com/mrazekv/logicalparser

논리 표현식을 작성하는 단순히 라이브러리 (precenednce 테이블로 퇴거, 허용 또는 onte, on on on in Integer 변수 및 = 문자열 변수).

간단한 통역사/파서를 쓸 수 있습니다. 같은 것을 사용하십시오 antlr 기존 문법을 재사용하십시오.

.NET 3.5를 사용하는 경우 람다 표현식을 만들 수 있습니다. 그런 다음 대의원을 생성하고 표준 대의원/방법으로 호출 할 수 있습니다. 인터넷에는 Lambda 표현에 관한 많은 샘플이 있습니다.

한 가지 솔루션은 표현식을 문자열로 조립 한 다음 SQL Server 또는 귀하의 데이터베이스가 평가를위한 모든 것을 보내는 것입니다. 실제 변수를 각각 true 및 false의 경우 1 = 1 또는 0 = 1으로 바꾸면 다음과 같은 쿼리로 끝납니다.

여기서 (1 = 1 및 0 = 1) 또는 (1 = 1 및 1 = 1) 또는 (0 = 1 및 1 = 1이 아님) 1을 선택하십시오.

그런 다음 쿼리를 실행하면 결과가 사실 일 때 1을 다시 얻습니다. 가장 우아한 솔루션은 아니지만 작동합니다. 많은 사람들이 아마도 이것에 대해 조언 할 것이지만, 어쨌든 가능한 해결책으로 버릴 것입니다.

이것은 최선의 대답이 아니지만, 나는 얼마 전에이 문제를 겪었습니다.

여기 내 기존 코드가 있습니다 : vb.net- 보증이 전혀 없습니다!

https://cloud.downfight.de/index.php/s/w92i9qq1ia216xb

Dim BoolTermParseObjekt As New BoolTermParse
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)

이 코드는 다수의 '(', '),', ',', '또는'plus '기타'가있는 문자열을 섭취하고 부울 값으로 대체함으로써 물건을 부울로 나눕니다. 그러므로:

'다른 것들'을 평가하고 싶었던 것이 무엇이든, 나는 "Funktionen ausführen und Zurückgeben, einzelwert!" 페이지 2에서 오른쪽은 "숫자가> 1 인 경우"입니다.

인사말

내 도서관을 살펴보고 프로비언트. 이를 사용하는 .NET 표준 라이브러리입니다 야드 알고리즘 분로 부울 표현을 평가합니다.

또한 표현에 대한 진실 테이블을 생성 할 수 있습니다.

자신의 문법을 구현할 수도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top