question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is it somehow possible to use this javacc jar to parse a jjt and jj file

See original GitHub issue

I want to construct some tests depending on the tokens used in a specific rule of my grammar.

void myrule() : {} {
<K_MYKEYWORD1>
| <K_MYKEYWORD2>
}

So I have a jjt file and need to transform this in a jj file and then parse this and get the AST - node tree, to traverse it.

My first attempt was this:

var parser = new JJTreeParser(
                Files.newInputStream(Paths.get("src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt"))
) {
    public ASTGrammar getRoot() {
        return (ASTGrammar)jjtree.rootNode());
    }
};
parser.javacc_input();

new JavaCodeGenerator().visit(parser.getRoot(), io);

But I have to fight method and class visibility issues:

IO is only package private, ASTGrammer.generate is package private as well.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:14

github_iconTop GitHub Comments

1reaction
manticore-projectscommented, Apr 15, 2022

Or in other words: What would be the best (e.g. simplest and most robust) to extract the actual Tokens from a jj Grammar File, without running JTREE first and also considering Composite Tokens.

0reactions
manticore-projectscommented, May 14, 2022

For reference, below is the code which finally returns all Keywords from a Grammar:

    private static void addTokenImage(TreeSet<String> allKeywords, RStringLiteral literal) {
        if (CHARSET_ENCODER.canEncode(literal.image) && literal.image.matches("[A-Za-z]+")) {
            allKeywords.add(literal.image);
        }
    }

    @SuppressWarnings({"PMD.EmptyIfStmt", "PMD.CyclomaticComplexity"})
    private static void addTokenImage(TreeSet<String> allKeywords, Object o) throws Exception {
        if (o instanceof RStringLiteral) {
            RStringLiteral literal = (RStringLiteral) o;
            addTokenImage(allKeywords, literal);
        } else  if (o instanceof RChoice) {
            RChoice choice = (RChoice) o;
            addTokenImage(allKeywords, choice);
        } else if (o instanceof RSequence) {
            RSequence sequence1 = (RSequence) o;
            addTokenImage(allKeywords, sequence1);
        } else if (o  instanceof ROneOrMore) {
            ROneOrMore oneOrMore = (ROneOrMore) o ;
            addTokenImage(allKeywords, oneOrMore);
        } else if (o  instanceof RZeroOrMore) {
            RZeroOrMore zeroOrMore = (RZeroOrMore) o ;
            addTokenImage(allKeywords, zeroOrMore);
        } else if (o  instanceof RZeroOrOne) {
            RZeroOrOne zeroOrOne = (RZeroOrOne) o ;
            addTokenImage(allKeywords, zeroOrOne);
        }  else if (o  instanceof RJustName) {
            RJustName zeroOrOne = (RJustName) o ;
            addTokenImage(allKeywords, zeroOrOne);
        } else if (o  instanceof RCharacterList) {
           // do nothing, we are not interested in those
        } else {
            throw new InvalidClassException("Unknown Type: " + o.getClass().getName() + " " + o.toString());
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, RSequence sequence) throws Exception {
        for (Object o: sequence.units) {
            addTokenImage(allKeywords, o);
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, ROneOrMore oneOrMore) {
        for (Token token: oneOrMore.lhsTokens) {
            if (CHARSET_ENCODER.canEncode(token.image)) {
                allKeywords.add(token.image);
            }
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, RZeroOrMore oneOrMore) {
        for (Token token: oneOrMore.lhsTokens) {
            if (CHARSET_ENCODER.canEncode(token.image)) {
                allKeywords.add(token.image);
            }
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, RZeroOrOne oneOrMore) {
        for (Token token: oneOrMore.lhsTokens) {
            if (CHARSET_ENCODER.canEncode(token.image)) {
                allKeywords.add(token.image);
            }
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, RJustName oneOrMore) {
        for (Token token: oneOrMore.lhsTokens) {
            if (CHARSET_ENCODER.canEncode(token.image)) {
                allKeywords.add(token.image);
            }
        }
    }

    private static void addTokenImage(TreeSet<String> allKeywords, RChoice choice) throws  Exception {
        for (Object o: choice.getChoices()) {
            addTokenImage(allKeywords, o);
        }
    }

    public static TreeSet<String> getAllKeywordsUsingJavaCC(File file) throws Exception {
        TreeSet<String> allKeywords = new TreeSet<>();

        Path jjtGrammar = file.toPath();
        Path jjGrammarOutputDir = Files.createTempDirectory("jjgrammer");

        new JJTree().main(new String[]{
                "-JDK_VERSION=1.8",
                "-OUTPUT_DIRECTORY=" + jjGrammarOutputDir.toString(),
                jjtGrammar.toString()
        });
        Path jjGrammarFile = jjGrammarOutputDir.resolve("JSqlParserCC.jj");

        JavaCCParser parser = new JavaCCParser(new java.io.FileInputStream(jjGrammarFile.toFile()));
        parser.javacc_input();

        // needed for filling JavaCCGlobals
        Semanticize.start();

        // read all the Token and get the String image
        for (Map.Entry<Integer, RegularExpression> item : JavaCCGlobals.rexps_of_tokens.entrySet()) {
            addTokenImage(allKeywords, item.getValue());
        }

        //clean up
        if (jjGrammarOutputDir.toFile().exists()) {
            jjGrammarOutputDir.toFile().delete();
        }

        return allKeywords;
    }

We can close this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JavaCC | The most popular parser generator for use with Java ...
The most popular parser generator for use with Java applications.
Read more >
Using JavaCC
JavaCC is a lexer and parser generator for LL(k) grammars. You specify a language's lexical and syntactic description in a JJ file, then...
Read more >
Java – How to implement JJTree on grammar – iTecNote
I have an assignment to use JavaCC to make a Top-Down Parser with Semantic ... invoke jjtree on your jjt grammar, which will...
Read more >
How to modularize a JavaCC grammar file (.jj)? - Stack Overflow
There is no way built in to JavaCC to modularize .jj files. The best thing to do is often to use JJT, as...
Read more >
javacc-7.0.2.javacc-releases.notes Maven / Gradle / Ivy
JavaCC [tm]: Release Notes THIS FILE IS A COMPLETE LOG OF ALL CHANGES THAT HAVE ... .jjt file if the .jj file is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found