Основная стратегия для этих частей выражения будет такой же, как и для других операций, только вам не нужно анализировать два подвыражения, а только один или три. Для let
это будет выглядеть так:
parseExpr ('l':'e':'t':s) = (Let x y z, s3)
where (x, 'b':'e':s1) = parseExpr s
(y, 'i':'n':s2) = parseExpr s1
(z, s3) = parseExpr s2
Если строка начинается с букв l
, e
, t
, возьмите оставшуюся строку (s
) и попытайтесь проанализировать выражение из нее. Это приводит к выражению (x
) и оставшейся строке. Мы ожидаем, что эта оставшаяся строка начинается с букв b
, e
. Поскольку за этим должно следовать другое выражение, мы передаем оставшуюся часть этой строки (s2
) снова parseExpr для анализа другого выражения. И так далее.
Единственная проблема с этим заключается в том, что мы не учитываем пробелы, которые могут отделить эти ключевые слова, такие как «let» и «be», от окружающих выражений. Простым решением было бы потребовать ровно один пробел до / после этих ключевых слов и изменить шаблоны в parseExpr, чтобы явно включить их, например:
where (x, ' ':'b':'e':' ':s1) = parseExpr s
Более гибким было бы добавить функцию dropSpaces :: String -> String
, которая удаляет начальные пробелы и вызывается в соответствующих местах.