如何使用antlr语法定义一个固定次数重复的模式规则

时间:2012-03-07 01:33:17

标签: antlr grammar

我知道'+','?'和'*'。但是,如果我想要一些东西重复,比如5次呢?例如,如果标识符必须是长度为5的十六进制数字的字符串

更具体地说,我正在考虑定义一个无限长度的通用词法分析器规则,然后在解析时计算它重复的时间,如果等于5,则将其重命名为另一种类型的令牌,但我怎么能这样做?或者有一些简单的方法吗?

2 个答案:

答案 0 :(得分:4)

  

在解析时计算重复的时间,如果它等于5,则将其重命名为另一种类型的令牌,但我该怎么办呢?或者有一些简单的方法吗?

是的,你可以用消除歧义的语义谓词explanation)来做到这一点:

grammar T;

parse
 : (short_num | long_num)+ EOF
 ;

short_num
 : {input.LT(1).getText().length() == 5}? NUM
 ;

long_num
 : {input.LT(1).getText().length() == 8}? NUM
 ;

NUM
 : '0'..'9'+
 ;

SP
 : ' ' {skip();}
 ;

将解析输入12345 12345678,如下所示:

enter image description here

但您也可以根据匹配文本的某些属性更改词法分析器中的标记类型,如下所示:

grammar T;

parse
 : (SHORT | LONG)+ EOF
 ;

NUM
 : '0'..'9'+
   {
     if(getText().length() == 5) $type = SHORT;
     if(getText().length() == 8) $type = LONG;
     // when the length is other than 5 or 8, the type of the token will stay NUM
   }
 ;

SP
 : ' ' {skip();}
 ;

fragment SHORT : ;
fragment LONG : ;

将导致相同的输入被解析如下:

enter image description here

答案 1 :(得分:1)

您需要指定5次,例如:

ZIPCODE: '0'..'9' '0'..'9' '0'..'9' '0'..'9' '0'..'9'; 

或者,您可以使用 验证语义谓词

DIGIT: '0'..'9';
zipcode
@init { int N = 0; }
  :  (DIGIT { N++; } )+ { N <= 5 }?
  ;

请参阅:What is a 'semantic predicate' in ANTLR?