2021年1月17日星期日

disabling subrule with semantic predicates in antlr4

Starting with this contrived example .... I have an expression grammar where, depending on context, it might be legal to tag each element of the expression. After a lot of messing around with various approaches I finally got this to work:

grammar TaggedExpression;    @parser::members {    tagOK(cx: ParserRuleContext):boolean {      if (cx instanceof FullExpressionContext) { return true; }      if (cx.parent == undefined) { return false; }      return this.tagOK(cx.parent);    }  }    document    : (fullExpression | simpleExpression) EOF    ;    fullExpression    : FULL expression    ;    simpleExpression    : SIMPLE expression    ;    expression    : NUMBER    | ID    | '(' expression ')'    | '-' expression    | expression ( '+' | '-' ) expression    | expression tag { this.tagOK($ctx) }?    ;    tag: '[' ID ']' ;    FULL: [Ff] [Uu] [Ll] [Ll];  SIMPLE: [Ss] [Ii] [Mm] [Pp] [Ll] [Ee];  ID: ID_CHAR ( ID_CHAR|DIGIT )*;  NUMBER: DIGIT+;  fragment ID_CHAR: [\p{Alphabetic}_];  fragment DIGIT: [0-9];  WHITE_SPACE: [ \u000B\t\r\n] -> skip;    

With this, the sentence FULL ( 1 [left] + 2 [right] ) [sum] parses but SIMPLE 1 [left] will get an error.

I have been wrestling with this for a while, so I am happy to see ANYTHING work, after many failed attempts, but I am not thrilled with this solution either. For one thing the error message is just "failed predicate". For another it is not REALLY in the grammar since it depends on compiler actions.

I know I could do it in the translation pass (which is a visitor walk).

I tried to use parse rules with arguments, but I kept getting internal errors from antlr.

Is there a better way to do this?

https://stackoverflow.com/questions/65769584/disabling-subrule-with-semantic-predicates-in-antlr4 January 18, 2021 at 02:08PM

没有评论:

发表评论