0 | module Text.Molfile.Parser
2 | import Data.Array.Mutable
3 | import Data.SortedMap as SM
6 | import Text.Molfile.Parser.KeyVal
7 | import Text.Molfile.Parser.Util
8 | import Text.Molfile.Parser.V2000
9 | import Text.Molfile.Parser.V3000
10 | import Text.Molfile.Writer.Util
12 | import public Text.Molfile.Parser.Stack
20 | ctabTrans : Lex1 q CSz CSTCK
23 | [ E H1 $
dfa [convline (star dot >> newline) h1]
24 | , E H2 $
dfa [convline (star dot >> newline) h2]
25 | , E H3 $
dfa [convline (star dot >> newline) h3]
26 | , E Counts $
dfa [mv30prefix 2 v3000 CountsV3, convline v2000 countsV2]
27 | , E SData $
dfa sdata
28 | , E SDValue $
dfa sdvalue
29 | , E EndMol $
dfa sdata
32 | , E Coords2 $
spaced Coords2 [conv coordinatesV2 coordsV2]
33 | , E Sym2 $
dfa $
valsN (fill 4 . (" "++) . dispIso) (setIso Chrg2) isos
34 | , E Chrg2 $
dfa [newline zeroes atomV2, line 2 (sdigits 5) chargeV2]
35 | , E Bnd2 $
dfa [line 0 (sdigits 6) bond]
36 | , E Prop2 $
dfa prop2
39 | , E CountsV3 $
spaced CountsV3 [cexpr' "COUNTS" ACount]
40 | , E EmptyV3 $
dfa emptyEnd
41 | , E ACount $
spaced ACount [conv (plus digit) newV3]
42 | , E BCount $
spaced BCount [conv (plus digit) bondsV3]
43 | , E CountEnd $
dfa [newlines' 2 (dots >> newline >> beginV3 "ATOM") Atom3]
45 | , E Atom3 $
dfa [cexpr' mv30 Index3]
46 | , E Index3 $
spaced Index3 [conv (plus digit) indexV3]
47 | , E Sym3 $
spaced Sym3 (vals dispIso (setIso Coords3) isos)
48 | , E Coords3 $
spaced Coords3 [conv coordinatesV3 coordsV3]
49 | , E AAMap $
dfa [conv' (plus ' ' >> plus digit) Prop3]
50 | , E Prop3 $
spaced Prop3 prop3
51 | , E AtomEnd $
dfa [newline (endV3 "ATOM") beginBondV3]
53 | , E BondBegin $
dfa [newline' (beginV3 "BOND") Bnd3]
54 | , E Bnd3 $
dfa [conv bondExprV3 bondV3]
55 | , E BndProp3 $
spaced BndProp3 bondProp3
56 | , E BondEnd $
dfa [newline' (endV3 "BOND") RestV3]
57 | , E SGroup $
dfa sgroup
58 | , E RestV3 $
dfa rest3
61 | ctabErr : Arr32 CSz (CSTCK q -> F1 q (BoundedErr MolErr))
62 | ctabErr = arr32 CSz (unexpected []) []
64 | ctabEOI : CST -> CSTCK q -> F1 q (Either (BoundedErr MolErr) (List Molfile))
66 | case st == H1 || st == CDone of
67 | False => case st == EndMol of
68 | False => arrFail CSTCK ctabErr st sk
69 | True => end >> getList sk.stack_ >>= pure . Right
70 | True => getList sk.stack_ >>= pure . Right
75 | ctab : P1 q (BoundedErr MolErr) (List Molfile)
76 | ctab = P H1 init ctabTrans snocChunk ctabErr ctabEOI
78 | parameters {auto has : Has (ParseError MolErr) es}
87 | readMolFrom : Origin -> String -> ChemRes es Molfile
89 | case parseString ctab o s of
90 | Left x => Left $
inject x
91 | Right [] => Right (MkMolfile "" "" "" (G 0 empty) [])
92 | Right [x] => Right x
94 | Left (inject $
toParseError o s (B (Custom MEntries) NoBounds))
98 | readMol : String -> ChemRes es Molfile
99 | readMol = readMolFrom Virtual
105 | readSDFFrom : Origin -> String -> ChemRes es (List Molfile)
106 | readSDFFrom o = mapFst inject . parseString ctab o
110 | readSDF : String -> ChemRes es (List Molfile)
111 | readSDF = readSDFFrom Virtual
114 | test : String -> IO ()
116 | case readMol {es = [ParseError MolErr]} s of
117 | Left (Here x) => putStrLn (interpolate x)
118 | Right (MkMolfile _ _ _ (G s _) _) => putStrLn "\{show s} atoms parsed"
128 | M V30 COUNTS 1 0 1 0 0
135 | M V30 1 SUP 0 LABEL=a0 ATOMS=(1 1)