Implementation of empty
10.2.6 Implementation of empty
Many functions defined in this chapter make use of a predicate isEmpty, which tests whether or not the empty sequence can be derived from a nonterminal. This subsection defines this function. Consider the grammar exGrammar. We are now only interested in deriving sequences which contain only nonterminal symbols (since it is impossible to derive the empty string if a terminal occurs). Therefore we only have to consider the productions in which no terminal symbols appear in the right-hand sides.
C →D One can immediately see form those productions that the nonterminal A derives the
empty string in one step. To know whether there are any nonterminals which derive
LL Parsing
the empty string in more than one step we eliminate the productions for A and we eliminate all occurrences of A in the right hand sides of the remaining productions
S → B | CB
B →
C →D One can now conclude that the nonterminal B derives the empty string in two steps.
Doing the same with B as we did with A gives us the following productions
S → |C
C →D One can now conclude that the nonterminal S derives the empty string in three steps.
Doing the same with S as we did with A and B gives us the following productions
C →D At this stage we can conclude that there are no more new nonterminals which derive
the empty string. We now give the Haskell implementation of the algorithm described above. The
algorithm is iterative: it does the same steps over and over again until some desired condition is met. For this purpose we use function fixedPoint, which takes a function and a set, and repeatedly applies the function to the set, until the set does not change anymore.
fixedPoint
:: Ord a => ([a] -> [a]) -> [a] -> [a]
fixedPoint f xs | xs == nexts = xs
| otherwise
= fixedPoint f nexts
where nexts = f xs fixedPoint f is sometimes called the fixed-point of f. Function isEmpty determines
whether or not a nonterminal can derive the empty string. A nonterminal can derive the empty string if it is a member of the emptySet of a grammar.
isEmpty
:: (Symbol s, Ord s) => CFG s -> s -> Bool
isEmpty grammar = (‘elem‘ emptySet grammar) The emptySet of a grammar is obtained by the iterative process described in the
example above. We start with the empty set of nonterminals, and at each step n of the computation of the emptySet as a fixedPoint, we add the nonterminals that can derive the empty string in n steps. Function emptyStepf adds a nonterminal if there exists a production for the nonterminal of which all elements can derive the empty string.
emptySet :: (Symbol s, Ord s) => CFG s -> [s] emptySet grammar = fixedPoint (emptyStepf grammar) []
emptyStepf :: (Symbol s, Ord s) => CFG s -> [s] -> [s] emptyStepf grammar set =
nub (map fst (filter (\(nt,rhs) -> all (‘elem‘ set) rhs)
(prods grammar)
10.2 LL Parsing: Implementation