-- added unit test for HTTP GET
[bkell-clj.git] / etc / cc / bkeeping.cc
blob10550224bac8ca1118e5e9f0ddadf9dcaae2f2fe
2 Package com.interrupt.bookkeeping.cc;
5 Helpers
7 all = [0 .. 127];
9 lowercase = ['a' .. 'z'];
10 uppercase = ['A' .. 'Z'];
11 digit = ['0' .. '9'];
12 hex_digit = [ digit+ [['a' .. 'f'] + ['A' .. 'F']] ];
14 tab = 9;
15 cr = 13;
16 lf = 10;
17 eol = cr lf | cr | lf; // This takes care of different platforms
18 dash = '-';
19 dot = '.';
20 forwardslash = '/';
21 backslash = '\';
22 asterix = 42;
23 equals_helper = '=';
24 colon_helper = ':';
25 ats = '@';
26 underscore = '_';
28 single_quote = ''';
29 double_quote = '"';
31 lsquare_bracket = '[';
32 rsquare_bracket = ']';
34 left_bracket = '(';
35 right_bracket = ')';
38 ws = (' ' | tab | eol);
42 States
43 bkeeping, freetext; // we need a way to ignore commands in freetext
46 Tokens
49 //** VARIABLE
50 {bkeeping} var = 'var';
53 //** COMMANDS
54 {bkeeping} create = 'create';
55 {bkeeping} add = 'add';
56 {bkeeping} update = 'update';
57 {bkeeping} remove = 'remove';
58 {bkeeping} reverse = 'reverse';
59 {bkeeping} find = 'find';
60 {bkeeping} list = 'list';
62 {bkeeping} print = 'print';
63 {bkeeping} commit = 'commit';
65 {bkeeping} load = 'load';
66 {bkeeping} login = 'login';
67 {bkeeping} logout = 'logout';
68 {bkeeping} exit = 'exit';
70 {bkeeping} semicolon = ( 59 )?;
72 whitespace = (' ' | tab | eol);
73 comment_line = forwardslash forwardslash all* eol;
74 comment_block = forwardslash asterix all* asterix forwardslash;
77 //** COMMAND OPTIONS
78 entry_opt = '-entry' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
79 entryid_opt = '-entryid' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
80 account_opt = '-account' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
81 accountid_opt = '-accountid' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
82 journal_opt = '-journal' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
83 name_opt = '-name' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
84 type_opt = '-type' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
85 counterweight_opt = '-counterWeight' ws+ lowercase+;
86 amount_opt = '-amount' ws+ digit+'.'digit+;
87 id_opt = '-id' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
88 entrynum_opt = '-entrynum' ws+ digit*;
89 date_opt = '-date' ws+ digit+'/'digit+'/'digit+;
90 file_opt = '-F' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
92 group_opt = '-group' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
93 uname_opt = '-username' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
94 passwd_opt = '-password' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
95 groupid_opt = '-groupid' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
96 userid_opt = '-userid' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
97 currency_opt = '-currency' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
98 returninput_opt = '-returninput' ws+ ( lowercase | uppercase | dash | colon_helper | ats | underscore | digit | dot )*;
102 //** COMMAND TOKENS
103 system_tok = 'system';
104 debit_tok = 'debit';
105 credit_tok = 'credit';
106 entry_tok = 'entry';
107 entries_tok = 'entries';
108 journal_tok = 'journal';
109 journals_tok = 'journals';
110 transaction_tok = 'transaction';
111 account_tok = 'account';
112 accounts_tok = 'accounts';
114 user_tok = 'user';
115 users_tok = 'users';
116 group_tok = 'group';
117 groups_tok = 'groups';
119 allowedactions_tok = 'allowedActions';
120 command_tok = 'command';
121 profiledetails_tok = 'profileDetails';
122 profiledetail_tok = 'profileDetail';
123 usersession_tok = 'userSession';
126 lparen = '<';
127 rparen = '>';
130 listdelimiter = ',';
131 exclamation = 33;
132 question = 63;
133 doubledash = dash dash;
136 lbracket = left_bracket;
137 rbracket = right_bracket;
138 //lsbracket = lsquare_bracket;
139 //rsbracket = rsquare_bracket;
141 equals = equals_helper;
142 fslash = forwardslash;
143 atsign = ats;
144 colon = colon_helper;
146 {bkeeping -> freetext, freetext -> bkeeping} quote = ( double_quote | single_quote );
147 {bkeeping -> freetext, freetext -> bkeeping} backquote = '`';
149 word = ( lowercase | uppercase | dash | underscore | digit | dot )+;
151 //xpath_chars = ( ats | forwardslash | colon_helper | left_bracket | right_bracket | lsquare_bracket | rsquare_bracket | equals_helper | double_quote | single_quote );
152 xpath_chars = ( colon_helper | left_bracket | right_bracket | lsquare_bracket | rsquare_bracket );
155 xmlns = 'xmlns';
156 decl_xml = 'xml';
157 decl_dtd = 'DOCTYPE';
158 eoll = (cr | lf | cr lf)?;
161 Ignored Tokens
163 whitespace,
164 comment_line,
165 comment_block;
168 Productions
171 expr = {cmd} command semicolon |
172 {thexpr} twohandexpr semicolon;
174 /***************************
175 * VARIABLES
177 * @memory
178 * @previous
181 twohandexpr = var word equals command; // assigning results to variables
182 varname = atsign word?; // put an '@' sign in front of variable name to reference it
185 /***************************
186 * COMMANDS
188 * add ((token.literal) token.literal, ...)
189 * update ((token.literal) token.literal, ...)
190 * remove ((token.literal) token.literal, ...)
192 * reverse ((token.literal) (token.literal) token.literal)
195 * find ((token.literal) token -opts)
196 * list ((token.literal) token -opts)
198 * create (token -opts)
200 * load (token -opts) <-- DB
201 * commit (token.literal) <-- DB
203 * print (token.literal)
205 * login (token -opts) <-- DB
206 * logout <-- DB
207 * exit
209 *command1 = {add} add [lbdepth1]:lbracket [lbdepth2]:lbracket command_input [rbdepth2]:rbracket ilist* [rbdepth1]:rbracket |
210 *{remove} remove [lbdepth1]:lbracket [lbdepth2]:lbracket command_input [rbdepth2]:rbracket ilist* [rbdepth1]:rbracket;
212 command = {c1} command1 |
213 {c5} command5 |
214 {c2} command2 |
215 {c3} command3 |
216 {c4} command4 |
217 {c6} command6 |
218 {c7} command7;
221 command1 = {add} add [lbdepth1]:lbracket [lbdepth2]:lbracket command_input [rbdepth2]:rbracket ilist* [rbdepth1]:rbracket |
222 {update} update [lbdepth1]:lbracket [lbdepth2]:lbracket [c1]:command_input [rbdepth2]:rbracket [c2]:command_input [rbdepth1]:rbracket |
223 {remove} remove [lbdepth1]:lbracket [lbdepth2]:lbracket command_input [rbdepth2]:rbracket ilist* [rbdepth1]:rbracket;
225 command5 = {reverse} reverse [lbdepth1]:lbracket [lbdepth2]:lbracket [ci1]:command_input [rbdepth2]:rbracket [lbdepth3]:lbracket [ci2]:command_input [rbdepth3]:rbracket [ci3]:command_input [rbdepth1]:rbracket;
227 //** input list & delimiter
228 ilist = command_input ilistpart*;
229 ilistpart = listdelimiter command_input;
232 command2 = {find} find [lbdepth1]:lbracket [lbdepth2]:lbracket [c1]:command_input [rbdepth2]:rbracket [c2]:command_input [rbdepth1]:rbracket|
233 {list} list [lbdepth1]:lbracket [lbdepth2]:lbracket [c1]:command_input [rbdepth2]:rbracket [c2]:command_input [rbdepth1]:rbracket;
235 command3 = {load} load lbracket command_input rbracket |
236 {create} create lbracket command_input rbracket |
237 {login} login lbracket command_input rbracket;
239 command4 = {logout} logout|
240 {exit} exit;
242 command6 = {print} print lbracket command_input rbracket;
244 command7 = {commit} commit [lbdepth1]:lbracket [lbdepth2]:lbracket [input1]:command_input [rbdepth2]:rbracket [input2]:command_input [rbdepth1]:rbracket;
248 /**************************
249 * COMMAND INPUT
251 command_input = {var} varname |
252 {xml} xmlblock |
253 {opts} input_option |
254 {cmd} command |
255 {xpath} xpath;
258 // token -opts
259 input_option = commandtoken commandoption* ;
262 xpath = [left]:backquote xpath_part* [right]:backquote;
263 xpath_part = {wd} wordetal |
264 {xpc} xpath_chars |
265 {fslash} fslash |
266 {quote} quote |
267 {ats} atsign |
268 {equals} equals;
272 /***************************
273 * COMMAND OPTIONS
275 commandoption = {entry} entry_opt |
276 {entryid} entryid_opt |
277 {account} account_opt |
278 {accountid} accountid_opt |
279 {journal} journal_opt |
280 {name} name_opt |
281 {type} type_opt |
282 {cweight} counterweight_opt |
283 {amount} amount_opt |
284 {id} id_opt |
285 {entrynum} entrynum_opt |
286 {date} date_opt |
287 {file} file_opt |
288 {group} group_opt |
289 {uname} uname_opt |
290 {passwd} passwd_opt |
291 {groupid} groupid_opt |
292 {userid} userid_opt |
293 {currency} currency_opt |
294 {return} returninput_opt;
298 /***************************
299 * XML BLOCKS
301 xmlblock = xml_decl? fulltag;
303 fulltag = {fulltag} opentag fulltag* wordetal* closetag |
304 {emptytag} emptytag |
305 {comment} xmlcomment;
307 opentag = lparen nsprefix? wordetal attribute* rparen;
308 emptytag = lparen nsprefix? wordetal attribute* fslash rparen;
309 closetag = lparen fslash nsprefix? wordetal rparen;
313 xml_decl = {xml_schem} xml_decl_schem |
314 {xml_dtd} xml_decl_dtd;
316 // <?xml version="1.0" encoding="iso8859-1" ?>
317 xml_decl_schem = lparen [left]:question wordetal attribute+ [right]:question rparen;
319 // <!DOCTYPE greeting SYSTEM "hello.dtd" >
320 xml_decl_dtd = lparen exclamation word_dtd+ rparen;
321 word_dtd = {attrhs} attributerhs |
322 {word} word;
325 attribute = nsprefix? attributelhs equals attributerhs;
326 attributelhs = wordetal;
327 attributerhs = [left]:quote zzz* [right]:quote;
329 nsprefix = wordetal colon;
331 xmlcomment = xml_opencomment wordetal* xml_closecomment;
333 xml_opencomment = lparen exclamation doubledash;
334 xml_closecomment = doubledash rparen;
337 zzz = {one} wordetal |
338 {two} fslash;
340 wordetal = {word} word |
341 {ats} atsign |
342 {ctoken} commandtoken;
346 /***************************
347 * COMMAND TOKENS
349 commandtoken = {system} system_tok |
350 {debit} debit_tok |
351 {credit} credit_tok |
352 {entry} entry_tok |
353 {entries} entries_tok |
354 {journal} journal_tok |
355 {journals} journals_tok |
356 {transaction} transaction_tok |
357 {accounts} accounts_tok |
358 {account} account_tok |
359 {user} user_tok |
360 {users} users_tok |
361 {group} group_tok |
362 {groups} groups_tok |
363 {allowedactions} allowedactions_tok |
364 {command} command_tok |
365 {profiledetails} profiledetails_tok |
366 {profiledetail} profiledetail_tok |
367 {usersession} usersession_tok;
371 // >>>>>>>>>> TODO
373 // 7. include CDATA blocks
374 // <a> <![CDATA[ do something ]]> </a>
378 /**
380 * TEST XMLs
382 // <xml>
383 // <xml/>
384 // <xml> ccc </xml>
385 // <xml> lorem ipsum some text </xml>
386 // <xml attr1="" attr2="wert" />
387 // <xml attr1="" attr2="wert" > </xml>
389 // <xml:xml />
390 // <xml:xml></xml:xml>
392 // <xml:xml attr1="" attr2="wert" />
393 // <xml:xml attr1="" attr2="wert" ></xml:xml>
395 // <xml:xml attr1="" attr2="wert" > <a> <b/> </a> lorem ipsum some text </xml:xml>
396 // <xml:xml attr1="" attr2="wert" > <a> <!-- this is comments --> <b/> </a> lorem ipsum some text </xml:xml>
397 // <xml:xml pre:attr1="" pref:attr2="wert" > <a> <!-- this is comments --> <b/> </a> lorem ipsum some text </xml:xml>
399 // <?xml version="1.0" encoding="iso8859-1" ?> <xml:xml attr1="" attr2="wert" > <a> <!-- this is comments --> <b/> </a> lorem ipsum some text </xml:xml>
400 // <!DOCTYPE greeting SYSTEM "hello.dtd" > <xml:xml attr1="" attr2="wert" > <a> <!-- this is comments --> <b/> </a> lorem ipsum some text </xml:xml>
402 // <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' entryid='e1' accountid='2' />
403 // <?xml version="1.0" encoding="iso8859-1" ?><credit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' entryid='e1' accountid='2' />
405 // <account xmlns='com/interrupt/bookkeeping/account' id='1' name='office equipment' type='asset' counterWeight='debit' ><debit xmlns='com/interrupt/bookkeeping/account' id='' amount='10.00' entryid='' accountid='1' /></account>
408 /**
410 * SCRATCH XML
412 // <lebit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' entryid='e1' accountid='2' />
413 // <lebit xmlns='comaccount' id='def' amount='1.50' entryid='e1' accountid='2' />
414 // <debit xmlns='comaccount' id='def' amount='1.50' entryid='e1' accountid='2' />
415 // <xml:xml attr1="com/interrupt/bookkeeping/account" attr2="wert" > <a> <b/> </a> lorem ipsum some text </xml:xml>
416 // <xml attr1="com/interrupt/bookkeeping/account" attr2="wert" > <a> <b/> </a> lorem ipsum some text </xml>
417 // <xml attr1="com/interrupt/bookkeeping/account" attr2="wert" > <a> <b/> </a> </xml>
419 // <xml attr1="comaccount" attr2="wert" > <a> <b/> </a> </xml>
420 // <xml attr1="comaccount" attr2="wert" > <a> <b/> </a> lorem ipsum </xml>
421 // <xml attr1="com/interrupt/bookkeeping/account" attr2="wert" > <a> <b/> </a> lorem ipsum </xml>
423 // <debit attr1="com/interrupt/bookkeeping/account" attr2="wert" > <a> <b/> </a> </debit>
424 // <debit attr1="com/interrupt/bookkeeping/account" attr2="wert" > </debit>
428 /**
430 * TEST OPTIONS
432 // -entry journal
433 // -type type -name some
434 // -type type -name some -id qerfb1435c -date 06/24/2003
436 //[X] -account "account name"
437 //[X] -journal journal name -entry journal
439 // -counterWeight debit
440 // -amount 123.33
441 // -id qerfb1435c
442 // -entrynum 765
443 // -date 06/24/2003
444 // -F filename
447 // login ( user -username root -password password );
448 // load ( users -id aauth.users );
451 //** create ( debit -id erfg -amount 123.33 );
452 // create ( <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' /> );
455 // load ( users -id aauth.users );
456 // load ( debit -amount 10.00 );
457 // load ( debit -id abc -amount 10.00 );
458 // load ( <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' /> );
461 //** add ((create ( entry -id ez ) ) create ( debit -id dbzz -amount 10.00 ) );
462 // add ((create ( entry -id ez ) ) load ( debit -id abc -amount 10.00 ) );
464 // add ((create ( entry -id ez -currency CDN ) ) create ( <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' currency='CDN' /> ) );
467 // remove ( (load ( entry -id e1 )) );
468 // remove ( (load ( entry -id e1 )) load ( debit -id abc -amount 10.00 ) );
471 /* reverse ( (
472 <entries xmlns='com/interrupt/bookkeeping/journal' id='' >
473 <entry xmlns='com/interrupt/bookkeeping/journal' id='e1' entrynum='' state='closed' journalid='' date='' >
474 <debit xmlns='com/interrupt/bookkeeping/account' id='abc' amount='10.00' entryid='e1' accountid='1' />
475 <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' entryid='e1' accountid='2' />
476 <credit xmlns='com/interrupt/bookkeeping/account' id='ghi' amount='11.50' entryid='e1' accountid='3' />
477 </entry>
478 </entries>
481 <entry xmlns='com/interrupt/bookkeeping/journal' id='e1' entrynum='' state='closed' journalid='' date='' >
482 <debit xmlns='com/interrupt/bookkeeping/account' id='abc' amount='10.00' entryid='e1' accountid='1' />
483 <debit xmlns='com/interrupt/bookkeeping/account' id='def' amount='1.50' entryid='e1' accountid='2' />
484 <credit xmlns='com/interrupt/bookkeeping/account' id='ghi' amount='11.50' entryid='e1' accountid='3' />
485 </entry>
487 <entry xmlns='com/interrupt/bookkeeping/journal' id='ereverse' entrynum='' state='closed' journalid='' date='' >
488 <debit xmlns='com/interrupt/bookkeeping/account' id='reverseabc' amount='11.50' entryid='ereverse' accountid='1' />
489 <credit xmlns='com/interrupt/bookkeeping/account' id='reverseghi' amount='11.50' entryid='ereverse' accountid='3' />
490 </entry>
493 // reverse ( (entries -id es1) (entry -id e1) <entry xmlns='com/interrupt/bookkeeping/journal' id='newid' state='closed' > </entry> );
496 // find ( (load ( account -id 2 )) load ( debit -amount 1.50 ) );
499 // list ( (load ( entry -id e1 )) load ( debit -entryid e1) );
500 //** list ( (load ( entry -id e1 )) <debit xmlns='com/interrupt/bookkeeping/account' / > );
501 // list ( (load ( entry -id e1 )) <debit xmlns='com/interrupt/bookkeeping/account' entryid='e1' / > );
505 //** VARIABLES
506 // var timmy = list ( (load ( entry -id e1 )) <debit xmlns='com/interrupt/bookkeeping/account' / > );
507 // find ( (load ( entry -id e1 )) @timmy );
509 // print ( @timmy );
512 //** COMMITING
514 add ( (load ( entries -id es1 ))
515 add (
516 (create ( entry -id e2 ))
517 create (debit -id nsfada -entryid e2 -amount 52.30 -accountid 1 ),
518 create (credit -id efiafd -entryid e2 -amount 52.30 -accountid 3 )
523 // add ( ( create (entries) ) create ( entry ) );
524 // add ( ( create (entries) ) create ( entry ), create ( entry ) );
528 var tim = add (
529 (create ( entry -id e2 ))
530 create (debit -id nsfada -entryid e2 -amount 52.30 -accountid 1 ),
531 create (credit -id efiafd -entryid e2 -amount 52.30 -accountid 3 )
534 // var result = add ( (load ( entries -id es1 )) @tim );
535 // commit ( @result );
540 // >>>>>>>>>> DONE
541 // * Tokens cannot use other tokens
543 // [OK] multiple attributes
544 // [OK] include 2 tokens in a production rule
546 // [OK] include xml comments
547 // <!-- -->
549 // [OK] include namespace declarations; namespace usage in tags and attributes
550 // xmlns='' xmlns:ans='' <ans:tagname att='' />
552 // [OK] text in open/close tags
553 // <a att='' >
554 // <b/>
555 // some text
556 // </a>
559 // [OK] include document declaration ( DTD & schema )
560 // <?xml version="1.0" encoding="iso8859-1" **allow any and all characters between** ?>
561 // <!DOCTYPE greeting SYSTEM "hello.dtd" **allow any and all characters between** >
563 // [OK] implement token & options (this will also be the short form of inputs )
565 // [OK] comments