Skip to content

Commit

Permalink
[ #71 ] Fixed crash in DFAMin
Browse files Browse the repository at this point in the history
DFA minimization used to crash on tokens of the form c* which produce
automata with only accepting states.  Considering the empty set of
non-accepting states as an equivalence class caused minimization to
crash with exception

  Prelude.head: empty list

Now, DFA minimization succeeds.

There is still a problem with nullable tokens like c*.  Alex produces an
infinite token sequence at the end of the input.
  • Loading branch information
andreasabel committed Jan 22, 2020
1 parent 6d57118 commit 70cc112
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
1 change: 1 addition & 0 deletions alex.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ extra-source-files:
tests/posn_typeclass_bytestring.x
tests/strict_typeclass.x
tests/unicode.x
tests/issue_71.x

source-repository head
type: git
Expand Down
5 changes: 4 additions & 1 deletion src/DFAMin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ groupEquivStates DFA { dfa_states = statemap }
accept_groups :: [EquivalenceClass]
accept_groups = map IS.fromList (Map.elems accept_map)

init_p = nonaccepting_states : accept_groups
init_p, init_q :: [EquivalenceClass]
init_p -- Issue #71: each EquivalenceClass needs to be a non-empty set
| IS.null nonaccepting_states = accept_groups
| otherwise = nonaccepting_states : accept_groups
init_q = accept_groups

-- map token T to
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ TESTS = \
basic_typeclass_bytestring.x \
default_typeclass.x \
gscan_typeclass.x \
issue_71.x \
monad_typeclass.x \
monad_typeclass_bytestring.x \
monadUserState_typeclass.x \
Expand Down
49 changes: 49 additions & 0 deletions tests/issue_71.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
-- Issue #71
-- reported 2015-10-20 by Ian Duncan
-- fixed 2020-01-22 by Andreas Abel
--
-- Problem was:
-- DFA minimization crashed with "Prelude head: empty list" because
-- empty set of non-accepting states was treated as empty equivalence
-- class of states.

module Main (main) where

import System.Exit
}

%wrapper "posn"
%token "Token"

$whitespace = [\ \n\t]
@whitespaces = $whitespace*

:-

@whitespaces { \ _ _ -> Whitespaces }
"a" { \ _ _ -> A }

{
data Token = Whitespaces | A
deriving (Eq, Show)

input = "aa \n\taa \t \n a"
expected_result = [A,A,Whitespaces,A,A,Whitespaces,A]

main :: IO ()
main
-- Since the whitespaces token is nullable, Alex
-- will recognize an infinite number of those
-- at the end of file. This behavior is problematic,
-- but we don't fix it here.
-- We just test here whether the expected result
-- is a prefix of the produced result.
| take (length expected_result) result == expected_result = do
exitWith ExitSuccess
| otherwise = do
print $ take 20 result
exitFailure
where
result = alexScanTokens input
}

0 comments on commit 70cc112

Please sign in to comment.