Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncommonly used Java syntax (JavaParser)?

I'm exploring a Java grammar parser and I came across this strange piece of code that I wouldn't normally use in ordinary code. Taken from https://code.google.com/p/javaparser/source/browse/branches/mavenized/JavaParser/src/main/java/japa/parser/ASTParser.java#1998

It has many functions that contains code such as

final public NameExpr Name() throws ParseException {
    NameExpr ret;
    jj_consume_token(IDENTIFIER);
    ret = new NameExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
    label_23: while (true) {
        if (jj_2_17(2)) {
            ;
        } else {
            break label_23;
        }
        jj_consume_token(DOT);
        jj_consume_token(IDENTIFIER);
        ret = new QualifiedNameExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, token.image);
    }
    {
        if (true) {
            return ret;
        }
    }
    throw new Error("Missing return statement in function");
}

At a glance it appears strange but no doubt it's valid as I can compile it. But can someone explain how it works? I have tried to input invalid Java syntax and it does it's job! I'm baffled. How does the few lines throw exception after the return?

like image 935
Nederealm Avatar asked May 28 '14 07:05

Nederealm


People also ask

What is javaparser?

The JavaParser community is vibrant and active, with a weekly release cadence that supports language features up to Java 12. Available either under either the terms of the LGPL or Apache Licenses. Our goal is to build a simple and lightweight set of tools to analyze, transform and generate Java code.

What do you like the most about Java parser?

One of the things I like the most is to parse code and to perform automatic operations on it. For this reason I started contributing to JavaParser and created a couple of related projects: java-symbol-solver and effectivejava.

Should I use a visitor or a class in Java parser?

use a visitor: this is the right strategy when you want to operate on specific types of AST nodes Visitors can be written extending classes included in JavaParser, while this is a simple node iterator: Now let’s see how to use this code to solve some questions found on Stack Overflow.

Can We extend classes included in Java parser?

Visitors can be written extending classes included in JavaParser, while this is a simple node iterator: Now let’s see how to use this code to solve some questions found on Stack Overflow. How to extract the name of all classes in a normal String from java class? This solution can be solved looking for the ClassOrInterfaceDeclaration nodes.


1 Answers

This is indeed valid code, without seeing everything, I can see some odditities:

  • 'Incorrect' variable and method naming, using PascalCase sometimes.
  • Instance variable token
  • Static variable IDENTIFIER

Then:

label_23: while (true) {
    if (jj_2_17(2)) {
        ;
    } else {
        break label_23;
    }
    jj_consume_token(DOT);
    jj_consume_token(IDENTIFIER);
    ret = new QualifiedNameExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, token.image);
}

This is an infinite loop that keeps running as long as jj_2_17(2) returns true, but appears to do nothing upon that result. It breaks out of label_23 when the expression was false. To confuse future readers even more, it then actually does things only if the expression is true (as it breaks on false), namely the last three lines.

For futher information, the label_23 is simply a label that may only be used on while and for loops. You can then break out of that loop when using break labelName;.

Example that breaks out of an outer loop from within an inner loop:

outerLoop: for (int i = 0; i < max; i++) {
    innerLoop: for (int j = 0; j < max2 - i; j++) {
        if (something) {
            break outerLoop;
        }
        //...
    }
}

You can actually also use continue in combination with labels.

Then we see a scoped block without guard that always returns ret:

{
    if (true) {
        return ret;
    }
}

So it's all valid. I think we can also conclude with high chance that this code has been machine-generatd.

like image 152
skiwi Avatar answered Sep 18 '22 15:09

skiwi