-
Notifications
You must be signed in to change notification settings - Fork 12
Overview: grappa 1.0.x vs parboiled java
This page is an (hopefully not biased!) overview of the differences (and compatibilities) between parboiled-java and grappa 1.0.x. It is a high-level view of the (very technical and sometimes arid) release notes.
Grappa uses gradle as a build system, where parboiled uses SBT.
Grappa also makes use of the gradle wrapper; this means that you don't need anything other than a working Internet connection, git and a JDK (6 or more) to get started.
Grappa is meant to be Java and only Java; as such, Scala support has been removed entirely.
Partial in the sense that Grappa will run on a 1.8 JRE, unlike parboiled; however, parsers are still generated using 1.6 bytecode, so you cannot (yet) write grammars making use of new features available in Java 7 (try-with-resources for instance) or Java 8 (lambdas, etc).
Grappa depends on Guava (version 17.0); this allows to make full use of this library's very powerful features.
The ASM dependency has been updated from 4.x to 5.x; what is more, the dependency is on asm-debug-all
instead of "non debug" versions of ASM: this allows for much easier debugging.
This means you can use Grappa to parse CharBuffer
s, but also very large text files using largetext.
Grappa provides another mechanism for managing parser rule outputs in addition to the value stack, actions and Var
s: you can now trigger events on the inputs you choose.
All this requires is that you write an event class and listener class; see here for more details.
Grappa 1.0.x is fully backwards-compatible with parboiled. All your grammars written for parboiled should work out of the box with Grappa, with no modifications. Any custom actions you may have written etc should also work.
If this isn't the case, this is a bug, and yours truly asks that you open an issue.
Note however that all basic rules which were defined in parboiled are deprecated in order to be compliant with Java naming conventions; that is, FirstOf
is now firstOf
etc. Other than that, the new rules work exactly the same.
Again, if this isn't the case, this is a bug, and yours truly asks that you open an issue.
Grappa has new rules not present in parboiled:
- Unicode matchers: you can match a single code point (
unicodeChar()
) or a range of code points (unicodeRange()
); - all rules (lowercased) defined by RFC 5234, Appendix B, section 1 are present, except for
LWSP
. This means you havedigit()
,alpha()
, etc; -
trie()
: this new rule uses a trie to match one string among many; for instancetrie("Alice", "Bob", "Fred")
; note that it will always find the longest match:trie("do", "double")
will finddouble
indoubles
, notdo
; -
join()
: this is a general joining rule allowing all combinations of repetitions; note that the joining rule should not match an empty string: if it does, you will get an exception at runtime.
Example usage of join()
: let us say you parse a JSON Array; you have a clear separator which is the comma (,
), with JSON values inbetween. Provided you have the appropriate rules, here is how you would match a JSON array:
Rule jsonArray()
{
return sequence('[', join(jsonValue()).using(',').min(0), ']');
}
This will even match empty arrays. Whitespaces etc not accounted for but they can be inserted with little effort.
Parboiled was written with Java 5 in mind; grappa is (for version 1.0.x! 2.0.x will go Java 7) written with Java 6 in mind. As such, a lot of code has been modified to account for Java 6 features (for instance, the appearance of Deque
, String
's .isEmpty()
, others).
The code is nearly fully annotated with JSR 305 annotations; this allows IDEs or tools supporting them (IDEA, FindBugs, others) to report problems related to these annotations.
Note that unfortunately, the annotation which is by far the most prominent in the current code is @Nullable
. If you use an IDE which warns on nullable value problems, you will probably get a lot of those if your existing grammars use the stack or Var
s a lot, since all of these accept or can produce null
s. This will not change for version 1.0 but it will change for version 1.1.
A lot of tests (not all of them yet) have been converted from using String-based comparisons (!!!) to using assertions (using AssertJ). Another added dependency is Mockito.
Grappa also has the ability to run mutation testing using pitest via the existing gradle plugin.