2017-05-10 89 views
2

以下解析器爲任何輸入輸入無限循環。爲什麼這個Parsec解析器輸入一個無限循環?

data Ast 
    = Number Int 
    | Identifier String 
    | Operation Ast BinOp Ast 
    deriving (Show, Eq) 

data BinOp = Plus | Minus 
    deriving (Show, Eq, Enum) 

number = Number <$> read <$> many1 digit 

identifier = Identifier <$> many1 letter 

operator = choice $ mkParser <$> [(Plus, '+'), (Minus, '-')] 
    where mkParser (f, c) = f <$ char c 

operation = Operation <$> ast <*> operator <*> ast 

ast :: Parser Ast 
ast = operation <|> number <|> identifier 

問題出在操作解析器的某個地方。我認爲它與替代解析有關,但我不理解它。

你能解釋一下問題所在嗎?

謝謝!

回答

4

問題確實存在於無限遞歸中。您的ast解析器首先調用operation解析器。但隨後operation解析器再次調用ast。等等。 <*>解析運算符也運行解析器。與<|>以非常非正式的方式不同的解釋:<*>按順序依次運行解析器是否<|>運行第一個解析器,並且僅在失敗時運行第二個解析器。

operation = Operation <$> ast <*> operator <*> ast 
ast  = operation <|> number <|> identifier 

基本上,甚至重新排列解析器你的做法是行不通的。在類似的問題上看到這個答案的解釋:Megaparsec: Not able to parse arithmetic string

相關問題