强制和可选空间

时间:2012-01-16 05:07:44

标签: parsing antlr antlr3

我需要解析这样的字符串:

"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 个答案:

答案 0 :(得分:2)

' '规则中删除文字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); })+
 ;