Write parsers for arbitrary text inputs, entirely in Java, with no preprocessing phase

Overview

Read me first

The license of this project is Apache 2.0.

Requires Java 7 or later.

The latest versions are:

  • development: 2.1.0-beta.3; requires Java 8 (this is 2016, after all);
  • stable: 2.0.4. requires Java 7.

What this is

This package allows you to write grammars entirely in Java. Unlike, for instance, ANTLR and JavaCC, parsers written with this package do not require a pre-processing phase. Yes, this means you generate your parsers at runtime. And there is no DSL. Pure Java!

See also the debugger package.

And, uh, the name?

Well, you write grammars and can then generate parsers for them. (I also happen to like the drink of the same name)

Versions

There are three major versions.

2.1.x

This version is currently in development. See here for a list of changes from 2.0.x.

2.0.x

The latest 2.0.x version is 2.0.4. Using gradle:

dependencies {
    compile(group: "com.github.fge", name: "grappa", version: "2.0.4");
}

Projects using grappa

Parse tree generator

Grappa in itself does not generate a parse tree. While you can do it yourself, a module exists which allows you to do exactly that with little effort:

https://github.com/ChrisBrenton/grappa-parsetree

A visualizer (using Graphviz) also exists for such parse trees: https://github.com/fge/grappa-parsetree-visual

More advanced usage...

A project, currently in development, will allow you to generate a grappa parser from a formal grammar (BNF, EBNF, WSN, others) at runtime. See here:

https://github.com/ChrisBrenton/grappa-formal

Other usages

The following projects, all on GitHub, use grappa:

Examples

Unfortunately, I still haven't documented the project properly.

Here is a link to a tutorial by Joseph Ottinger explaining a possible use of grappa:

http://enigmastation.com/2016/03/07/simple-grappa-tutorial/

The code for this tutorial is available on GitHub.

I have also put up a project with some sample grammars; in particular, a grammar which is able to fully parse any JSON:

https://github.com/fge/grappa-examples

Getting help

This project has an IRC channel (#grappa on Freenode; server: irc.freenode.net) and two dedicated Google groups: grappa-users and grappa-devel. They are also available to post by email.

Comments
  • CharSink closes its Writer after every .write() [was: provide alternative for deprecated TracingParseRunner.getLogs()]

    CharSink closes its Writer after every .write() [was: provide alternative for deprecated TracingParseRunner.getLogs()]

    TracingParseRunner.getLogs() was deprecated, however, the functionality is essential for debugging (as outlined here: https://github.com/sirthias/parboiled/wiki/Grammar-and-Parser-Debugging).

    This is to suggest that an alternative for getLogs() or a refactoring of getLogs() is provided in order to make the functionality available in non-deprecated form again.

    (Version grappa 1.0.0-beta.6)

    Thanks!

    bug 
    opened by chbussler 16
  • Using a boolean action variable for guarding rules fails with a NPE

    Using a boolean action variable for guarding rules fails with a NPE

    A NPE is thrown if the value of a boolean action variable is directly used to guard a set of rules like in the following example:

    public Rule someRule() {
        Var<Boolean> guard = new Var<>(false);
        return sequence(
                optional('@', guard.set(true)),
                "some text",
                optional(guard.get(), // fail if this does not start with @
                        "some other text");
    }
    

    The stack trace for the NPE:

    java.lang.NullPointerException
        at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:213)
        at com.google.common.collect.ImmutableCollection$ArrayBasedBuilder.add(ImmutableCollection.java:339)
        at com.google.common.collect.ImmutableList$Builder.add(ImmutableList.java:652)
    ...
    

    The problem can be avoided by using !!guard.get() or guard.get() ? true : false. I think that grappa does not correctly detect guard.get() as an action invocation.

    bug 
    opened by kenwenzel 10
  • Value stack is not cleared between ParseRunner.run() calls

    Value stack is not cleared between ParseRunner.run() calls

    I'm updating some code from 1.0.4 to 2.0.0-beta.1

    Everything works correctly, with the sole exception of the value stack retaining its contents from previous runs using the same ParseRunner instance.

    Is this an intended change, or a regression?

    bug 
    opened by hatstand0 8
  • Infinite recursion regression

    Infinite recursion regression

    The following rules do work fine with Grappa 1.0.4 but cause an infinite recursion with Grappa 2.0.0-beta.4.

        @Cached
        public Rule rule2(Var<Integer> count) {
            return firstOf(sequence("c", count.set(0)), sequence("b", rule2(count), count.set(count.getNonnull()+1), "b"));
        }
    
        @Cached
        public Rule rule3(Var<AtomicInteger> count) {
            return firstOf(sequence("c", set(count, 0)), sequence("b", rule3(count), set(count, count.getNonnull().get()+1), "b"));
        }
    
        public boolean set(Var<AtomicInteger> var, final int value) {
            var.getNonnull().set(value);
            return true;
        }
    

    In neither case an infinite recursion should occur because both methods are annotated with @Cached and because in each recursion the same Var instance is provided.

    The stack overflow exception is:

    Exception in thread "main" java.lang.StackOverflowError
        at java.util.Arrays.deepHashCode(Arrays.java:4199)
        at org.parboiled.transform.CacheArguments.hashCode(CacheArguments.java:43)
        at java.util.HashMap.hash(HashMap.java:338)
        at java.util.HashMap.get(HashMap.java:556)
        at grappa1.app.Parser$$parboiled.string(Unknown Source)
        at grappa1.app.Parser$$parboiled.fromCharArray(Unknown Source)
        at grappa1.app.Parser$$parboiled.fromStringLiteral(Unknown Source)
        at grappa1.app.Parser$$parboiled.toRule(Unknown Source)
        at org.parboiled.BaseParser.toRules(BaseParser.java:1845)
        at grappa1.app.Parser$$parboiled.sequence(Unknown Source)
        at grappa1.app.Parser$$parboiled.sequence(Unknown Source)
        at grappa1.app.Parser$$parboiled.rule2(Unknown Source)
        at grappa1.app.Parser$$parboiled.rule2(Unknown Source)
        at grappa1.app.Parser$$parboiled.rule2(Unknown Source)
        at grappa1.app.Parser$$parboiled.rule2(Unknown Source)
    [...over and over again...]
    
    opened by akirschbaum 7
  • Possibly contradicting parse error indicators

    Possibly contradicting parse error indicators

    In ParsingResult there are two different indicators whether a parsing error has occurred: matched and parseErrors. Is it possible that !matched but parseErrors.isEmpty()? If so: which error message should the application using the parser print? If not: why do both indicators exist at all?

    I'd suggest that matched is removed. A parse should be successful if and only if no parse errors did occur.

    bug 
    opened by akirschbaum 5
  • Parser generation crashes with BufferOverflowException

    Parser generation crashes with BufferOverflowException

    Creating a new parser crashes 1.0.0-beta.4. The same code did work with Parboiled 1.1.6.

    Exception in thread "main" java.lang.RuntimeException: Error creating extended parser class: null
           at org.parboiled.Parboiled.createParser(Parboiled.java:60)
           at bugfinder.app.CParser.<init>(CParser.java:63)
           at bugfinder.app.Main.main(Main.java:70)
    Caused by: java.nio.BufferOverflowException
           at java.nio.Buffer.nextPutIndex(Buffer.java:519)
           at java.nio.HeapByteBuffer.putChar(HeapByteBuffer.java:264)
           at org.parboiled.transform.process.InstructionGroupPreparer$MD5Digester.update(InstructionGroupPreparer.java:369)
           at org.parboiled.transform.process.InstructionGroupPreparer$MD5Digester.visitTypeInsn(InstructionGroupPreparer.java:241)
           at org.objectweb.asm.tree.TypeInsnNode.accept(TypeInsnNode.java:83)
           at org.objectweb.asm.tree.InsnList.accept(InsnList.java:162)
           at org.parboiled.transform.process.InstructionGroupPreparer.name(InstructionGroupPreparer.java:176)
           at org.parboiled.transform.process.InstructionGroupPreparer.process(InstructionGroupPreparer.java:116)
           at org.parboiled.transform.ParserTransformer.runMethodTransformers(ParserTransformer.java:98)
           at org.parboiled.transform.ParserTransformer.extendParserClass(ParserTransformer.java:81)
           at org.parboiled.transform.ParserTransformer.transformParser(ParserTransformer.java:55)
           at org.parboiled.Parboiled.createParser(Parboiled.java:55)
           ... 2 more
    
    opened by akirschbaum 5
  • Typo in error message

    Typo in error message

    If a private rule is called during parser generation, the following exception is thrown:

    Exception in thread "main" java.lang.RuntimeException: Error creating extended parser class: Rule method 'rule1'must not be private.
    [...]
    Caused by: org.parboiled.errors.GrammarException: Rule method 'rule1'must not be private.
    Mark the method protected or package-private if you want to prevent public access!
        at org.parboiled.support.Checks.ensure(Checks.java:41)
        at org.parboiled.transform.ClassNodeInitializer.visitMethod(ClassNodeInitializer.java:187)
        at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:911)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:693)
        at org.objectweb.asm.ClassReader.accept(ClassReader.java:506)
        at org.parboiled.transform.ClassNodeInitializer.process(ClassNodeInitializer.java:97)
        at org.parboiled.transform.ParserTransformer.extendParserClass(ParserTransformer.java:97)
        at org.parboiled.transform.ParserTransformer.transformParser(ParserTransformer.java:66)
        at org.parboiled.Parboiled.createParser(Parboiled.java:67)
    

    There should be a space in "[...]'rule1'must[...]".

    opened by akirschbaum 3
  • enforceVersion for build is too strict

    enforceVersion for build is too strict

    enforceVersion mandates 1.7, exactly, even with source version set to 1.7; this means that compilation with gradle fails if the user has 1.8 installed. Should be more lenient IMO.

    opened by jottinger 2
  • CharSequenceInputBuffer should use daemon threads to issue its LineCounter instances

    CharSequenceInputBuffer should use daemon threads to issue its LineCounter instances

    From IRC:

    <Ragnor> Hmmm... That is not a good change -- now my test just hangs. No CPU usage: it just doesn't finish for some reason. <idletask> Can you obtain a stack trace? <idletask> Or maybe it will eventually finish with some StackOverflowError or something... <idletask> (I think I know where this can come from; but I'd need a stack trace) <idletask> Ragnor: that's important -- can I have the input text, please? <idletask> I'll see if I can reproduce the bug here <Ragnor> No stack trace. No nothing. Currently trying to find out the problem in a debugger -- so far no results. <Ragnor> When I halt the program, it doesn't show anything at all. At least nothing related to my program; only Threads within java.*. <idletask> If you can provide the input text of the hanging text I'll try here <Ragnor> Hah! Do you start some Threads maybe? <idletask> Hanging test, I mean <idletask> Yes <Ragnor> Seems my application is exiting from main() but does not terminate. Some non-deamon thread maybe? <idletask> No, not non-daemon <idletask> That's curious, none of my tests hang <idletask> Do you have veeery large inputs? <Ragnor> Not really. It's just a tiny input. Regression tests ;) <Ragnor> (Trying to get a stack dump to show...) <idletask> It's the LineCounter which is launched in an ExecutorService, I think <idletask> And this ExecutorService is a Executors.newCachedThreadPool(); I guess I have to change that <idletask> Oh wait <Ragnor> This is the output of CTRL-\ : http://pastebin.mozilla.org/8263309 <idletask> My threads are non-daemon <idletask> Meh <idletask> I misinterpreted your question <Ragnor> (Maybe I should just System.exit(0) at end of main(). I'd guess this should circumvent the problem for now...) <idletask> Or just use the DefaultInputBuffer... <idletask> Curious however that it hangs like that <Ragnor> idletask: From the stack dump I just pasted: ""pool-1-thread-1" prio=10 tid=0x00007ffcf03e3000 nid=0x1221 waiting on condition [0x00007ffcfcc53000]" -- this line is missing the "daemon" flag. Therefore this thread prevents the JVM from terminating. <idletask> Ragnor: yep, that's a bug in CharSequenceInputBuffer <idletask> Ragnor: I'll fix it for 1.0.1 but in the meantime you'll have to revert to DefaultInputBuffer

    bug 
    opened by fge 1
  • Incorrect function names in error messages

    Incorrect function names in error messages

    Some function names in BaseParser have been renamed and now start with a lower case character. Error messages still refer to the now deprecated function names: The inner rule of ZeroOrMore rule 'file/ZeroOrMore/FirstOf/Sequence/ZeroOrMore' must not allow empty matches This should be changed so that error messages use the exact same names as the (non-deprecated) function names.

    opened by akirschbaum 1
  • The relevance of `RecoveringParseRunner`?

    The relevance of `RecoveringParseRunner`?

    This piece of code is one of the more complex in the current code; understanding what it does is all the harder that the test code for this parser consists of... String test outputs.

    Which is not a good thing, of course. This means the mechanics are not tested, and they need to be.

    Also, a lot of code in matchers themselves, or dedicated visitors, or even input buffers (see MutableInputBuffer), exist solely for the purpose of this runner.

    The only benefit that I can see is that it allows to not stop at the first parsing error...

    Do you use it at all? If yes, how? Another problem I have is figuring out actual use cases for it!

    help wanted question 
    opened by fge 1
  • firstOf() ignores overridden fromStringLiteral(String)

    firstOf() ignores overridden fromStringLiteral(String)

    The following grammar contains three rules. Each of these rules should match inputs "a" or "b", optionally followed by spaces.

    rule1 explicitly matches the trailing whitespace with zeroOrMore(sp()). This rule matches the input "a".

    rule2 implicitly matches the trailing whitespace by overriding fromStringLiteral(String) and adding zeroOrMore(sp()). That is: "x" matches this string; "x " matches sequence("x", zeroOrMore(sp())). This rule does NOT match the input "a". This is incorrect.

    rule3 is the same as rule2 but also matches cr(). This slight change causes the rule to match the input "a".

    Note: it seems that the actual change in rule3 is not important: If at least one non-String argument is present, the rule does match the input "a".

    The issue seems to be that if all arguments of firstOf() are string literals, the overloaded fromStringLiteral(String) is ignored.

    $ gradle
    :compileJava
    :processResources UP-TO-DATE
    :classes
    :run
    rule1: true
    rule2: false
    rule3: true
    
    BUILD SUCCESSFUL
    
    Total time: 5.954 secs
    $ cat build.gradle
    defaultTasks 'run'
    
    apply plugin: 'application'
    apply plugin: 'java'
    
    sourceCompatibility = 1.8
    mainClassName = 'app.Main'
    
    dependencies {
        compile 'com.github.fge:grappa:2.0.0'
    }
    
    repositories {
        mavenCentral()
    }
    $ cat src/main/java/app/Main.java
    package app;
    
    import com.github.fge.grappa.Grappa;
    import com.github.fge.grappa.buffers.CharSequenceInputBuffer;
    import com.github.fge.grappa.parsers.BaseParser;
    import com.github.fge.grappa.rules.Rule;
    import com.github.fge.grappa.run.ListeningParseRunner;
    
    public class Main {
    
        public static void main(final String[] args) {
            final Parser1 parser = Grappa.createParser(Parser1.class);
            final CharSequenceInputBuffer buffer = new CharSequenceInputBuffer("a");
            System.out.println("rule1: "+new ListeningParseRunner<>(parser.rule1()).run(buffer).isSuccess());
            System.out.println("rule2: "+new ListeningParseRunner<>(parser.rule2()).run(buffer).isSuccess());
            System.out.println("rule3: "+new ListeningParseRunner<>(parser.rule3()).run(buffer).isSuccess());
        }
    
        public static class Parser1 extends BaseParser<Object> {
    
            public Rule rule1() {
                return firstOf(sequence(fromStringLiteral("a"), zeroOrMore(sp())), sequence(fromStringLiteral("b"), zeroOrMore(sp())));
            }
    
            public Rule rule2() {
                return firstOf("a ", "b ");
            }
    
            public Rule rule3() {
                return firstOf("a ", "b ", cr());
            }
    
            @Override
            protected Rule fromStringLiteral(final String string) {
                return string.endsWith(" ") ? sequence(super.fromStringLiteral(string.substring(0, string.length()-1)), zeroOrMore(sp())) : super.fromStringLiteral(string);
            }
    
        }
    
    }
    
    opened by akirschbaum 1
  • anyOf(Characters.ALL) matches at end of input

    anyOf(Characters.ALL) matches at end of input

    anyOf(Characters.ALL) does match even if no more input is available. It should not match because no input character is available and thus no input character could have been consumed.

    The behavior of ANY is correct: it does not match if no more input is available.

    $ gradle
    :compileJava
    :processResources UP-TO-DATE
    :classes
    :run
    Parser1: false
    Parser2: true
    
    BUILD SUCCESSFUL
    
    Total time: 6.269 secs
    $ cat build.gradle
    defaultTasks 'run'
    
    apply plugin: 'application'
    apply plugin: 'java'
    
    sourceCompatibility = 1.8
    mainClassName = 'app.Main'
    
    dependencies {
        compile 'com.github.fge:grappa:2.0.0'
    }
    
    repositories {
        mavenCentral()
    }
    $ cat src/main/java/app/Main.java
    package app;
    
    import com.github.fge.grappa.Grappa;
    import com.github.fge.grappa.buffers.CharSequenceInputBuffer;
    import com.github.fge.grappa.parsers.BaseParser;
    import com.github.fge.grappa.rules.Rule;
    import com.github.fge.grappa.run.ListeningParseRunner;
    import com.github.fge.grappa.support.Characters;
    
    public class Main {
    
        public static void main(final String[] args) {
            final Parser parser = Grappa.createParser(Parser.class);
            final CharSequenceInputBuffer buffer = new CharSequenceInputBuffer("");
            System.out.println("Parser1: "+new ListeningParseRunner<>(parser.rule1()).run(buffer).isSuccess());
            System.out.println("Parser2: "+new ListeningParseRunner<>(parser.rule2()).run(buffer).isSuccess());
        }
    
        public static class Parser extends BaseParser<Object> {
    
            public Rule rule1() {
                return ANY;
            }
    
            public Rule rule2() {
                return anyOf(Characters.ALL);
            }
    
        }
    
    }
    
    opened by akirschbaum 0
  • Static rule creates broken parser

    Static rule creates broken parser

    A rule that is declared "static" causes a "java.lang.VerifyError" during parser generation. Instead Grappa should either support this or else should generate a proper error message.

    $ gradle
    :compileJava
    Download http://repo1.maven.org/maven2/com/github/fge/grappa/2.0.0/grappa-2.0.0.jar
    :processResources UP-TO-DATE
    :classes
    :run
    Exception in thread "main" java.lang.VerifyError: Bad local variable type
    Exception Details:
      Location:
        app/Main$Parser$$grappa.rule()Lcom/github/fge/grappa/rules/Rule; @0: aload_0
      Reason:
        Type top (current frame, locals[0]) is not assignable to reference type
      Current Frame:
        bci: @0
        flags: { }
        locals: { }
        stack: { }
      Bytecode:
        0x0000000: 2ab4 01a1 59c6 0004 b057 bb00 3059 b700
        0x0000010: 3459 2a5f b501 a12a b701 a359 c600 0b13
        0x0000020: 01a4 b900 4702 005a c000 49b6 004d 592a
        0x0000030: 5fb5 01a1 b0
      Stackmap Table:
        same_locals_1_stack_item_frame(@9,Object[#67])
        full_frame(@39,{},{Object[#48],Object[#67]})
    
            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Class.java:2663)
            at java.lang.Class.getConstructors(Class.java:1643)
            at com.github.fge.grappa.Grappa.findConstructor(Grappa.java:111)
            at com.github.fge.grappa.Grappa.createParser(Grappa.java:67)
            at app.Main.main(Main.java:12)
    :run FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':run'.
    > Process 'command '/usr/local/java/64/jdk1.8.0_31/bin/java'' finished with non-zero exit value 1
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
    
    BUILD FAILED
    
    Total time: 7.967 secs
    $ cat build.gradle
    defaultTasks 'run'
    
    apply plugin: 'application'
    apply plugin: 'java'
    
    sourceCompatibility = 1.8
    mainClassName = 'app.Main'
    
    dependencies {
        compile 'com.github.fge:grappa:2.0.0'
    }
    
    repositories {
        mavenCentral()
    }
    $ cat src/main/java/app/Main.java
    package app;
    
    import com.github.fge.grappa.Grappa;
    import com.github.fge.grappa.buffers.CharSequenceInputBuffer;
    import com.github.fge.grappa.parsers.BaseParser;
    import com.github.fge.grappa.rules.Rule;
    import com.github.fge.grappa.run.ListeningParseRunner;
    
    public class Main {
    
        public static void main(final String[] args) {
            new ListeningParseRunner<>(Grappa.createParser(Parser.class).rule()).run(new CharSequenceInputBuffer("a"));
        }
    
        public static class Parser extends BaseParser<Object> {
    
            public static Rule rule() {
                return ANY;
            }
    
        }
    
    }
    
    bug 
    opened by akirschbaum 1
  • firstOf() fails for one-character String argument

    firstOf() fails for one-character String argument

    When using firstOf() with only String arguments and if one String has length 1, then parser generation fails with a reference to trie(). This is incorrect for two reasons:

    I didn't use trie() but firstOf(). The error message should use the function name that I actually did use, even if Grappa internally maps it.

    I cannot think of any reason why one-character strings should be forbidden. Therefore this restriction seems so arbitrary to me that consider it a bug.

    /tmp/bug-firstof$ cat build.gradle
    defaultTasks 'run'
    apply plugin: 'application'
    sourceCompatibility = 1.8
    mainClassName = 'app.Main'
    dependencies { compile 'com.github.fge:grappa:2.0.0-beta.4' }
    repositories { mavenCentral() }
    /tmp/bug-firstof$ cat src/main/java/app/Main.java
    package app;
    
    import com.github.fge.grappa.Grappa;
    import com.github.fge.grappa.parsers.BaseParser;
    import com.github.fge.grappa.rules.Rule;
    
    public class Main extends BaseParser<Object> {
    
        public static void main(final String[] args) {
            Grappa.createParser(Main.class).rule();
        }
    
        public Rule rule() {
            return firstOf("//", "#");
        }
    
    }
    /tmp/bug-firstof$ gradle
    :compileJava
    :processResources UP-TO-DATE
    :classes
    :run
    Exception in thread "main" java.lang.IllegalArgumentException: strings in a trie must be two characters long or greater
            at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
            at com.github.fge.grappa.matchers.trie.TrieBuilder.addWord(TrieBuilder.java:52)
            at app.Main$$grappa.trie(Unknown Source)
            at app.Main$$grappa.firstOf(Unknown Source)
            at app.Main$$grappa.firstOf(Unknown Source)
            at app.Main.rule(Main.java:14)
            at app.Main$$grappa.rule(Unknown Source)
            at app.Main.main(Main.java:10)
    :run FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':run'.
    > Process 'command '/usr/local/java/64/jdk1.8.0_31/bin/java'' finished with non-zero exit value 1
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
    
    BUILD FAILED
    
    Total time: 5.13 secs
    
    bug 
    opened by akirschbaum 1
Owner
Francis Galiegue
Francis Galiegue
Java 1-15 Parser and Abstract Syntax Tree for Java, including preview features to Java 13

JavaParser This project contains a set of libraries implementing a Java 1.0 - Java 14 Parser with advanced analysis functionalities. This includes pre

JavaParser 4.5k Jan 9, 2023
A Java API for generating .java source files.

JavaPoet JavaPoet is a Java API for generating .java source files. Source file generation can be useful when doing things such as annotation processin

Square 10k Jan 5, 2023
Numerical-methods-using-java - Source Code for 'Numerical Methods Using Java' by Haksun Li

Apress Source Code This repository accompanies Numerical Methods Using Java by Haksun Li (Apress, 2022). Download the files as a zip using the green b

Apress 5 Nov 20, 2022
A collection of source code generators for Java.

Auto A collection of source code generators for Java. Auto‽ Java is full of code that is mechanical, repetitive, typically untested and sometimes the

Google 10k Jan 9, 2023
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 543 Nov 23, 2022
Catch common Java mistakes as compile-time errors

Error Prone Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time. public class ShortSet { public

Google 6.3k Dec 31, 2022
Elegant parsing in Java and Scala - lightweight, easy-to-use, powerful.

Please see https://repo1.maven.org/maven2/org/parboiled/ for download access to the artifacts https://github.com/sirthias/parboiled/wiki for all docum

Mathias 1.2k Dec 21, 2022
Compiler of Java bytecode to JavaScript

TeaVM See documentation at the project web site. Useful links: Getting started Gallery Flavour source code repository Site source code repository Disc

Alexey Andreev 2.1k Jan 3, 2023
Kodlama.io'da verilen ödev gereği Engin Demiroğ'un düzenlediği C# ile birlikte gerçek hayatta interface ve abstract konulu yayının Java uyarlaması yapılmıştır.

GercekHayattaInterfaceVeAbstract Kodlama.io'da verilen ödev gereği Engin Demiroğ'un düzenlediği C# ile birlikte gerçek hayatta interface ve abstract k

Baran Emre Türkmen 7 May 11, 2021
Chamomile is a Java Virtual Machine class file assembler and disassembler.

Chamomile is a Java Virtual Machine class file assembler and disassembler. Installation Maven <repositories> <repository> <id>jitpack.io</

null 15 May 24, 2022
uniVocity-parsers is a suite of extremely fast and reliable parsers for Java. It provides a consistent interface for handling different file formats, and a solid framework for the development of new parsers.

Welcome to univocity-parsers univocity-parsers is a collection of extremely fast and reliable parsers for Java. It provides a consistent interface for

univocity 874 Dec 15, 2022
First client that i didin't paste entirely...

BASE(D)BAND External Command Based Utility Player Assistance Mod To open the external command input type "B?" into the ingame chat. Modules live in th

null 9 Sep 24, 2022
JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. Go check the README.md file to see how to use it.

JCLR JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. To start using it, go to the

Scythe 3 Aug 21, 2021
A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back

A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back, with a transparent support of any kind of self-references and with a full Java 9 compatibility.

Andrey Mogilev 9 Dec 30, 2021
JavaCC - a parser generator for building parsers from grammars. It can generate code in Java, C++ and C#.

JavaCC Java Compiler Compiler (JavaCC) is the most popular parser generator for use with Java applications. A parser generator is a tool that reads a

null 971 Dec 27, 2022
Build parsers in Java

jparsec Builds mini parsers in pure Java. Latest version: 3.0 (requires Java 8+) News 2016-12-05 Removed references to Codehaus in copyright and packa

null 324 Dec 31, 2022
Arbitrary test data generator for parameterized tests in Java inspired by AutoFixture.

AutoParams AutoParams is an arbitrary test data generator for parameterized tests in Java inspired by AutoFixture. Sometimes setting all the test data

null 260 Jan 2, 2023
A high-performance Java API wrapper for arblib, the fantastic and amazing arbitrary-precision ball arithmetic C library, implemented via SWIG

A high-performance Java API wrapper for arblib, the fantastic and amazing arbitrary-precision ball arithmetic C library, implemented via SWIG

null 3 Dec 19, 2022
Nokogiri (鋸) is a Rubygem providing HTML, XML, SAX, and Reader parsers with XPath and CSS selector support.

Nokogiri Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby. It provides a sensible, easy-to-understand API for reading, writ

Sparkle Motion 6k Jan 8, 2023
An evil RMI server that can launch an arbitrary command. May be useful for CVE-2021-44228

evil-rmi-server An evil RMI server that can launch an arbitrary command. May be useful for CVE-2021-44228 in a local privesc scenario Build ./gradlew

Adam Bertrand 12 Nov 9, 2022