不常用的Java语法(JavaParser)?

不常用的Java语法(JavaParser)?,java,algorithm,syntax,syntax-error,Java,Algorithm,Syntax,Syntax Error,我正在探索一个Java语法分析器,我遇到了一段普通代码中通常不会用到的奇怪代码。取自 它有许多包含代码的函数,例如 final public NameExpr Name() throws ParseException { NameExpr ret; jj_consume_token(IDENTIFIER); ret = new NameExpr(token.beginLine, token.beginColumn, token.endLine, token.endCol

我正在探索一个Java语法分析器,我遇到了一段普通代码中通常不会用到的奇怪代码。取自

它有许多包含代码的函数,例如

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");
}

乍一看,它似乎很奇怪,但毫无疑问,它是有效的,因为我可以编译它。但是有人能解释一下它是如何工作的吗?我试着输入无效的Java语法,它做到了!我很困惑。返回后,几行如何抛出异常?

这确实是有效的代码,在没有看到所有内容的情况下,我可以看到一些奇怪之处:

  • “不正确”变量和方法命名,有时使用PascalCase
  • 实例变量
    token
  • 静态变量
    标识符
然后:

这是一个无限循环,只要
jj_2_17(2)
返回
true
,它就会一直运行,但在该结果出现时不会执行任何操作。当表达式为
false
时,它从
标签23
中断开。让未来的读者更加困惑的是,只有当表达式是
true
(当它在
false
上断开时)即最后三行时,它才真正起作用

关于进一步的信息,
标签\u 23
只是一个标签,只能在
上使用,而
用于
循环。然后,当使用
break labelName时,您可以将从该循环中断开

从内环中断开外环的示例:

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

所以这一切都是有效的。我想我们也很有可能得出结论,这段代码是机器生成的。

这里可能最让人困惑的是if-else在while中阻塞了

事实上,如果:

if(!jj_2_17(2)) {
    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);
所以实际上这段代码只返回最后一个
QualifiedNameExpr(/*…*/)

关于你在评论中提到的“无法到达的投掷”。想象一下,当您创建一个方法(在eclipse或netbeans中)而不添加return语句时会发生什么


生成的代码(假设这里是生成的代码)不包含return语句,然后突然抛出错误。这导致eclipse/netbeans/[insert IDE here]告诉您“函数中缺少返回语句”,这正是该语句的目的……

确保识别不理解的确切代码/语法:即它是“标签”吗?“空话”?“无用的抛出”?我无法给出答案,因为我从来没有遇到过这样的事情,但这似乎在Oracle教程中有概述。是的,我指的是块标签、围绕返回的额外大括号、无用的if语句和不可到达的抛出。它看起来像是生成的代码。也许从Antral?break到label是goto的邪恶表亲。这个类似乎是根据其大小手动完成的,并且必须手动对所有标签进行编码?@Nederealm我想说这个代码强烈表明它是机器生成的。为了回答您关于标签只能用于while或for循环的观点,从技术上讲,不仅如此。break语句对于没有循环的标记块也是有效的。请参阅我的编辑。
{
    if (true) {
        return ret;
    }
}
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(!jj_2_17(2)) {
    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);