Проблема в вашем коде состоит в том, что вы пытаетесь проанализировать formula
, для которого первая попытка состоит в анализе formulaCon
.Затем он сначала пытается проанализировать formula
, т. Е. Вы создаете бесконечную рекурсию без использования какого-либо ввода .
Чтобы решить эту проблему, вы должны структурировать свою грамматику.Определите ваши термины, как это (обратите внимание, что все эти термины потребляют некоторый ввод перед выполнением рекурсии обратно к formula
):
formulaTerm = ttFormula
<|> ffFormula
<|> varFormula
<|> forallFormula
<|> roundBrackets formula
forallFormula = do
keyword "forall"
x <- identifier
op "."
phi <- formula
return $ Forall x phi
В этом случае формула представляет собой либо отдельный термин, либо соединение, состоящее из термина,оператор и другая формула.Чтобы убедиться, что все входные данные проанализированы, сначала попытайтесь проанализировать конъюнкцию и - если это не удастся - проанализировать один термин:
formula = (try formulaCon) <|> formulaTerm
Наконец, formulaCon
может быть проанализирован следующим образом:
formulaCon = do
f1 <- formulaTerm
op "&"
f2 <- formula
return $ Con f1 f2
Недостаток этого решения в том, что соединения теперь прямо ассоциативны.