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?
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.
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.
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.
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.
This is indeed valid code, without seeing everything, I can see some odditities:
token
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With