에 대한 차별 조합과 대안 및 노동 조합 (1 + (2 * 3)) // DSL 샘플 입력 (재귀) 나는 fparsec에서fparsec 구문 분석 DSL
type AirthmeticExpression =
| Constant of float
| AddNumber of AirthmeticExpression * AirthmeticExpression
| Mul of AirthmeticExpression * AirthmeticExpression
이 createParserForwardedToRef
let parseExpression, implementation = createParserForwardedToRef<AirthmeticExpression, unit>();;
let parseAdd = between pstring"(" pstring ")" (tuple2 (parseExpression .>> pstring " + ") parseExpression) |>> AddNumber
let parseMul = between pstring"(" pstring ")" (tuple2 (parseExpression .>> pstring " * ") parseExpression) |>> Mul
implementation := parseConstant <|> parseAdd <|> parseMull
로 추가 및 도난뿐만 파서 (P1) 입력을 소비하고 P2를 시도하지 않습니다 실패하면 fparsec 문서는 대안을 말한다.
내 경우 Add와 Mul은 모두 연산자 이전에 동일한 패턴을 가지고 있으므로 p1 만 작동합니다. 입력을 구문 분석 할 수 있도록 어떻게 리팩토링 할 수 있습니까? fparsec doc 솔루션 예제에서, 구문 분석을하고 Discriminated union 인스턴스를 생성하지 않은 것처럼 작동했습니다. 내 경우 Add 또는 Mul 중 하나를 만들 수 있도록 일치하는 패턴을 알아야합니다.
해결하기 위해 접두어 연산자 개념을 사용할 수 있습니다. 하지만 내 DSL 입력의 가독성을 위해 중위 연산자 개념을 원합니다. + (1,2)와 같은 간단한 연산자 접두사 개념을 위해. 그러나 문자열 ({in})이나 숫자 ({between})와 같은 복잡한 연산자를 사용하여 문법을 발전시킵니다. 접두사는 가독성이 떨어집니다. – abhishek
대안을'시도 '로 감싸십시오. –
Fyodor에게 답장을 보내 주셔서 감사합니다. 나는 f #과 fprasec에 익숙하지 않다. 당신은 그 코드를 더 잘 만들거나 더 잘 만들 수 있는가? 다중 시도 구문 분석기를 사용하면 어떤 식별자가 일치했는지 알 수 있으므로 식별자 식별자를 적절하게 인스턴스화 할 수 있습니다. 'pstring "+"<|> pstring "*"' 과 같은 피연산자에 대한 문자열 파서를 만든 다음 tuple3을 사용하여 (피연산자, 연산자, righthandoperand) 가져 오려고했습니다. 그런 다음 Operator에서 if/else를 사용하여 어떤 연산자가 일치하고 인스턴스가 내 discriminator 유형인지 결정합니다. 그것은 작동하지만 올바른 기능적 접근법이 아니라고 생각합니다. – abhishek