2016-02-06 62 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提供各种设施来解决这个问题;然而,解决你的特定问题最方便的方法可能还需要你的语法重新工作。

相关问题