Обязательные и необязательные пробелы - PullRequest
1 голос
/ 16 января 2012

Мне нужно разобрать строки следующим образом:

"qqq www eee" -> "qqq", "www", "eee" (case A)
"qqq   www  eee" -> "qqq", "www", "eee" (case B)

Вот грамматика, которая у меня сейчас есть:

grammar Query;

SHORT_NAME : ('a'..'z')+ ;

name returns [String s]: SHORT_NAME { $s = $SHORT_NAME.text; };      

names 
    returns [List<String> v]
    @init { $v = new ArrayList<String>(); }
    : name1 = name { $v.add($name1.s); } 
      (' ' name2 = name { $v.add($name2.s); })*;

Работает нормально для caseA, но не для caseB:

line 1:4 missing SHORT_NAME at ' '
line 1:5 extraneous input ' ' expecting SHORT_NAME
line 1:10 extraneous input ' ' expecting SHORT_NAME

Есть идеи, как заставить это работать?

1 Ответ

2 голосов
/ 16 января 2012

Удалите литерал ' ' из вашего правила names и замените его токеном SPACES:

grammar Query;

SPACES
 : (' ' | '\t')+
 ;

SHORT_NAME 
 : ('a'..'z')+ 
 ;

name returns [String s]
 : SHORT_NAME { $s = $SHORT_NAME.text; }
 ;      

names returns [List<String> v]
@init { $v = new ArrayList<String>(); }
 : a=name { $v.add($a.s); } (SPACES b=name { $v.add($b.s); })*
 ;

Или просто отбросьте пробелы на уровне лексера, чтобы вам не нужно было включать их в правила парсера:

grammar Query;

SPACES
 : (' ' | '\t')+ {skip();}
 ;

SHORT_NAME 
 : ('a'..'z')+ 
 ;

name returns [String s]
 : SHORT_NAME { $s = $SHORT_NAME.text; }
 ;      

names returns [List<String> v]
@init { $v = new ArrayList<String>(); }
 : (name { $v.add($b.s); })+
 ;
...