1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
module Text.Edifact.Scaffolder.Composites.Specification
( -- *
specificationParser
, listSimples
) where
import Text.Edifact.Scaffolder.Commons
import Text.Edifact.Scaffolder.Composites.Types
import Text.Parsec as P (anyChar, count,
digit,
endOfLine, many,
many1, manyTill,
oneOf, skipMany,
string, try,
(<?>))
import Text.Parsec.String (Parser)
specificationParser :: Parser ((CompositeCode, CompositeName), [Dependency])
specificationParser = do
compositeInfo <- scanUntil [ compositeParser ]
dependencies <- scan [ inLine dependencyParser ] <?> "Composites specification"
pure (compositeInfo, dependencies)
listSimples :: Parser (CompositeCode, [SimpleCode])
listSimples = do
parsed <- specificationParser
pure (fst $ fst parsed, getElementSimpleCode . dependencyElement <$> snd parsed)
compositeParser :: Parser (CompositeCode, CompositeName)
compositeParser = do
_ <- count 6 (oneOf "+*#|X ")
skipMany (string " ")
code <- compositeCodeParser
_ <- string " "
name <- CompositeName <$> manyTill anyChar (() <$ try endOfLine)
pure (code, name)
compositeCodeParser :: Parser CompositeCode
compositeCodeParser = do
initial <- oneOf "CE"
rest <- count 3 digit
pure (fromString (initial : rest))
dependencyParser :: Parser Dependency
dependencyParser =
Dependency <$> positionParser
<* many1 (oneOf "+*#|-X ")
<*> elementParser
<* stringToPresenceParser
<* many1 (string " ")
<*> presenceParser
<?> "Dependency"
inLine :: Parser a -> Parser [a]
inLine p = single (many (string " ") *> p <* filler)
filler :: Parser ()
filler = () <$ many (oneOf "an.0123456789 ")
positionParser :: Parser Position
positionParser =
fromString <$> count 3 digit
<?> "Position"
elementParser :: Parser Element
elementParser =
fromString <$> count 4 digit
<?> "Element"
|