Use the new import feature of Ragel for bringing in defines from the parser
[ragel.git] / test / mailbox2.rl
blobd84696dedbee8d21483201152286fbaf1489a420
1 /*
2  * @LANG: c++
3  * @CFLAGS: -I../aapl
4  */
6 #include <iostream>
7 #include <string.h>
9 using std::cin;
10 using std::cout;
11 using std::cerr;
12 using std::endl;
14 %%{
15         machine mailbox;
17         action prn_char { cout << *p; }
18         action prn_space { cout << ' '; }
19         action prn_word { cout.write(ws, p-ws); cout << ' '; }
20         action prn_addr1 { cout << "| "; cout.write(ws+1, p-ws-2); }
21         action prn_addr2 { cout << "| "; cout.write(ws, p-ws); }
22         action prn_tab { cout << '\t'; }
23         action prn_nl { cout << '\n'; }
24         action prn_separator { cout << "------\n"; } 
25         action prn_from { cout << "FROM\n"; }
26         action prn_to { cout << "TO\n"; }
27         action prn_subj { cout << "SUBJECT\n"; }
29         action start_word { ws = p; }
30         action start_headers { preserve = p; }
31         action end_headers {preserve = 0;}
33         day = upper lower{2};
34         month = upper lower{2};
35         year = digit{4};
36         time = digit{2} ':' digit{2} 
37                 ( ':' digit{2} )?;
38         letterZone = upper{3};
39         numZone = [+\-] digit{4};
40         zone = letterZone | numZone;
41         dayNum = ( digit | ' ' ) digit;
43         date = day ' ' month ' ' 
44                 dayNum ' ' time ' '
45                 ( 
46                         year | 
47                         year ' ' zone | 
48                         zone ' ' year
49                 );
51         fromLine = 'From ' [^\n]* ' ' 
52                 date '\n' @start_headers;
54         headerChar = print - [ :];
55         headersToPrint = 'From' | 
56                 'To' | 'Subject';
57         headersToConsume = 
58                 headerChar+ - headersToPrint;
60         consumeHeader = 
61                 headersToConsume ':'
62                 ( 
63                         [^\n] | 
64                         ( '\n' [ \t] )
65                 )*
66                 '\n';
68         addrWS = ( [ \t]+ | '\n' [ \t]+ );
69         addrComment = '(' [^)]* ')';
70         addrWord = [^"'@,<>() \t\n]+;
71         addrAddr1 = '<' [^>]* '>';
72         addrAddr2 = addrWord '@' addrWord;
73         addrString = 
74                 '"' [^"]* '"' |
75                 "'" [^']* "'";
77         addrItem = (
78                         addrAddr1 %prn_addr1 |
79                         addrAddr2 %prn_addr2 |
80                         addrWord %prn_word |
81                         addrString %prn_word
82                 ) >start_word;
84         address = ( 
85                         addrWS |
86                         addrComment |
87                         addrItem 
88                 )** >prn_tab;
90         addrHeader = ( 
91                         'From' %prn_from | 
92                         'To' %prn_to
93                 ) ':'
94                 address ( ',' @prn_nl address )*
95                 '\n' %prn_nl;
97         subjectHeader = 
98                 'Subject:' @prn_subj @prn_tab
99                 ' '* <:
100                 ( 
101                         [^\n] @prn_char  | 
102                         ( '\n' [ \t]+ ) %prn_space
103                 )**
104                 '\n' %prn_nl;
106         header = consumeHeader | 
107                 addrHeader | subjectHeader;
109         messageLine = 
110                 ( [^\n]* '\n' - fromLine );
112         main := (
113                         fromLine %prn_separator
114                         header* 
115                         '\n' @end_headers
116                         messageLine*
117                 )*;
118  }%%
120 %% write data;
122 #define BUFSIZE 8192
124 void test( char *buf )
126         int cs, len = strlen( buf );
127         char *preserve = 0, *ws = 0;
129         %% write init;
130         char *p = buf;
131         char *pe = p + len;
132         %% write exec;
134         if ( cs == mailbox_error )
135                 cerr << "ERROR" << endl;
137         if ( cs < mailbox_first_final )
138                 cerr << "DID NOT FINISH IN A FINAL STATE" << endl;
141 int main()
143         test(
144                 "From user@host.com Wed Nov 28 13:30:05 2001\n"
145                 "From: \"Adrian D. Thurston\" <thurston@cs.queensu.ca>\n"
146                 "Subject:   the squirrel has landed\n"
147                 "\n"
148                 "Message goes here. \n"
149                 "From (trick from line).\n"
150                 "From: not really a header\n"
151                 "\n"
152                 "From user2@host2.com Wed Nov 28 13:30:05 2001\n"
153                 "To: Edgar Allen Poe <ep@net.com> (da man)\n"
154                 "Subject:   (no subject) \n"
155                 "\n"
156                 "Message goes here. \n"
157                 "\n"
158         );
159         return 0;
162 #ifdef _____OUTPUT_____
163 ------
164 FROM
165         "Adrian D. Thurston" | thurston@cs.queensu.ca
166 SUBJECT
167         the squirrel has landed
168 ------
170         Edgar Allen Poe | ep@net.com
171 SUBJECT
172         (no subject) 
173 #endif