-- Parse a Net definition:
--  NET ::= PLACES, "\n", TRANS, { TRANS }, "\n", MBPLACES "\n";
--
--  PLACE ::= {- Natural Number -};
--
--  MBPLACES ::= []
--            |  PLACES;
--
--  PLACES ::= PLACE
--          |  PLACE, ",", PLACES;
--
--  TRANS ::= PLACES, "--", LABELS, "->", PLACES;
--
--  LABELS ::= LABEL
--          | LABEL, ",", LABELS;
--
--  LABEL ::= {- Anything but ',' or '-' -}
--
--
-- E.g.:
--     0
--     0--a,b,c->1
--     0--a->0
--     1
--
-- is the NFA that has two states and accepts any string a*(a|b|c).
parseNetDef :: Parser (NFADef String)
parseNetDef =
    NFADef <$> (parsePlaces <* newline)
           <*> (NEL.fromList <$> many1 (try (parseNFATrans <* newline)))
           <*> option [] (NEL.toList <$> parsePlaces <* option '\n' newline)
  where
    commaSep1 x = sepBy1 x (char ',')

    parseInt = read <$> many1 digit

    parsePlaces = NEL.fromList <$> commaSep1 parseInt

    parseNFATrans =
        NFATransDef <$> parsePlaces
                    <*> between (string "--") (string "->") parseLabels
                    <*> parsePlaces

    parseLabels = NEL.fromList <$> (commaSep1 . many1 $ noneOf "-,")
parseNetDef :: Parser (NFADef String)
parseNetDef =
    NFADef <$> (parsePlaces <* newline)
           <*> (NEL.fromList <$> many1 (try (parseNFATrans <* newline)))
           <*> option [] (NEL.toList <$> parsePlaces <* option '\n' newline)
  where
    commaSep1 x = sepBy1 x (char ',')

    parseInt = read <$> many1 digit

    parsePlaces = NEL.fromList <$> commaSep1 parseInt

    parseNFATrans =
        NFATransDef <$> parsePlaces
                    <*> between (string "--") (string "->") parseLabels
                    <*> parsePlaces

    parseLabels = NEL.fromList <$> (commaSep1 . many1 $ noneOf "-,")
parseNetDef =
    NFADef <$> (parsePlaces <* newline)
           <*> (NEL.fromList <$> many1 (try (parseNFATrans <* newline)))
           <*> option [] (NEL.toList <$> parsePlaces <* option '\n' newline)
  where
    commaSep1 x = sepBy1 x (char ',')

    parseInt = read <$> many1 digit

    parsePlaces = NEL.fromList <$> commaSep1 parseInt

    parseNFATrans =
        NFATransDef <$> parsePlaces
                    <*> between (string "--") (string "->") parseLabels
                    <*> parsePlaces

    parseLabels = NEL.fromList <$> (commaSep1 . many1 $ noneOf "-,")