Я новичок в Haskell и работаю над заданием, в котором я пытаюсь создать функцию синтаксического анализа для простого языка калькулятора.
Мне дали грамматику, и мне не разрешено ее менять. Я попытался решить эту проблему, пройдя через строку и рекурсивно используя мою функцию синтаксического анализа.
Предполагается, что грамматика будет
Expr -> Int | -Expr | + Expr Expr | * Expr Expr
Int -> Digit | Digit Int
Digit -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Поэтому моя функция принимает в качестве аргумента строку на языке Expr и создает абстрактное синтаксическое дерево в этом формате
data Ast = Tall Int | Sum Ast Ast | Mult Ast Ast| Min Ast| Var String deriving (Eq, Show)
Аст должен быть абстрактным синтаксическим деревом
И это то, что я до сих пор получил в своей функции синтаксического анализа
parseEx :: [String] -> (Ast, [String])
parseEx [] = error "empty string"
parseEx (s:ss) | all isDigit s = (Tall (read s), ss)
| s == "-" = let (ast, ss') = parseEx ss in (Min ast, ss')
| s == "+" = let (ast, ss'), let(ast',ss'') = parseEx ss in (Sum ast ast', ss') parseEx ss' (ast', ss'')
| s == "*" = (Mult ast ast', ss'') where
(ast, ss'') = parseEx ss'
(ast', ss''') = parseEx ss''
Я ясно вижу, что условие с +
неправильно, и что я не могу иметь два let
там. Кроме того, я как бы потерялся во всех этих списках. Я думал, что map
-функция может быть решением моей проблемы, и, возможно, это сделает мой код более аккуратным. Но я не уверен, с чего начать, так как это должно быть в форме [String]->Ast
. И проще ли просто придерживаться имеющегося у меня кода и попытаться заставить его работать?