antlr4-c3 icon indicating copy to clipboard operation
antlr4-c3 copied to clipboard

Semantic Predicate not working

Open albyrock87 opened this issue 3 years ago • 4 comments

Hello,

it seems that semantic predicates are not handled.

Given the following grammar with semantic predicates

grammar Expr;

@parser::header {
  export function isSummable(ID: string) {
    // symbol table checks here.. now using a mock logic
    return ID.startsWith('x');
  }
}

expression
  : summableIdentifier '+' NUM
  | subtractableIdentifier '-' NUM
  ;
  
summableIdentifier: {isSummable(this.currentToken.text)}? ID;
subtractableIdentifier: {!isSummable(this.currentToken.text)}? ID;

ID: [a-z];
NUM: [0-9]+;

WHITESPACE
	: [ \t\r\n] -> skip
	;

during prediction this.currentToken is <EOF> so all checks are not working.

I think that prediction algorithm should walk the parsed tree until caretTokenIndex is reached, and only then determine follow sets, but maybe I'm totally wrong.

Thanks so much for this awesome library.

albyrock87 avatar Sep 10 '20 10:09 albyrock87

@mike-lischke if you have an hint on how to fix this, maybe I can help and try to make a pull request

albyrock87 avatar Sep 10 '20 13:09 albyrock87

Well, without debugging I cannot say for sure, but I suspect that this.currentToken.text is not available in the predicate code (remember this is just using eval() to execute things). You cannot use ANTLR runtime code in your action file, only what's passed in.

mike-lischke avatar Sep 10 '20 14:09 mike-lischke

Yes, you're right, during predicate.eval() context is not available.

I followed this official tutorial https://github.com/antlr/antlr4/blob/master/doc/predicates.md#finding-visible-predicates where it suggests to use getCurrentToken() (should be equal to this.currentToken in antlr4ts).

Also a more complex case like context dependant predicates fails.

Do you know if is it possible to get current token during predicion? Thanks

albyrock87 avatar Sep 10 '20 14:09 albyrock87

The problem seems to be that the parser's token stream is at the end (EOF), which is correct because the text was already parsed to the end. If you seek the input stream to the corresponding token (parser.tokenStream.seek(index) before transition.predicate.eval) the predicate get's the correct token.

ptr1120 avatar Dec 31 '20 14:12 ptr1120