消除给定ANTLR语法中的额外空格

时间:2010-12-19 18:48:55

标签: antlr

在我在ANTLR中创建的任何语法中,是否可以解析语法,并且解析的结果可以在语法中消除任何额外的空格。 f.e

简单的例子;

int x=5;

如果我写

int x      =          5         ; 

我希望文本在没有额外空格的情况下更改为int x = 5。解析器可以在没有额外空格的情况下返回原始文本吗?

1 个答案:

答案 0 :(得分:3)

  

解析器可以在没有额外空格的情况下返回原始文本吗?

是的,你需要定义一个捕获这些空格的词法分析器规则,然后skip()它们:

Space
  :  (' ' | '\t') {skip();}
  ;

将导致空格和制表符被忽略。

PS。我假设您使用Java作为目标语言。 skip()在其他目标中可能有所不同(例如,对于C#,Skip())。您可能还希望在此规则中包含\r\n个字符。

修改

假设您的语言只包含几个变量声明。假设您了解ANTLR的基础知识,以下语法应该易于理解:

grammar T;

parse
  :  stat* EOF
  ;

stat
  :  Type Identifier '=' Int ';'
  ;

Type
  :  'int'
  |  'double'
  |  'boolean'
  ;

Identifier
  :  ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
  ;

Int
  :  '0'..'9'+
  ;

Space
  :  (' ' | '\t' | '\n' | 'r')+ {skip();}
  ; 

你正在解析来源:

int x   =      5     ; double y     =5;boolean z      =    0  ;

你想改成:

int x=5;
double y=5;
boolean z=0;

这是一种在语法中嵌入代码并让解析器规则返回自定义对象的方法(在本例中为字符串):

grammar T;

parse returns [String str]
@init{StringBuilder buffer = new StringBuilder();}
@after{$str = buffer.toString();}
  :  (stat {buffer.append($stat.str).append('\n');})* EOF
  ;

stat returns [String str]
  :  Type Identifier '=' Int ';' 
     {$str = $Type.text + " " + $Identifier.text + "=" + $Int.text + ";";}
  ;

Type
  :  'int'
  |  'double'
  |  'boolean'
  ;

Identifier
  :  ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
  ;

Int
  :  '0'..'9'+
  ;

Space
  :  (' ' | '\t' | '\n' | 'r')+ {skip();}
  ; 

使用以下类测试它:

import org.antlr.runtime.*;

public class Main {
    public static void main(String[] args) throws Exception {
        String source = "int x   =      5     ; double y     =5;boolean z      =    0  ;";
        ANTLRStringStream in = new ANTLRStringStream(source);
        TLexer lexer = new TLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TParser parser = new TParser(tokens);
        System.out.println("Result:\n"+parser.parse());
    }
}

产生:

Result:
int x=5;
double y=5;
boolean z=0;