diff options
Diffstat (limited to 'test/ragel.d/mailbox2.rl')
-rw-r--r-- | test/ragel.d/mailbox2.rl | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/test/ragel.d/mailbox2.rl b/test/ragel.d/mailbox2.rl new file mode 100644 index 00000000..6b9d7359 --- /dev/null +++ b/test/ragel.d/mailbox2.rl @@ -0,0 +1,171 @@ +/* + * @LANG: c++ + */ + +#include <iostream> +#include <string.h> + +using std::cin; +using std::cout; +using std::cerr; +using std::endl; + +%%{ + machine mailbox; + + action prn_char { cout << *p; } + action prn_space { cout << ' '; } + action prn_word { cout.write(ws, p-ws); cout << ' '; } + action prn_addr1 { cout << "| "; cout.write(ws+1, p-ws-2); } + action prn_addr2 { cout << "| "; cout.write(ws, p-ws); } + action prn_tab { cout << '\t'; } + action prn_nl { cout << '\n'; } + action prn_separator { cout << "------\n"; } + action prn_from { cout << "FROM\n"; } + action prn_to { cout << "TO\n"; } + action prn_subj { cout << "SUBJECT\n"; } + + action start_word { ws = p; } + action start_headers { } + action end_headers { } + + day = upper lower{2}; + month = upper lower{2}; + year = digit{4}; + time = digit{2} ':' digit{2} + ( ':' digit{2} )?; + letterZone = upper{3}; + numZone = [+\-] digit{4}; + zone = letterZone | numZone; + dayNum = ( digit | ' ' ) digit; + + date = day ' ' month ' ' + dayNum ' ' time ' ' + ( + year | + year ' ' zone | + zone ' ' year + ); + + fromLine = 'From ' [^\n]* ' ' + date '\n' @start_headers; + + headerChar = print - [ :]; + headersToPrint = 'From' | + 'To' | 'Subject'; + headersToConsume = + headerChar+ - headersToPrint; + + consumeHeader = + headersToConsume ':' + ( + [^\n] | + ( '\n' [ \t] ) + )* + '\n'; + + addrWS = ( [ \t]+ | '\n' [ \t]+ ); + addrComment = '(' [^)]* ')'; + addrWord = [^"'@,<>() \t\n]+; + addrAddr1 = '<' [^>]* '>'; + addrAddr2 = addrWord '@' addrWord; + addrString = + '"' [^"]* '"' | + "'" [^']* "'"; + + addrItem = ( + addrAddr1 %prn_addr1 | + addrAddr2 %prn_addr2 | + addrWord %prn_word | + addrString %prn_word + ) >start_word; + + address = ( + addrWS | + addrComment | + addrItem + )** >prn_tab; + + addrHeader = ( + 'From' %prn_from | + 'To' %prn_to + ) ':' + address ( ',' @prn_nl address )* + '\n' %prn_nl; + + subjectHeader = + 'Subject:' @prn_subj @prn_tab + ' '* <: + ( + [^\n] @prn_char | + ( '\n' [ \t]+ ) %prn_space + )** + '\n' %prn_nl; + + header = consumeHeader | + addrHeader | subjectHeader; + + messageLine = + ( [^\n]* '\n' - fromLine ); + + main := ( + fromLine %prn_separator + header* + '\n' @end_headers + messageLine* + )*; + }%% + +%% write data; + +#define BUFSIZE 8192 + +void test( const char *buf ) +{ + int cs, len = strlen( buf ); + const char *ws = 0; + + %% write init; + const char *p = buf; + const char *pe = p + len; + %% write exec; + + if ( cs == mailbox_error ) + cerr << "ERROR" << endl; + + if ( cs < mailbox_first_final ) + cerr << "DID NOT FINISH IN A FINAL STATE" << endl; +} + +int main() +{ + test( + "From user@host.com Wed Nov 28 13:30:05 2001\n" + "From: \"Adrian D. Thurston\" <thurston@complang.org>\n" + "Subject: the squirrel has landed\n" + "\n" + "Message goes here. \n" + "From (trick from line).\n" + "From: not really a header\n" + "\n" + "From user2@host2.com Wed Nov 28 13:30:05 2001\n" + "To: Edgar Allen Poe <ep@net.com> (da man)\n" + "Subject: (no subject) \n" + "\n" + "Message goes here. \n" + "\n" + ); + return 0; +} + +##### OUTPUT ##### +------ +FROM + "Adrian D. Thurston" | thurston@complang.org +SUBJECT + the squirrel has landed +------ +TO + Edgar Allen Poe | ep@net.com +SUBJECT + (no subject) |