How to preserve whitespace when we use text attrib

2019-07-02 00:53发布

问题:

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;

回答1:

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.



标签: antlr antlr4