rewrote 'Invertible syntax descriptions' from Haskell, a lot of refinement is needed