forked from gen-smtp/gen_smtp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsmtp_rfc5322_parse.yrl
104 lines (86 loc) · 1.82 KB
/
smtp_rfc5322_parse.yrl
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
%% @doc Parser for [[https://datatracker.ietf.org/doc/html/rfc5322#section-3.4]] "mailbox-list" structure
Terminals
qstring
domain_literal
atom
'<'
'>'
','
'@'
'.'
':'
';'.
Nonterminals
root
mailbox_list
group
mailbox
name_addr
addr_spec
angle_addr
display_name
word
local_part
domain
dot_atom.
Rootsymbol
root.
root ->
mailbox_list : {mailbox_list, '$1'}.
root ->
group : {group, '$1'}.
group ->
display_name ':' ';' : {'$1', []}.
group ->
display_name ':' mailbox_list ';' : {'$1', '$3'}.
mailbox_list ->
mailbox : ['$1'].
mailbox_list ->
mailbox ',' mailbox_list : ['$1' | '$3'].
mailbox -> name_addr : '$1'.
mailbox -> addr_spec : {undefined, '$1'}.
name_addr ->
angle_addr : {undefined, '$1'}.
name_addr ->
display_name angle_addr : {'$1', '$2'}.
angle_addr ->
'<' addr_spec '>' : '$2'.
addr_spec ->
local_part '@' domain : {addr, '$1', '$3'}.
local_part ->
dot_atom : '$1'.
local_part ->
qstring : value_of('$1').
display_name ->
word : '$1'.
display_name ->
word display_name : '$1' ++ " " ++ '$2'.
word ->
dot_atom : '$1'.
word ->
qstring : unescape(value_of('$1')). % same as local_part, but with unescaping (is it necessary?)
domain ->
dot_atom : '$1'.
domain ->
domain_literal : value_of('$1').
dot_atom ->
atom : value_of('$1').
dot_atom ->
atom '.' dot_atom : value_of('$1') ++ "." ++ '$3'.
Erlang code.
-ignore_xref([{smtp_rfc5322_parse, return_error, 2}]).
%% Unescaping
unescape([$\\, C | Tail]) ->
%% unescaping
[C | unescape(Tail)];
unescape([$" | Tail]) ->
%% stripping quotes (only possible at start and end)
unescape(Tail);
unescape([C | Tail]) ->
[C | unescape(Tail)];
unescape([]) -> [].
value_of(Token) ->
try element(3, Token)
catch error:badarg ->
error({badarg, Token})
end.