Xtext vs ANTLR vs Parser Combinators
So you have decided that you need a parser, a real one. Now you need to decide what to use to implement that parser. There are several choices:
- Create your own parser manually
- Use a parser combinator library like fastparse or parboiled2
- Use a parser generator, like Antlr
- Use a language workbench, like Xtext or Langium
Each choice has advantages and disadvantages that I will discuss in this post.
Create your own parser manually
It your main interest is to have an extremely fast and flexible parser, this is the way to go. Manual parser are mostly used for programming languages or in places where every bit of performance is needed. However, creating your own parser is a tedious, slow and repetitive process.
Use a parser combinator library
Functional languagues, like Scala, allow the creation of parser combinators. Parser combinators offer a benefit from the usability point of view. You can define grammar in a straightforward and compact way. There are libraries, such as fastparse, that make an effort to support nice error messages and fast parsing speed.
Parser combinators are very good if you need to write a parser without too much hassle. However, they are not as flexible as manual parsers and might be slower.
Use a parser generator
Parser generators sacrifice usability but give you flexibility and speed. The problem is that parser generators require code generation, so they will complicate your development process. However, the generated code is highly optimized, and it can be heavily customized.
Use a language workbench
Language workbenches introduce the most complexity, but in turn it goes beyond the parser. The language workbench enables the creation of tooling. For example, Xtext enables the creation of a language server, an Eclipse plugin, helps to connect with code generators, etc.
However, the disadvantages are both tooling and mental overhead. Even if Xtext is easy to start with, for complex and bigger projects, it is required to thoroughly understand it.
Choosing the right tool for the job depends on your needs. To create a full-fledged DSL (with tooling), the best way is clearly a language workbench. However, there are lots of use cases that do not require the complexity of a language workbench that are better served with the other alternatives.