{- File: expr08.hs This is a recursive-descent parser for the grammar: expr -> term | term + expr | term - expr term -> factor | factor * term | factor / term factor -> const | ( expr ) Here const is a String that can be interpreted as an integer value (e.g., "8", "72"). There is one function for each non-terminal ( expr, term and factor ). Each function takes a list of strings to simulate the token stream. The return value is a pair (b, t). The Boolean b indicates whether parsing was successful. The list t is a list of unprocessed tokens. For exmple: > term ["8", "*", "72", "+", "14"] (True,["+","14"]) -} module HW8_3 where -- Miranda Carroll (station11) import Text.Read import HW8_2 -- tail that doesn't crash on empty list safetail [] = [] safetail (x:xs) = xs -- head that doesn't crash on empty list safehead [] = "" safehead (x:xs) = x -- ------------------------------------------------------ expr [] = (False, []) expr tokens = let (b1,tokens1) = term tokens next = safehead tokens1 in if b1 && ( next == "+" || next == "-") then expr (safetail tokens1) else (b1, tokens1) -- ------------------------------------------------------ term [] = (False, []) term tokens = let (b1,tokens1) = factor tokens next = safehead tokens1 in if b1 && ( next == "*" || next == "/") then term (safetail tokens1) else (b1, tokens1) -- ------------------------------------------------------ factor [] = (False, []) factor (t:tokens) | t == "(" = let (b1,tokens1) = expr tokens in if b1 && safehead tokens1 == ")" then (True, safetail tokens1) else (False, tokens1) | otherwise = case (readMaybe t :: Maybe Int ) of Nothing -> (False, t:tokens) Just n -> (True, tokens) -- ------------------------------------------------------