1
+ functor
2
+ export
3
+ 'class' : MessageParser
4
+ prepare
5
+ IsSpace = Char.isSpace
6
+
7
+ fun {DropInitialSpaces L}
8
+ case L
9
+ of H| T andthen (H== & orelse H== &\t) then
10
+ {DropInitialSpaces T}
11
+ else L end
12
+ end
13
+
14
+ class MessageParser
15
+ attr
16
+ AcceptCRLF : false
17
+ AcceptLF : false
18
+ AcceptCR : false
19
+
20
+ meth acceptCRLF(B) AcceptCRLF< - B end
21
+ meth acceptLF( B) AcceptLF < - B end
22
+ meth acceptCR( B) AcceptCR < - B end
23
+
24
+ meth messageStart() skip end
25
+ meth messageEnd() skip end
26
+ meth messageHeader(Header Value) skip end
27
+ meth messageBody() skip end
28
+
29
+ meth parse(L)
30
+ {self messageStart}
31
+ MessageParser,MaybeHeader(L)
32
+ {self messageEnd}
33
+ end
34
+
35
+ meth EOL(L $)
36
+ case L
37
+ of &\r|&\n| L andthen @AcceptCRLF then L
38
+ [] &\r |L andthen @AcceptCR then L
39
+ [] &\n| L andthen @AcceptLF then L
40
+ else unit end
41
+ end
42
+
43
+ meth MaybeHeader(L)
44
+ if L== nil then skip
45
+ elsecase MessageParser,EOL(L $)
46
+ of unit then H in MessageParser,Header(L H H)
47
+ [] L then {self messageBody(L)} end
48
+ end
49
+
50
+ meth Header(L Head Tail)
51
+ case L
52
+ of H| T then
53
+ if H== &: then V in
54
+ Tail= nil
55
+ MessageParser,AfterSemiColon(
56
+ {DropInitialSpaces T}
57
+ Head V V)
58
+ elseif {IsSpace H} then
59
+ Tail= nil
60
+ MessageParser,AfterHeader(T Head)
61
+ else Tail2 in
62
+ Tail= (H| Tail2)
63
+ MessageParser,Header(T Head Tail2)
64
+ end
65
+ else
66
+ raise messageParser(unexpectedEndOfMessage) end
67
+ end
68
+ end
69
+
70
+ meth AfterHeader(L Header)
71
+ case L
72
+ of H| T then
73
+ if H== &: then H in
74
+ MessageParser,AfterSemiColon(
75
+ {DropInitialSpaces T} Header H H)
76
+ elseif {IsSpace H} then
77
+ MessageParser,AfterHeader(T Header)
78
+ else
79
+ raise messageParser(expectedSpaceOrSemiColon:L) end
80
+ end
81
+ else
82
+ raise messageParser(unexpectedEndOfMessage) end
83
+ end
84
+ end
85
+
86
+ meth AfterSemiColon(L Header Value Tail)
87
+ case MessageParser,EOL(L $)
88
+ of unit then
89
+ case L
90
+ of H| T then Tail2 in
91
+ Tail= (H| Tail2)
92
+ MessageParser,AfterSemiColon(T Header Value Tail2)
93
+ else
94
+ Tail= nil
95
+ {self messageHeader(Header Value)}
96
+ end
97
+ [] L then
98
+ case L
99
+ of H| T andthen (H== & orelse H== &\t) then Tail2 in
100
+ Tail= (H| Tail2)
101
+ MessageParser,AfterSemiColon(T Header Value Tail2)
102
+ else
103
+ Tail= nil
104
+ {self messageHeader(Header Value)}
105
+ MessageParser,MaybeHeader(L)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
0 commit comments