antlr / antlr/antlr4

Explicit labels not assigned to unless reference (in the context objects)

Open
#552 1 comment 0 reactions 0 assignees View on GitHub
actions code-gen type:bug
Dominant language
Java
Stars
19k
Forks
3.5k
PR merge metrics
No merged PRs in 30d

Description

the generated code doesn’t set fields associated with labels.

```
TestParserExec.testListLabelOnSet produces the following:

public static class BContext extends ParserRuleContext {
public Token INT;
public List val = new ArrayList();
public Token FLOAT;
public Token _tset26;
public List FLOAT() { return getTokens(TParser.FLOAT); }
public List INT() { return getTokens(TParser.INT); }
```

but actually Token INT and Token FLOAT are never used, and are a potential source of confusion, not speaking of conflicts in certain target languages such as Python.

We state that parameters and local variables become fields in the context objects; that is a nonportable way to associate fields with context objects for semantic passes over the trees later. ultimately, I think we need a parse tree factory, but the book specifically talks about this and we might break a lot of code.

I also just noticed that labels are referenced in fact using the field:

```
/** If we don't know location of label def x, use this template */
labelref(x) ::= "(()_localctx)."
```

are you sure this is not being used? it seems to be referenced a lot in the template.

More thoughts:

```
b : ID val+=(INT | FLOAT)* {Token t = $ID;} ;
```

generates

```
public static class BContext extends ParserRuleContext {
public Token ID;
public Token INT;
public TerminalNode ID() { return getToken(TParser.ID, 0); }
...
}
```

ID is set but only i think because we ref it:

```
((BContext)_localctx).ID = match(ID);
```

ctx.ID() would also work but it’s duplication.

Adding $INT ref:

```
b : ID val+=(INT | FLOAT)* {Token t = $ID; $INT;} ;
```

gives action:

```
Token t = ((BContext)_localctx).ID; ((BContext)_localctx).INT;
```

BUT, INT not set, just ID. interesting. Maybe tokens in loops that yield lists yield superfluous fields.

Suggested solution:
- for explicit labels, always set them but leave as fields for quick access (though redundant).
- implicit $token refs always use .token() not .token

Contributor guide

Open the contributing guide

Research direction

Start with TestParserExec.testListLabelOnSet and compare the generated BContext and action output for explicit labels, loop labels, and implicit token references. Read the labelref(x) template and the examples in the issue first. Done means the intended field assignment and token-access behavior is defined and covered by generated-output tests without the reported redundant or conflicting fields.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, python
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.