1 ///
2 module imap.grammar;
3 
4 /++
5     This code is not currently used or required.  An experiment with replacing custom parsing code by
6     a PEG grammer.
7 +/
8 
9 version (SIL) :
10     import pegged.grammar;
11 
12 
13 ///
14 public PT tee(PT)(PT p) {
15     import std.stdio;
16     writeln("****");
17     writeln(p);
18     writeln("****");
19     return p;
20 }
21 
22 
23 mixin(grammar(`
24 Imap:
25 	Expr			<-  ((whitespace)* Response)*
26 	whitespace		<-	[\r\n \t]
27 	dash			<-	"-"
28 	plus			<-	"+"
29 	colon			<-	":"
30 	comma			<-	","
31 	bang            <-	"!"
32 	star			<-	"*"
33 	percent			<-	"%"
34 	LParens			<-	"("
35 	RParens			<-	")"
36 
37 	LowerCase		<-	[a-z]
38 	UpperCase		<-	[A-Z]
39 	Alpha			<-	[a-zA-Z]
40 	HexDigit		<-	[a-f0-9A-F]
41 	Digit			<-	[0-9]
42 	DigitNonZero	<-	[1-9]
43 	Digits			<~	[0-9]+
44 	Zero			<-	"0"
45 	Number			<-	Digits # unsigned 32 bit/check size
46 	NzNumber		<-	!Zero Digits
47 	Underscore		<-	"_"
48 	Base64Char		<-	[a-zA-Z0-9\+\/]
49 	Base64Terminal	<-	(Base64Char Base64Char "==") / (Base64Char Base64Char Base64Char "=")
50 	Base64			<~	Base64Char Base64Char Base64Char Base64Char Base64Terminal
51 	StrChar         <~ backslash doublequote
52 	                    / backslash backslash
53 	                    / backslash [abfnrtv]
54 	                    / (!doublequote .)
55 	CRLF			<-	"\r" "\n"
56 	TextChar		<-	!CRLF .
57 	Text			<-	Text+
58 	Char			<-	!"\0" .
59 	#literal			<-	"{" Number "}" CRLF Char*
60 	Literal			<-	Alpha*
61 	QuotedSpecial	<-	doublequote / backslash
62 	QuotedChar		<-	(!QuotedSpecial TextChar) / (backslash QuotedSpecial)
63 	Quoted			<~	doublequote QuotedChar* doublequote
64 	String			<-	Quoted / Literal
65 	CTL				<-	"\a" "\b"
66 	ListWildCard	<-	"%" / star
67 	RespSpecial		<- "]"
68 	AtomSpecial		<-	LParens / RParens / "{" / space / CTL / ListWildCard / QuotedSpecial / RespSpecial
69 	AtomChar		<-	!AtomSpecial Char
70 	Atom			<-	AtomChar+
71 	AstringChar		<-	AtomChar / RespSpecial
72 	Astring			<-	AstringChar+ / String
73 	Nil				<-	"NIL"
74 	Nstring			<-	Nil / String
75 	AddrName		<-	Nstring
76 	AddrAdl			<-	Nstring
77 	AddrMailbox		<-	Nstring
78 	AddrHost		<-	Nstring
79 	Address			<-	LParens AddrName space AddrAdl space AddrMailbox space AddrHost RParens
80 	Envelope		<-	"(" EnvDate space EnvSubject space EnvFrom space EnvSender space EnvReplyTo space EnvTo space EnvCC space EnvBCC space EnvInReplyTo space EnvMessageId ")"
81 	EnvBCC			<-	("(" Address+ ")") / Nil
82 	EnvCC			<-	( "(" Address+ ")" ) / Nil
83 	EnvDate			<-	Nstring
84 	EnvFrom			<-	( "(" Address+ ")" ) / Nil
85 	EnvInReplyTo	<-	Nstring
86 	EnvMessageId	<-	Nstring
87 	EnvReplyTo		<-	( "(" Address+ ")" ) / Nil
88 	EnvSender		<-	(LParens Address+ RParens ) / Nil
89 	EnvSubject		<- Nstring
90 	EnvTo			<-	(LParens Address+ RParens) / Nil
91 	Inbox			<-	"INBOX" / "inbox" # FIXME - should be completely case insensitive
92 	Mailbox			<-	Inbox / Astring
93 	FlagExtension	<-	backslash Atom
94 	FlagKeyword		<-	Atom
95 	Flag			<-	"\\Answered" / "\\Flagged" / "\\Deleted" / "\\Seen" / "\\Draft" / FlagKeyword / FlagExtension
96 	FlagList		<-	LParens Flag (space Flag)* RParens
97 	DateDay			<-	Digit Digit / Digit
98 	DateDayFixed	<-	Digit Digit / (space Digit)
99 	DateMonth		<-	"Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
100 	DateYear		<-	Digit Digit Digit Digit
101 	DateText		<-	DateDay dash DateMonth dash DateYear
102 	Time			<-	Digit Digit colon Digit Digit colon Digit Digit
103 	Zone			<-	( "+" / "-" ) Digit Digit Digit Digit
104 	Date			<-	DateText / (doublequote DateText doublequote)
105 	DateTime		<-	doublequote DateDayFixed dash DateMonth dash DateYear space Time space Zone doublequote
106 
107 	HeaderFldName	<-	Astring
108 	HeaderList		<-	"(" HeaderFldName (space HeaderFldName)* ")"
109 	ListMailbox		<-	AtomChar / ListWildCard / RespSpecial
110 	MailboxData		<-	"FLAGS" space FlagList / "LIST" space MailboxList / "LSUB" space MailboxList / "SEARCH" (space NzNumber)*  "STATUS" space Mailbox space "(" (StatusAttList)? ")" / Number space "EXISTS" / Number space "RECENT"
111 	MailboxList		<-	LParens (MbxListFlags)? RParens (space doublequote QuotedChar doublequote) / Nil space Mailbox
112 	MbxListFlags	<-	((MbxListOFlag space)* MbxListSFlag (MbxListOFlag)*) / (MbxListOFlag (space MbxListOFlag)*)
113 	MbxListOFlag	<-	backslash "Noinferiors" / FlagExtension
114 	MbxListSFlag	<-	backslash "Noselect" / backslash "Marked" / backslash "Unmarked"
115 	MessageData		<-	NzNumber space ("EXPUNGE" / ("FETCH" space MsgAtt))
116 	MsgAtt			<-	LParens (MsgAttDynamic / MsgAttStatic) (space MsgAttDynamic / MsgAttStatic)* RParens
117 	MsgAttDynamic	<-	"FLAGS" space (FlagFetch (space FlagFetch)*)? RParens
118 	MsgAttStatic	<-	"ENVELOPE" space Envelope /
119 						"INTERNALDATE" space DateTime /
120 						"RFC822" (".HEADER" / ".TEXT")? space Nstring /
121 						"RFC822.SIZE" space Number /
122 						"BODY" ("STRUCTURE")? space Body /
123 						"BODY" Section ("<" Number ">")? space Nstring /
124 						"UID" space UniqueId
125 	StatusAttList	<-	StatusAtt space Number (space StatusAtt space Number)*
126 	UserID			<-	Astring
127 	Password		<-	Astring
128 	Tag				<-	( !"+" AstringChar)+
129 	UniqueId		<-	NzNumber
130 	SearchKey		<-	"ALL" "ANSWERED" "BCC" space Astring / "BEFORE" space Date / "BODY" space Astring / "CC" space Astring / "DELETED" / "FLAGGED" / "FROM" space Astring / "KEYWORD" space FlagKeyword / "NEW" / "OLD" / "ON" space Date / "RECENT" / "SEEN" / "SINCE" space Date / "SUBJECT" space Astring / "TEXT" space  Astring / "TO" space Astring / "UNANSWERED" / "UNDELETED" / "UNFLAGGED" / "UNKEYWORD" space FlagKeyword / "UNSEEN" / "DRAFT" / "HEADER" space HeaderFldName space Astring / "LARGER" space Number / "NOT" space SearchKey / "OR" space SearchKey / "SENTON" space Date / "SENTSINCE" space Date / "SMALLER" space Number / "UID" space SequenceSet / "UNDRAFT" / SequenceSet/ "(" SearchKey (space SearchKey)* ")"
131 	Section			<- "[" SectionSpec? "]"
132 	SectionMsgText	<-	"HEADER" / "HEADER.FIELDS" ".NOT"? space HeaderList / "TEXT"
133 	SectionPart		<-	NzNumber ("." NzNumber)*
134 	SectionSpec		<-	SectionMsgText / SectionPart / ("." SectionText)?
135 	SectionText		<-	SectionMsgText / "MIME"
136 	SeqNumber		<-	NzNumber / star
137 	SeqRange		<-	SeqNumber colon SeqNumber
138 	SequenceSet		<-	(SeqNumber / SeqRange) (comma SequenceSet)*
139 	FetchAtt		<-	"ENVELOPE" / "FLAGS" / "INTERNALDATE" / "RFC822" / (".HEADER" / ".SIZE" / ".TEXT")? / "BODY" ("STRUCTURE")? / "UID" / "BODY" Section ("<" Number "." NzNumber ">" )?
140 	StoreAttFlags	<-	("+" / "-") "FLAGS" (".SILENT")? space (FlagList / (Flag (space Flag)*))
141 	Uid				<-	"UID" space (Copy/Fetch/Search/Store)
142 
143 # Commands
144 	AuthType		<-	Atom
145 	Authenticate	<-	"AUTHENTICATE" space AuthType (CRLF Base64)*
146 	Capability		<-	("AUTH=" AuthType) / Atom
147 	CapabilityData	<-	"CAPABILITY" (space Capability)* space "IMAP4rev1" (space Capability)*
148 	Append			<-	"APPEND" space Mailbox (space FlagList)? (space DateTime) (space Literal)
149 	Copy			<-	"COPY" space SequenceSet space Mailbox
150 	Create			<-	"CREATE" space Mailbox
151 	Delete			<-	"DELETE" space Mailbox
152 	Examine			<-	"EXAMINE" space Mailbox
153 	FlagFetch		<-	Flag / "\\Recent"
154 	FlagPerm		<-	Flag / (backslash star)
155 	Fetch			<-	"FETCH" space SequenceSet space ("ALL" / "FULL" / "FAST" / FetchAtt / "(" FetchAtt (space FetchAtt)* ")" )
156 	List			<-	"LIST" space Mailbox space ListMailbox
157 	Login			<-	"LOGIN" space UserID Password
158 	Lsub			<-	"LSUB" space Mailbox space ListMailbox
159 	Rename			<-	"RENAME" space Mailbox space Mailbox
160 	Search			<-	"SEARCH" (space "CHARSET" space Astring)? (space SearchKey)+
161 	Select			<-	"SELECT" space Mailbox
162 	StatusAtt		<-	"MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" / "UNSEEN"
163 	Status			<-	"STATUS" space Mailbox space LParens StatusAtt (space StatusAtt)* RParens
164 	Subscribe		<-	"SUBSCRIBE" space Mailbox
165 	Unsubscribe		<-	"UNSUBSCRIBE" space Mailbox
166 	XCommand		<-	"X" Atom Text #FIXME
167 
168 	Command			<-	Tag space (CommandAny / CommandAuth / CommandNonAuth / CommandSelect) CRLF
169 	CommandAuth		<-	Append / Create / Delete / Examine / List / Lsub / Rename/ Select / Status / Subscribe / Unsubscribe
170 	CommandNonAuth	<-	Login / Authenticate / "STARTTLS"
171 	CommandAny		<-	"CAPABILITY" / "LOGOUT" / "NOOP" / XCommand
172 	CommandSelect	<-	"CHECK" / "CLOSE" / "EXPUNGE" / Copy / Fetch / Store / Uid / Search
173 
174 # Response
175 	ContinueReq		<-	plus space (RespText / Base64) CRLF
176 	ResponseData	<-	star space (RespCondState / RespCondBye / MailboxData / MessageData / CapabilityData) CRLF
177 	ResponseTagged	<-	star space RespCondState CRLF
178 	ResponseFatal	<-	star RespCondBye CRLF
179 	RespCondAuth	<-	("OK" / "PREAUTH") space RespText
180 	RespCondBye		<-	"BYE" space RespText
181 	RespCondState	<-	( "OK" / "NO" / "BAD" ) / RespText
182 	RespText		<-	( "[" RespTextCode "]" space )? Text
183 	RespTextCode	<-	"ALERT" / 
184 						"BADCHARSET" (space LParens Astring (space Astring)* RParens )? /
185 						CapabilityData /
186 					    "PARSE" /
187 						"PERMANENTFLAGS" space LParens (FlagPerm (space FlagPerm))* RParens /
188 						"READ-ONLY" /
189 						"READ-WRITE" /
190 						"TRYCREATE" /
191 						"UIDNEXT" space NzNumber /
192 						"UIDVALIDITY" space NzNumber /
193 						"UNSEEN" space NzNumber /
194 						Atom (space ( !"]" TextChar+)?)
195 	ResponseDone	<-	ResponseTagged / ResponseFatal
196 
197 	Response		<-	(ContinueReq / ResponseData)* ResponseDone
198 	Store			<-	"STORE" space SequenceSet space StoreAttFlags
199 
200 	BodyFields		<-	BodyFieldParam space BodyFieldID space BodyFieldDesc space BodyFieldEnc space BodyFieldOctets
201 	BodyFieldDesc	<-	Nstring
202 	BodyFieldDsp	<-	( "(" String space BodyFieldParam ")" ) / Nil
203 	BodyFieldEnc	<-	(doublequote ("7BIT"/"8BIT"/"BINARY"/"BASE64"/"QUOTED-PRINTABLE") doublequote) / String
204 	BodyFieldID		<-	Nstring
205 	BodyFieldLang	<-	Nstring / "(" String (space String)* ")"
206 	BodyFieldLoc	<-	Nstring
207 	BodyFieldLines	<-	Number
208 	BodyFieldMD5	<-	Nstring
209 	BodyFieldOctets	<-	Number
210 	BodyFieldParam	<-	("(" String space String (space String space String)* ")") / Nil
211 	BodyExtension	<-	Nstring / Number / ("(" BodyExtension (space BodyExtension)* ")" )
212 	BodyExtSinglePart <- BodyFieldMD5 (space BodyFieldDsp (space BodyFieldLang (space BodyFieldLoc (space BodyExtension)* )? )? )?
213 	BodyExtMultiPart <- BodyFieldParam (space BodyFieldDsp (space BodyFieldLang (space BodyFieldLoc (space BodyExtension)* )? )? )?
214 	BodyTypeSinglePart <- (BodyTypeBasic / BodyTypeMsg / BodyTypeText) (space BodyExtSinglePart)?
215 	BodyTypeBasic	<-	MediaBasic space BodyFields
216 	BodyTypeMultiPart <- Body+ space MediaSubType (space BodyExtMultiPart)?
217 	BodyTypeMsg		<-	MediaMessage space BodyFields space Envelope space Body space BodyFieldLines
218 	BodyTypeText	<-	MediaText space BodyFields space BodyFieldLines
219 	Body			<-	LParens (BodyTypeSinglePart / BodyTypeMultiPart) RParens
220 
221 	MediaBasic		<-	(( doublequote ("APPLICATION" / "AUDIO" / "IMAGE" / "MESSAGE" / "VIDEO") doublequote) / String) space MediaSubType
222 	MediaMessage	<-	doublequote "MESSAGE" doublequote space doublequote "RFC822" doublequote
223 	MediaSubType	<- String
224 	MediaText		<-	doublequote "TEXT" doublequote space MediaSubType
225 	Greeting		<-	star space (RespCondAuth / RespCondBye) CRLF
226 `));