Allen pointed me to this: http://www.oilshell.org/blog/2017/02/11.html, From AST to Lossless Syntax Tree.
I thought I’d reply on the list.
The standard way to look at this is that you have a parser and generator function:
p : string -> ast
g : ast -> string
I don’t think requiring the AST to be lossless in the sense that g is an inverse of p is a useful property. Instead, p is many to one and the AST is a kind of canonical form.
We do want the composition
g.p = lambda x. g(p(x)))
to be idemopotent, which we get if the AST really is
p(s) = p(g(p(s))
Stan’s AST has enough info in it that you could use it to write a generator for a Stan program. Say, something like a pretty printer.