Skip to content

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

Open
@parrt

Description

@parrt

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<Token> val = new ArrayList<Token>();
        public Token FLOAT;
        public Token _tset26;
        public List<TerminalNode> FLOAT() { return getTokens(TParser.FLOAT); }
        public List<TerminalNode> 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) ::= "<if(!x.isLocal)>((<x.ctx.name>)_localctx).<endif><x.name>"

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions