datafix-0.0.1.0: tests/FirstFollow.hs
{-# LANGUAGE FlexibleContexts #-}
module FirstFollow where
import Prelude hiding (seq, exp)
import SetRecurrences.FirstFollow
import qualified Data.Set as Set
import Test.Tasty
import Test.Tasty.HUnit
tests :: [TestTree]
tests =
[ testGroup "Dyck"
[ testFirst 3 dyck "S(S)" ["(((", "(()", "()", "()("]
, testFollow 3 dyck 'S' ["###",")##",")((",")()","))#","))(",")))"]
]
, testGroup "LL(1), not SLL(k)"
[ testFirst 3 llsll "A" ["","a"]
, testFollow 3 llsll 'A' ["ab#","b##"]
]
, testGroup "empty"
[ testFirst 3 emptyL "A" []
, testFollow 3 emptyL 'A' ["###"]
]
, testGroup "Left recursion"
[ testFirst 3 leftrec "A" ["c","cab"]
, testFollow 3 leftrec 'A' ["a##","aba"]
]
] where
testFirst :: Int -> Grammar Char Char -> String -> [String] -> TestTree
testFirst k gr seq exp =
testCase ("First_" ++ show k ++ "('" ++ seq ++ "')") $
first k gr (map (mkV gr) seq) @?= Set.fromList exp
testFollow :: Int -> Grammar Char Char -> Char -> [String] -> TestTree
testFollow k gr nt exp =
testCase ("Follow_" ++ show k ++ "(" ++ show nt ++ ")") $
follow k gr nt @?= Set.fromList (map (map mkWithEOF) exp)
mkV gr v
| elem v (terminals gr) = T v
| elem v (nonterminals gr) = NT v
| otherwise = error "not part of vocabulary"
mkWithEOF '#' = EOF
mkWithEOF c = NoEOF c