устранить лишние пробелы в данной грамматике ANTLR - PullRequest
3 голосов
/ 19 декабря 2010

В любой грамматике, которую я создаю в ANTLR, возможно ли проанализировать грамматику, и результат анализа может уничтожить любые лишние пробелы в грамматике.fe

простой пример;

int x=5;

если я напишу

int x      =          5         ; 

Я хотел бы, чтобы текст изменился на int x = 5 без лишних пробелов.Может ли парсер вернуть исходный текст без лишних пробелов?

1 Ответ

3 голосов
/ 19 декабря 2010

Может ли синтаксический анализатор вернуть исходный текст без лишних пробелов?

Да, вам нужно определить правило лексера, которое фиксирует эти пробелы, а затем skip() их:

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

, что приведет к игнорированию пробелов и символов табуляции.

PS. Я предполагаю, что вы используете Java в качестве целевого языка. skip() может отличаться в других целях (например, Skip() для C #). Вы также можете включить в это правило символы \r и \n.

EDIT

Допустим, ваш язык состоит только из пары объявлений переменных. Предполагая, что вы знакомы с основами 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;

Вот способ встроить код в вашу грамматику и позволить правилам синтаксического анализа возвращать пользовательские объекты (в данном случае Strings):

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;
...