Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

antlr - How to preserve whitespace when we use text attribute in Antlr4

I want to keep white space when I call text attribute of token, is there any way to do it? Here is the situation: We have the following code

IF L > 40 THEN;

ELSE

  IF A = 20 THEN
      PUT "HELLO";

In this case, I want to transform it into:

if (!(L>40){

      if (A=20)
          put "hello";
}

The rule in Antlr is that:

stmt_if_block: IF expr
               THEN x=stmt
               (ELSE y=stmt)?
               {
                 if ($x.text.equalsIgnoreCase(";"))
                 {
                   WriteLn("if(!(" + $expr.text +")){");
                   WriteLn($stmt.text);
                   Writeln("}");
                 }
               }

But the result looks like:

if(!(L>40))
{
   ifA=20put"hello";
}

The reason is that the white space in $stmt was removed. I was wondering if there is anyway to keep these white space
Thank you so much

Update: If I add

SPACE: [ ] -> channel(HIDDEN);

The space will be preserved, and the result would look like below, many spaces between tokens:

 IF SUBSTR(WNAME3,M-1,1) = ')'             THEN                                        M = L;                                  ELSE                                        M = L - 1;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is the C# extension method I use for exactly this purpose:

public static string GetFullText(this ParserRuleContext context)
{
    if (context.Start == null || context.Stop == null || context.Start.StartIndex < 0 || context.Stop.StopIndex < 0)
        return context.GetText(); // Fallback

    return context.Start.InputStream.GetText(Interval.Of(context.Start.StartIndex, context.Stop.StopIndex));
}

Since you're using java, you'll have to translate it, but it should be straightforward - the API is the same.

Explanation: Get the first token, get the last token, and get the text from the input stream between the first char of the first token and the last char of the last token.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...