Search code examples
javaantlrgrammargreedynon-greedy

How can I access blocks of text as an attribute that are matched using a greedy=false option in ANTLR?


I have a rule in my ANTLR grammar like this:

COMMENT :  '/*' (options {greedy=false;} : . )* '*/' ;

This rule simply matches c-style comments, so it will accept any pair of /* and */ with any arbitrary text lying in between, and it works fine.

What I want to do now is capture all the text between the /* and the */ when the rule matches, to make it accessible to an action. Something like this:

COMMENT :  '/*' e=((options {greedy=false;} : . )*) '*/' {System.out.println("got: " + $e.text);

This approach doesn't work, during parsing it gives "no viable alternative" upon reaching the first character after the "/*"

I'm not really clear on if/how this can be done - any suggestions or guidance welcome, thanks.


Solution

  • Try this:

    COMMENT :
      '/*' {StringBuilder comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.appendCodePoint(c);} )* '*/' {System.out.println(comment.toString());};

    Another way which will actually return the StringBuilder object so you can use it in your program:

    COMMENT returns [StringBuilder comment]:
      '/*' {comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.append((char)c);} )* '*/';