antlr / antlr/antlr4

_localctx not casted to correct class when using Alternative Labels

Open
#767 7 comments 0 reactions 1 assignee View on GitHub

@parrt is already working on this.

Since Nov 29, 2014.

actions code-gen comp:tool type:bug
Dominant language
Java
Stars
19k
Forks
3.5k
PR merge metrics
No merged PRs in 30d

Description

Hi,

Here is a parser rule with two different types of alternatives:
- with two numerical arguments `BinaryNumberOp`
- with two logical arguments `BinaryLogicalOp`

``` antlr
logicalExpression returns [ LogicalExpression val ]:
l = number '>' r = number { $val = lt($ctx.r.val, $ctx.l.val); } # BinaryNumberOp
| l = number '>=' r = number { $val = le($ctx.r.val, $ctx.l.val); } # BinaryNumberOp
| l = number '<' r = number { $val = lt($ctx.l.val, $ctx.r.val); } # BinaryNumberOp
| l = number '<=' r = number { $val = le($ctx.l.val, $ctx.r.val); } # BinaryNumberOp
| l = number '==' r = number { $val = eq($ctx.l.val, $ctx.r.val); } # BinaryNumberOp
| l = logicalExpression '&&' r = logicalExpression { $val = and($ctx.l.val, $ctx.r.val); } # BinaryLogicalOp
| l = logicalExpression '||' r = logicalExpression { $val = or($ctx.l.val, $ctx.r.val); } # BinaryLogicalOp
;
```

Here is a fragment of code generated for one of alternatives.

``` java
setState(59);
((BinaryNumberOpContext)_localctx).l = number();
setState(60); match(T__5);
setState(61); ((BinaryNumberOpContext)_localctx).r = number();
((BinaryNumberOpContext)_localctx).val = lt(_localctx.r.val, _localctx.l.val);
}
```

The problem is that `_localctx` in the `lt(...)` function invocation is not converted to current local context type `BinaryNumberOpContext`, so this code can't be compiled because base class (`LogicalExpressionContext`) doesn't contain `.r` and `.l` fields.

I'm not sure if it is a bug, but it seems like in this situation `_localctx` can be casted to current local context class without any problems.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.