2017-02-22 1 views
1

나는 플래그 이러한 하위 인수를 구문 분석 할Option.Applicative : 결합 된 파서를 플래그로 구문 분석하는 방법은 무엇입니까?

data Arguments = Arguments Bool (Maybe SubArguments) 
data SubArguments = SubArguments String String 

로, 명령 줄 옵션을 복잡하게했다 :

programName --someflag --subarguments "a" "b" 
programName --someflag 

나는 이미 내가 작성해야 할 무엇

subArgParser = SubArguments <$> argument str <*> argument str 
mainParser = MainArgs <$> switch 
        (long "someflag" 
        <> help "Some argument flag") 
       <*> ??? 
        (long "subarguments" 
        <> help "Sub arguments" 

에서 ???

답변

1

적어도 직접적으로는 가능하지 않습니다. 당신은 당신을 위해 작동하는 간접 인코딩을 찾을 수도 있지만 확실하지는 않습니다. 옵션은 인수를 취하며 서브 구문은 인수가 아닙니다. 서브 파서는 가질 수 있지만 옵션이 아닌 "명령"에 의해 소개됩니다 (즉, 선두가없는 경우). --.

2

귀하의 질문은 생각보다 복잡합니다. 현재 optparse-applicative API는 이러한 경우에는 사용하지 않아야합니다. 따라서 CLI 인수를 처리하는 방법을 변경하거나 다른 CLI 구문 분석 라이브러리로 전환하는 것이 좋습니다. 그러나 목표 달성의 가장 가까운 방법을 설명 할 것입니다.

첫째, 당신은 다른 두 개의 SO 질문을 읽을 필요가 :

How to parse Maybe with optparse-applicative

2. 첫 번째 질문에서Is it possible to have a optparse-applicative option with several parameters?

당신이 optional 기능을 사용하여 선택적 인수를 구문 분석하는 방법을 알고 . 두 번째부터는 여러 인수를 파싱 할 때 몇 가지 문제점을 배웁니다. 그래서이 문제를 해결할 수있는 몇 가지 접근 방법을 여기에 쓰겠습니다.

1. 나이브 및

당신은 String 형태의 쌍으로 문자열의 쌍을 대표하고,이 한 쌍의 단지 순진 show을 사용할 수 있습니다 추한. ghci

여기
mainParser :: Parser Arguments 
mainParser = Arguments 
    <$> switch (long "someflag" <> help "Some argument flag") 
    <*> optional (uncurry SubArguments <$> 
        (option auto $ long "subarguments" <> help "some desc")) 

getArguments :: IO Arguments 
getArguments = do 
    (res,()) <- simpleOptions "main example" "" "desc" mainParser empty 
    return res 

main :: IO() 
main = getArguments >>= print 

결과입니다 : 여기에 코드입니다

ghci> :run main --someflag --subarguments "(\"a\",\"b\")" 
Arguments True (Just (SubArguments "a" "b")) 

2. 적은 당신이 하나의 문자열 내부에 여러 인수를 전달하는 방법을 배워야 할 두 번째 질문에 대한 대답에서

순진. 여기에 구문 분석 코드 :

subArgParser :: ReadM SubArguments 
subArgParser = do 
    input <- str 
    -- no error checking, don't actually do this 
    let [a,b] = words input 
    pure $ SubArguments a b 

mainParser :: Parser Arguments 
mainParser = Arguments 
    <$> switch (long "someflag" <> help "Some argument flag") 
    <*> optional (option subArgParser $ long "subarguments" <> help "some desc") 

을 그리고 여기 ghci 출력 :

ghci> :run main --someflag --subarguments "x yyy" 
Arguments True (Just (SubArguments "x" "yyy")) 

초 솔루션의 유일한 나쁜 것은 그 오류 검사가없는 것입니다. 따라서 let [a,b] = words input 대신 megaparsec과 같은 다른 일반 용도의 구문 분석 라이브러리를 사용할 수 있습니다.

+0

나는 도서관의 저자에게 물었다. 그것은 (현재로서는) 불가능합니다. Paolo Capriotti의 anwer보기 – Pieter

관련 문제