The main problem is that you want newlines to matter, but your lexer treats them as whitespace. This means that all newlines get silently consumed after each token. Unfortunately, there is no easy way around this: In Parsec, is there a way to prevent lexeme from consuming newlines?.
This is certainly poor design on the part of the library. Which is a little odd because, in general, Parsec is one of the best-designed libraries I've ever used.
Another little problem is that your separator (oneOf ";\n"
) does not allow any spaces following it. If you change it to oneOf ";\n" >> skipMany (oneOf " \t"))
, you will be able to parse something like "{ a(); b(); c(); }` correctly. Unfortunately, this does not help with the earlier problem of significant newlines.
Ultimately, it might just be your best bet to write your own lexing routines for striping tailing whitespace. This will also be a good exercise in learning more about Parsec :).