[在Antlr4中使用text属性时如何保留空白

问题描述 投票:4回答:2

调用令牌的文本属性时,我想保留空格,有什么办法吗?情况如下:我们有以下代码

IF L > 40 THEN;

ELSE

  IF A = 20 THEN
      PUT "HELLO";

在这种情况下,我想将其转换为:

if (!(L>40){

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

Antlr中的规则是:

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

但是结果看起来像:

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

原因是$stmt中的空白被删除。我想知道是否还有保留这些空白的地方非常感谢

更新:如果我添加

SPACE: [ ] -> channel(HIDDEN);

将保留空格,结果看起来像下面,令牌之间有许多空格:

 IF SUBSTR(WNAME3,M-1,1) = ')'             THEN                                        M = L;                                  ELSE                                        M = L - 1;
antlr antlr4
2个回答
9
投票

这正是我用于此目的的C#扩展方法:

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));
}

由于您使用的是Java,因此必须对其进行翻译,但是它应该很简单-API是相同的。

说明:获取第一个令牌,获取最后一个令牌,并从输入流中获取第一个令牌的第一个字符与最后一个令牌的最后一个字符之间的文本。


2
投票

@@ Lucas solution,但在Java中,如果您在翻译时遇到麻烦:

private String getFullText(ParserRuleContext context) {
    if (context.start == null || context.stop == null || context.start.getStartIndex() < 0 || context.stop.getStopIndex() < 0)
        return context.getText();

    return context.start.getInputStream().getText(Interval.of(context.start.getStartIndex(), context.stop.getStopIndex()));
}
© www.soinside.com 2019 - 2024. All rights reserved.