Switch branches/tags
GROOVY_3_0_0_ALPHA_3 GROOVY_3_0_0_ALPHA_2 GROOVY_3_0_0_ALPHA_1 GROOVY_2_6_0_ALPHA_4 GROOVY_2_6_0_ALPHA_3 GROOVY_2_6_0_ALPHA_2 GROOVY_2_6_0_ALPHA_1 GROOVY_2_5_2 GROOVY_2_5_1 GROOVY_2_5_0 GROOVY_2_5_0_RC_3 GROOVY_2_5_0_RC_2 GROOVY_2_5_0_RC_1 GROOVY_2_5_0_BETA_3 GROOVY_2_5_0_BETA_2 GROOVY_2_5_0_BETA_1 GROOVY_2_5_0_ALPHA_1 GROOVY_2_4_15 GROOVY_2_4_14 GROOVY_2_4_13 GROOVY_2_4_12 GROOVY_2_4_11 GROOVY_2_4_10 GROOVY_2_4_9 GROOVY_2_4_8 GROOVY_2_4_7 GROOVY_2_4_6 GROOVY_2_4_5 GROOVY_2_4_4 GROOVY_2_4_3 GROOVY_2_4_2 GROOVY_2_4_1 GROOVY_2_4_0 GROOVY_2_4_0_RC_2 GROOVY_2_4_0_RC_1 GROOVY_2_4_0_BETA_4 GROOVY_2_4_0_BETA_3 GROOVY_2_4_0_BETA_2 GROOVY_2_4_0_BETA_1 GROOVY_2_3_11 GROOVY_2_3_10 GROOVY_2_3_9 GROOVY_2_3_8 GROOVY_2_3_7 GROOVY_2_3_6 GROOVY_2_3_5 GROOVY_2_3_4 GROOVY_2_3_3 GROOVY_2_3_2 GROOVY_2_3_1 GROOVY_2_3_0 GROOVY_2_3_0_RC_4 GROOVY_2_3_0_RC_3 GROOVY_2_3_0_RC_2 GROOVY_2_3_0_RC_1 GROOVY_2_3_0_BETA_2 GROOVY_2_3_0_BETA_1 GROOVY_2_2_2 GROOVY_2_2_1 GROOVY_2_2_0 GROOVY_2_2_0_RC_3 GROOVY_2_2_0_RC_2 GROOVY_2_2_0_RC_1 GROOVY_2_2_0_BETA_1 GROOVY_2_1_9 GROOVY_2_1_8 GROOVY_2_1_7 GROOVY_2_1_6 GROOVY_2_1_5 GROOVY_2_1_4 GROOVY_2_1_3 GROOVY_2_1_2 GROOVY_2_1_1 GROOVY_2_1_0 GROOVY_2_1_0_RC_3 GROOVY_2_1_0_RC_2 GROOVY_2_1_0_RC_1 GROOVY_2_1_0_BETA_1 GROOVY_2_0_8 GROOVY_2_0_7 GROOVY_2_0_6 GROOVY_2_0_5 GROOVY_2_0_4 GROOVY_2_0_2 GROOVY_2_0_1 GROOVY_2_0_0 GROOVY_2_0_0_RC_4 GROOVY_2_0_0_RC_3 GROOVY_2_0_0_RC_2 GROOVY_2_0_0_RC_1 GROOVY_2_0_0_BETA_3 GROOVY_2_0_0_BETA_2 GROOVY_2_0_0_BETA_1 GROOVY_2_0_BETA_2 GROOVY_1_9_BETA_4 GROOVY_1_9_BETA_3 GROOVY_1_9_BETA_1 GROOVY_1_8_9 GROOVY_1_8_8 GROOVY_1_8_7
Nothing to show
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


This is the home of the new parser Parrot, which is based on Antlr4.

The new parser(Parrot) can parse Groovy source code and construct the related AST, which is almost identical to the one generated by the old parser(except the corrected node position, e.g. line, column of node). Currently all features of Groovy are available. In addition, the following new features have been added:

  • do-while loops; enhanced (now supporting commas) classic for loops, e.g. for(int i = 0, j = 10; i < j; i++, j--) {..})

  • lambda expressions, e.g. stream.map(e → e + 1)

  • method references and constructor references

  • try-with-resources, AKA ARM

  • code blocks, i.e. {..}

  • Java style array initializers, e.g. new int[] {1, 2, 3}

  • default methods within interfaces

  • additional places for type annotations

  • new operators: identity operators(===, !==), elvis assignment(?=), !in, !instanceof

  • safe index, e.g. nullableVar?[1, 2]

  • non-static inner class instantiation, e.g. outer.new Inner()

  • runtime groovydoc, i.e. groovydoc with @Groovydoc; groovydoc attached to AST node as metadata

How to enable the new parser

The new parser is enabled by default since Groovy 3.0.0

  • In the gradle build the property useAntlr4 has to be set to enable the build of the parser and the execution of all tests with it. Command line example:

./gradlew -PuseAntlr4=true bootstrapJar
  • To enable the new parser automatically at runtime the system property groovy.antlr4 has to be set. Command line example:

export JAVA_OPTS="-Dgroovy.antlr4=true"
groovy foo.groovy
  • This system property also controls groovyc and has to be used in case it is used outside of this build, for example with:

groovyOptions.forkOptions.jvmArgs += ["-Dgroovy.antlr4=true"]

JVM system properties to control parsing

  • groovy.antlr4.cache.threshold: how frequently to clear DFA cache(default: 64). Notice: The more frequently the DFA cache is cleared, the poorer parsing performance will be(you can not set the value that is less than the default value). But the DFA cache has to be cleared to avoid OutOfMemoryError’s occurring.

  • groovy.attach.groovydoc: whether to attach groovydoc to node as metadata while parsing groovy source code(default: false)

  • groovy.attach.runtime.groovydoc: whether to attach @Groovydoc annotation to all members which have groovydoc(i.e. /** …​ */)

  • groovy.extract.doc.comment: whether to collect groovydoc while parsing groovy source code(default: false). DEPRECATED, USE groovy.attach.groovydoc INSTEAD

P.S. Parrot is based on the highly optimized version of antlr4(com.tunnelvisionlabs:antlr4), which is licensed under BSD.


Question(from Slack):
Can someone explain to me the importance of the Parrot compiler? Basically explain like I am 5?
Answer(by Guillaume Laforge, Project Lead of Apache Groovy):
the syntax of Groovy hasn’t evolved in a long time
the current / old parser is a bit complicated to evolve
and is using a very old version of the parsing library
so any change we’d want to make to the language (a new operator, for example) becomes very complicated
So we’ve been wanting to upgrade the underlying parser library for a while, but since the library evolved a lot, that also required a rewrite of the grammar of the language
But there’s another thing to consider
Groovy’s always been adopted by Java developers easily because of how close to the Java syntax it’s always been
so most Java programs are also valid Groovy programs
it’s been important to Groovy’s success to have this source compatibility
Java 8's been out for a while already
and we’ve been asked countless times if we’d support this or that particular syntax enhancement from Java 8
for “copy’n paste compatibility”, if you will
We decided to upgrade to a newer version of our parsing library (from v2 to v4 of Antlr)
to allow Groovy’s syntax to continue to evolve
to also support new operators and things like that
but to also support Java 8 constructs, for continued compatibility
And that’s about it