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
你能說出你的問題,也許是用「我怎麼能...」和以「?」結尾? –
這是一個非常小的例子嗎?你做了哪些嘗試來追蹤導致問題的代碼?至少,試着用'undefined'逐個替換每個函數定義。當你的程序返回'undefined'而不是循環時,你知道違規函數就是你剛纔改變的函數。一位回答者已經向你提供了一個暗示它可能在哪裏。 – user2407038