Skip to content

Instantly share code, notes, and snippets.

@ast
Last active February 3, 2020 03:25
Show Gist options
  • Save ast/004f65fb2f5999e6cf27f8e84e3a9655 to your computer and use it in GitHub Desktop.
Save ast/004f65fb2f5999e6cf27f8e84e3a9655 to your computer and use it in GitHub Desktop.
Double entry bookkeeping in pegjs
/*
Use pegjs online evaluator to try
https://pegjs.org/online
Input sample:
albin food 100.00
juliana food 100
Output:
{
"albin": -100,
"food": 200,
"juiana": -100
}
*/
{
var accounts = {};
function addTransaction(cr, dr, am) {
if (!(cr in accounts)) accounts[cr] = 0;
if (!(dr in accounts)) accounts[dr] = 0;
accounts[cr] -= am;
accounts[dr] += am;
}
}
start = transaction*
{
for(var account in accounts) accounts[account] /= 100;
return accounts
}
transaction = cr:account _ dr:account _ am:amount _
{
if (cr === dr) expected("different accounts");
addTransaction(cr, dr, am);
}
amount =
decimal / integer
digit =
[0-9]
integer =
int:digit+
{ return parseInt(int.join("")) * 100}
decimal =
int:digit+ '.' fra:(digit digit)
{ return parseInt(int.join("")) * 100 + parseInt(fra.join(""))}
account =
acc:[a-zA-Z]+
{ return acc.join(""); }
_ =
!.
/ [ \t\n]+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment