Я относительно новичок в Haskell с основами программирования, основанными на языках OO. Я пытаюсь написать интерпретатор с парсером для простого языка программирования. Пока у меня есть переводчик в состоянии, которым я достаточно доволен, но немного борюсь с синтаксическим анализатором.
Вот фрагмент кода, с которым у меня возникают проблемы
data IntExp
= IVar Var
| ICon Int
| Add IntExp IntExp
deriving (Read, Show)
whitespace = many1 (char ' ')
parseICon :: Parser IntExp
parseICon =
do x <- many (digit)
return (ICon (read x :: Int))
parseIVar :: Parser IntExp
parseIVar =
do x <- many (letter)
prime <- string "'" <|> string ""
return (IVar (x ++ prime))
parseIntExp :: Parser IntExp
parseIntExp =
do x <- try(parseICon)<|>try(parseIVar)<|>parseAdd
return x
parseAdd :: Parser IntExp
parseAdd =
do x <- parseIntExp
whitespace
string "+"
whitespace
y <- parseIntExp
return (Add x y)
runP :: Show a => Parser a -> String -> IO ()
runP p input
= case parse p "" input of
Left err ->
do putStr "parse error at "
print err
Right x -> print x
Язык немного сложнее, но этого достаточно, чтобы показать мою проблему.
Таким образом, в типе IntExp ICon является константой, а IVar - переменной, но теперь о проблеме. Это, например, работает успешно
runP parseAdd "5 + 5"
, который дает (Добавить (ICon 5) (ICon 5)), что является ожидаемым результатом. Проблема возникает при использовании IVars, а не ICons, например
runP parseAdd "n + m"
Это приводит к тому, что программа выдает ошибку, говоря, что было неожиданное «n», где ожидалась цифра. Это приводит меня к мысли, что parseIntExp не работает так, как я планировал. Мое намерение состояло в том, что он попытается проанализировать ICon, если это не удастся, то попытаться проанализировать IVar и так далее.
Так что я думаю, что проблема существует в parseIntExp, или я что-то упускаю в parseIVar и parseICon.
Надеюсь, я дал достаточно информации о своей проблеме, и я достаточно ясно.
Спасибо за любую помощь, которую вы можете оказать мне!