2016-02-06 50 views
2

我一直在嘗試使用parsec爲類型化的lambda微積分編寫一個解析器,但它一直陷入循環導致出現<>錯誤。一切對我來說都很好;我可能誤解了parsec的一些問題。Haskell parsec給出了<<loop>>錯誤

{-# LANGUAGE UnicodeSyntax #-} 

module Parser where 

import Semantics (NmTerm(..) 
       , Ty(..)) 

import Text.ParserCombinators.Parsec (Parser(..) 
            , ParseError 
            , try 
            , oneOf 
            , char 
            , digit 
            , satisfy 
            , many1 
            , choice 
            , chainl1 
            , alphaNum 
            , eof 
            , letter 
            , parse) 

import qualified Text.Parsec.Token as T 
import qualified Text.Parsec.Language as L 
import qualified Text.Parsec.Expr as E 
import Control.Applicative ((<|>)) 

------------ 
-- LEXING -- 
------------ 

lexer ∷ T.TokenParser() 
lexer = T.makeTokenParser 
     $ L.emptyDef { T.identStart  = letter 
        , T.identLetter  = alphaNum 
        , T.reservedOpNames = ["lambda", ".", ":", "->"] 
        , T.reservedNames = ["true", "false", "Bool"] 
        , T.opLetter  = oneOf ".:" 
        } 

parens ∷ Parser a → Parser a 
parens = T.parens lexer 

natural ∷ Parser Integer 
natural = T.natural lexer 

reserved ∷ String → Parser() 
reserved = T.reserved lexer 

reservedOp ∷ String → Parser() 
reservedOp = T.reservedOp lexer 

identifier ∷ Parser String 
identifier = T.identifier lexer 

whiteSpace ∷ Parser() 
whiteSpace = T.whiteSpace lexer 

------------------------------------------------------------------------------- 
-------------------------------------- PARSING -------------------------------- 
------------------------------------------------------------------------------- 
variable ∷ Parser NmTerm 
variable = identifier >>= \x → return $ NmVar x 

true ∷ Parser NmTerm 
true = reserved "true" >> return NmTrue 

false ∷ Parser NmTerm 
false = reserved "false" >> return NmFalse 

bool ∷ Parser NmTerm 
bool = true <|> false 

boolTy ∷ Parser Ty 
boolTy = reserved "Bool" >> return TyBool 

arrTy ∷ Parser Ty 
arrTy = do 
    τ₁ ← anyType 
    whiteSpace 
    reservedOp "->" 
    whiteSpace 
    τ₂ ← anyType 
    return $ TyArr τ₁ τ₂ 

anyType ∷ Parser Ty 
anyType = arrTy <|> boolTy 

abstraction ∷ Parser NmTerm 
abstraction = do 
    reservedOp "lambda" 
    whiteSpace 
    x ← identifier 
    reservedOp ":" 
    τ ← anyType 
    reservedOp "." 
    whiteSpace 
    body ← expr 
    return $ NmAbs x τ body 

expr ∷ Parser NmTerm 
expr = abstraction 
    <|> variable 
    <|> bool 

parseExpr ∷ String → NmTerm 
parseExpr t = case parse expr "" t of 
       Left err → error $ show err 
       Right ast → ast 
+1

你能說出你的問題,也許是用「我怎麼能...」和以「?」結尾? –

+0

這是一個非常小的例子嗎?你做了哪些嘗試來追蹤導致問題的代碼?至少,試着用'undefined'逐個替換每個函數定義。當你的程序返回'undefined'而不是循環時,你知道違規函數就是你剛纔改變的函數。一位回答者已經向你提供了一個暗示它可能在哪裏。 – user2407038

回答

2

如果您對錯誤消息更加具體,它可能會有幫助。但我懷疑問題是您有一個左遞歸語法:例如,arrTy可以以anyType開頭,可以是arrTy

當直接在自頂向下的解析器(包括組合器解析器,如Parsec)中實現時,這種功能會導致無限循環。 Parsec提供各種設施來解決這個問題;然而,解決你的特定問題最方便的方法可能還需要你的語法重新工作。

相關問題