aboutsummaryrefslogtreecommitdiffhomepage
path: root/scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs
diff options
context:
space:
mode:
Diffstat (limited to 'scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs')
-rw-r--r--scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs99
1 files changed, 99 insertions, 0 deletions
diff --git a/scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs b/scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs
new file mode 100644
index 0000000..39a7ad4
--- /dev/null
+++ b/scaffolder/src/Text/Edifact/Scaffolder/Segments/Specification.hs
@@ -0,0 +1,99 @@
1module Text.Edifact.Scaffolder.Segments.Specification
2 ( -- *
3 specificationParser
4 , listCompositesAndSimples
5 ) where
6
7import Text.Edifact.Scaffolder.Commons
8import Text.Edifact.Scaffolder.Segments.Types
9
10import Text.Parsec as P (anyChar, choice,
11 count, digit,
12 endOfLine, many,
13 many1, manyTill,
14 oneOf, skipMany,
15 string, try,
16 upper, (<?>))
17import Text.Parsec.String (Parser)
18
19specificationParser :: Parser ((SegmentCode, SegmentName), [Dependency])
20specificationParser = do
21 segmentInfo <- scanUntil [ segmentParser ]
22 dependencies <- scan [ inLine dependencyParser ] <?> "Segments specification"
23 pure (segmentInfo, dependencies)
24
25listCompositesAndSimples :: Parser (SegmentCode, [Element])
26listCompositesAndSimples = do
27 parsed <- specificationParser
28 pure (fst $ fst parsed, dependencyElement <$> snd parsed)
29
30segmentParser :: Parser (SegmentCode, SegmentName)
31segmentParser = do
32 _ <- count 6 (oneOf "+*#|X ")
33 skipMany (string " ")
34 code <- SegmentCode <$> count 3 upper
35 _ <- count 2 (string " ")
36 skipMany (string " ")
37 name <- SegmentName <$> manyTill anyChar (() <$ try endOfLine)
38 pure (code, name)
39
40dependencyParser :: Parser Dependency
41dependencyParser =
42 Dependency <$> positionParser
43 <* many1 (oneOf "+*#|-X ")
44 <*> elementParser
45 <?> "Dependency"
46
47inLine :: Parser a -> Parser [a]
48inLine p = single (many (string " ") *> p)
49
50positionParser :: Parser Position
51positionParser =
52 fromString <$> count 3 digit
53 <?> "Position"
54
55elementParser :: Parser Element
56elementParser =
57 choice [ compositeParser
58 , simpleParser
59 ]
60 <?> "Element"
61
62compositeParser :: Parser Element
63compositeParser = Composite <$> compositeCodeParser
64 <* many (string " ")
65 <*> stringToPresenceParser
66 <* many1 (string " ")
67 <*> presenceParser
68 <* string " "
69 <* many (oneOf " 0123456789")
70 <?> "Composite"
71
72simpleParser :: Parser Element
73simpleParser = Simple <$> (fromString <$> count 4 digit)
74 <* many1 (string " ")
75 <*> stringToPresenceParser
76 <* many1 (string " ")
77 <*> presenceParser
78 <* string " "
79 <* many (oneOf " 0123456789")
80 <*> simpleTypeParser
81 <*> simpleLengthParser
82 <?> "Simple"
83
84simpleTypeParser :: Parser SimpleType
85simpleTypeParser = choice [ Alphanumeric <$ string "an"
86 , Alphabetic <$ string "a"
87 , Numeric <$ string "n"
88 ] <?> "SimpleType"
89
90simpleLengthParser :: Parser SimpleLength
91simpleLengthParser = choice [ UpTo <$> fmap fromString (string ".." >> many1 digit)
92 , Exactly <$> (fromString <$> many1 digit)
93 ] <?> "SimpleLength"
94
95compositeCodeParser :: Parser CompositeCode
96compositeCodeParser = do
97 initial <- oneOf "CE"
98 rest <- count 3 digit
99 pure (fromString (initial : rest))