-
Enhancement
-
Resolution: Fixed
-
P4
-
jfx12
We can do this in antlr4 by using the new visitor mechanism. Keeping
the grammar definition separate from the logic (embedded actions)" promotes the separation
of concerns between parsing and parser application". It also makes the
grammar easier to read and understand.
The PR of the linked `github-bug` takes a direct approach to extracting the embedded actions and does not change the end results of a generated shader. That is, a shader generated with JSLC before this PR and after will be identical. Here is an example of such a migration (for the unary_expression rule):
unary_expression returns [Expr expr]
: p=postfix_expression { $expr = $p.expr; }
| INC u=unary_expression { $expr = tm.unary(UnaryOpType.INC, $u.expr); }
| DEC u=unary_expression { $expr = tm.unary(UnaryOpType.DEC, $u.expr); }
| PLUS u=unary_expression { $expr = tm.unary(UnaryOpType.PLUS, $u.expr); }
| DASH u=unary_expression { $expr = tm.unary(UnaryOpType.MINUS, $u.expr); }
| BANG u=unary_expression { $expr = tm.unary(UnaryOpType.NOT, $u.expr); }
;
This is changed to:
unary_expression
: p=postfix_expression
| INC u=unary_expression
| DEC u=unary_expression
| PLUS u=unary_expression
| DASH u=unary_expression
| BANG u=unary_expression
;
and the following method of the JSLVisitor class auto-generated by antlr4 (this is done because of the newly added -visitor parameter to the antlr4 program invocation) is implemented in our (new to this PR) JSLVisitor class (it's more complicated to explain in words than with code, lol).
@Override
public Expr visitUnary_expression(JSLParser.Unary_expressionContext ctx) {
if (ctx.INC() != null) {
return tm.unary(UnaryOpType.INC, visitUnary_expression(ctx.u));
} else if (ctx.DEC() != null) {
return tm.unary(UnaryOpType.DEC, visitUnary_expression(ctx.u));
} else if (ctx.PLUS() != null) {
return tm.unary(UnaryOpType.PLUS, visitUnary_expression(ctx.u));
} else if (ctx.DASH() != null) {
return tm.unary(UnaryOpType.MINUS, visitUnary_expression(ctx.u));
} else if (ctx.BANG() != null) {
return tm.unary(UnaryOpType.NOT, visitUnary_expression(ctx.u));
} else if (ctx.postfix_expression() != null){
return visitPostfix_expression(ctx.p);
}
throw new RuntimeException("invalid unary expression");
}
This is a followup toJDK-8218170.
the grammar definition separate from the logic (embedded actions)" promotes the separation
of concerns between parsing and parser application". It also makes the
grammar easier to read and understand.
The PR of the linked `github-bug` takes a direct approach to extracting the embedded actions and does not change the end results of a generated shader. That is, a shader generated with JSLC before this PR and after will be identical. Here is an example of such a migration (for the unary_expression rule):
unary_expression returns [Expr expr]
: p=postfix_expression { $expr = $p.expr; }
| INC u=unary_expression { $expr = tm.unary(UnaryOpType.INC, $u.expr); }
| DEC u=unary_expression { $expr = tm.unary(UnaryOpType.DEC, $u.expr); }
| PLUS u=unary_expression { $expr = tm.unary(UnaryOpType.PLUS, $u.expr); }
| DASH u=unary_expression { $expr = tm.unary(UnaryOpType.MINUS, $u.expr); }
| BANG u=unary_expression { $expr = tm.unary(UnaryOpType.NOT, $u.expr); }
;
This is changed to:
unary_expression
: p=postfix_expression
| INC u=unary_expression
| DEC u=unary_expression
| PLUS u=unary_expression
| DASH u=unary_expression
| BANG u=unary_expression
;
and the following method of the JSLVisitor class auto-generated by antlr4 (this is done because of the newly added -visitor parameter to the antlr4 program invocation) is implemented in our (new to this PR) JSLVisitor class (it's more complicated to explain in words than with code, lol).
@Override
public Expr visitUnary_expression(JSLParser.Unary_expressionContext ctx) {
if (ctx.INC() != null) {
return tm.unary(UnaryOpType.INC, visitUnary_expression(ctx.u));
} else if (ctx.DEC() != null) {
return tm.unary(UnaryOpType.DEC, visitUnary_expression(ctx.u));
} else if (ctx.PLUS() != null) {
return tm.unary(UnaryOpType.PLUS, visitUnary_expression(ctx.u));
} else if (ctx.DASH() != null) {
return tm.unary(UnaryOpType.MINUS, visitUnary_expression(ctx.u));
} else if (ctx.BANG() != null) {
return tm.unary(UnaryOpType.NOT, visitUnary_expression(ctx.u));
} else if (ctx.postfix_expression() != null){
return visitPostfix_expression(ctx.p);
}
throw new RuntimeException("invalid unary expression");
}
This is a followup to