2017-11-30 12 views
2

스키마 해석기 작성시 this guide을 따르고 있습니다. 왼쪽 요인 DottedList/목록에 대한 문법을 ​​시도, 나는이 함께했다 :구문 분석 체계 dottedlist/list with Haskell

E -> (H T) 
H -> E H' 
H' -> <space> H 
H' -> <term> 
T -> <term> 
T -> <space> . <space> E 

-

spaces :: Parser() 
spaces = skipMany1 (space <?> "spaces") 

parseExpr :: Parser LispVal 
parseExpr = (... omitted ...) <|> 
      do char '(' 
       h <- sepBy parseExpr spaces 
       t <- optionMaybe ((spaces' >> char '.' >> spaces' >> parseExpr) <?> "parseDotExpr failed") 
       z <- if isJust t then return $ DottedSuffix $ fromJust t else return Tail 
       z' <- case z of Tail   -> return $ List x 
           DottedSuffix s -> return $ DottedList x s 
       char ')' 
       return z' 

불행하게도이 기본 dottedlists 처리하지 않습니다

test/Spec.hs:23: 
1) test eval 1 evals DottedList 
    expected: "(1 2 . 1)" 
     but got: "Parse error at \"lisp\" (line 1, column 7):\nunexpected \".\"\nexpecting spaces' or parseExpr!" 

test/Spec.hs:26: 
2) test eval 1 evals DottedList (quoted) 
    expected: "((1 2) . 1)" 
     but got: "Parse error at \"lisp\" (line 1, column 15):\nunexpected \".\"\nexpecting spaces' or parseExpr!" 

test/Spec.hs:29: 
3) test eval 1 evals DottedList (sugared) 
    expected: "((1 2) . 1)" 
     but got: "Parse error at \"lisp\" (line 1, column 9):\nunexpected \".\"\nexpecting spaces' or parseExpr!" 

업데이트 : @ pat의 응답에서 다음을 사용하여 통과 테스트를 거쳤습니다.

parseExpr :: Parser LispVal 
parseExpr = {- omitted -} 
     <|> do char '(' 
       x <- many1 (do e <- parseExpr; spaces'; return e) 
       {- omitted -} 

답변

3

파서가 점 앞의 공백을보고 다른 식을 구문 분석하려고하는데 실패합니다.

어휘가 소비되고 후행 공백을 버리고 (parsec의 lexeme 참조) sepBymany1으로 변경해야합니다. 그런 다음 optionMaybe은 점이 표시된 후 커밋 할 수 있습니다. 그렇지 않은 경우 try이 필요합니다.