module Mail
grammar RFC2822
include RFC2822Obsolete
rule ALPHA
[a-zA-Z]
end
rule DIGIT
[0-9]
end
rule DQUOTE
'"'
end
rule LF
"\n"
end
rule CR
"\r"
end
rule CRLF
"\r\n"
end
rule WSP
[\x09\x20]
end
rule FWS # Folding white space
(WSP* CRLF WSP+) / (CRLF WSP+) / obs_FWS
end
rule CFWS
(FWS* comment)* FWS?
end
rule NO_WS_CTL
[\x01-\x08] / # US-ASCII control characters
[\x0B-\x0C] / # that do not include the
[\x0E-\x1F] / # carriage return, line feed,
[\x7f] # and white space characters
end
rule specials
"(" / ")" / # Special characters used in
"<" / ">" / # other parts of the syntax
"[" / "]" /
":" / ";" /
"@" / '\\' /
"," / "." /
DQUOTE
end
rule ctext
NO_WS_CTL / # Non white space controls
[\x21-\x27] / # The rest of the US-ASCII
[\x2a-\x5b] / # characters not including "(",
[\x5d-\x7e] # ")", or "\"
end
rule ccontent
ctext / quoted_pair / comment
end
rule comment
"(" ( FWS? ccontent )* FWS? ")"
end
rule atext
ALPHA / DIGIT / # Any character except controls,
"!" / "#" / # SP, and specials.
"$" / "%" / # Used for atoms
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
end
rule mtext
(atext / ".")+
end
rule atom
CFWS? atext+ CFWS?
end
rule dot_atom
CFWS? dot_atom_text CFWS?
end
rule local_dot_atom
CFWS? local_dot_atom_text CFWS?
end
rule message_id_text
mtext+
end
rule dot_atom_text
(domain_text "."?)+
end
rule local_dot_atom_text
("."* domain_text "."*)+
end
rule domain_text
(DQUOTE (FWS? quoted_domain)+ FWS? DQUOTE) / atext+
end
rule quoted_domain
qdcontent / "\\" text
end
rule qdcontent
NO_WS_CTL / # Non white space controls
[\x21] / # The rest of the US-ASCII
[\x23-\x45] / # characters not including "\"
[\x47-\x5b] / # or the "." or the
[\x5d-\x7e] # double quote character
end
rule phrase
obs_phrase / word+
end
rule word
atom / quoted_string
end
rule phrase_list
first_phrase:phrase other_phrases:("," FWS* phrase_value:phrase)*
end
rule domain_literal
CFWS? "[" (FWS? dcontent)* FWS? "]" CFWS?
end
rule dcontent
dtext / quoted_pair
end
rule dtext
NO_WS_CTL / # Non white space controls
[\x21-\x5a] / # The rest of the US-ASCII characters
[\x5e-\x7e] # not including "[", "]", or "\"
end
rule angle_addr
CFWS? "<" addr_spec ">" CFWS? / obs_angle_addr
end
rule addr_spec
(local_part "@" domain) / local_part
end
rule local_part
local_dot_atom / quoted_string / obs_local_part
end
rule domain
dot_atom / domain_literal / obs_domain
end
rule group
group_name:display_name ":" group_list:(mailbox_list_group / CFWS)? ";" CFWS?
end
rule mailbox_list_group
mailbox_list {
def addresses
[first_addr] + other_addr.elements.map { |o| o.addr_value }
end
}
end
rule quoted_string
CFWS? DQUOTE quoted_content:(FWS? qcontent)+ FWS? DQUOTE CFWS?
end
rule qcontent
qtext / quoted_pair
end
rule quoted_pair
("\\" text) / obs_qp
end
rule qtext
NO_WS_CTL / # Non white space controls
[\x21] / # The rest of the US-ASCII
[\x23-\x5b] / # characters not including "\"
[\x5d-\x7e] # or the quote character
end
rule text
[\x01-\x09] / # Characters excluding CR and LF
[\x0b-\x0c] /
[\x0e-\x7e] /
obs_text
end
rule display_name
phrase
end
rule name_addr
display_name angle_addr / angle_addr
end
rule mailbox_list
(first_addr:mailbox other_addr:(("," / ";") addr_value:mailbox)*) / obs_mbox_list
end
rule mailbox
name_addr / addr_spec
end
rule address
group {
def dig_comments(comments, elements)
elements.each { |elem|
if elem.respond_to?(:comment)
comments << elem.comment
end
dig_comments(comments, elem.elements) if elem.elements
}
end
def comments
comments = []
dig_comments(comments, elements)
comments
end
} /
mailbox {
def dig_comments(comments, elements)
elements.each { |elem|
if elem.respond_to?(:comment)
comments << elem.comment
end
dig_comments(comments, elem.elements) if elem.elements
}
end
def comments
comments = []
dig_comments(comments, elements)
comments
end
}
end
rule address_list
first_addr:address? other_addr:(FWS* ("," / ";") FWS* addr_value:address?)*
end
rule date_time
( day_of_week ",")? date FWS time CFWS?
end
rule day_of_week
(FWS? day_name) / obs_day_of_week
end
rule day_name
"Mon" / "Tue" / "Wed" / "Thu" /
"Fri" / "Sat" / "Sun"
end
rule date
day month year
end
rule year
DIGIT DIGIT DIGIT DIGIT / obs_year
end
rule month
(FWS month_name FWS) / obs_month
end
rule month_name
"Jan" / "Feb" / "Mar" / "Apr" /
"May" / "Jun" / "Jul" / "Aug" /
"Sep" / "Oct" / "Nov" / "Dec"
end
rule day
(FWS? DIGIT DIGIT?) / obs_day
end
rule time
time_of_day FWS zone
end
rule time_of_day
hour ":" minute ( ":" second )?
end
rule hour
DIGIT DIGIT / obs_hour
end
rule minute
DIGIT DIGIT / obs_minute
end
rule second
DIGIT DIGIT / obs_second
end
rule zone
(( "+" / "-" ) DIGIT DIGIT DIGIT DIGIT) / obs_zone
end
rule return
path CRLF
end
rule path
((CFWS)? "<" ((CFWS)? / addr_spec) ">" (CFWS)?) / obs_path
end
rule received
name_val_list ";" date_time CRLF
end
rule name_val_list
(CFWS)? (name_val_pair (CFWS name_val_pair)*)
end
Loading ...