如何使用antlr语法定义固定次数重复的模式规则
我知道“+”、“?”和“*”。但是如果我想要某个东西重复,比如说,5次呢?例如,如果标识符必须是长度为5的十六进制数字字符串如何使用antlr语法定义固定次数重复的模式规则,antlr,grammar,Antlr,Grammar,我知道“+”、“?”和“*”。但是如果我想要某个东西重复,比如说,5次呢?例如,如果标识符必须是长度为5的十六进制数字字符串 更具体地说,我正在考虑定义一个长度不限的通用lexer规则,然后在解析时计算它重复了多少次,如果它等于5,然后将它重命名为另一种类型的令牌,但我如何才能做到这一点?或者有什么简单的方法吗?您需要指定5次,例如: ZIPCODE: '0'..'9' '0'..'9' '0'..'9' '0'..'9' '0'..'9'; 或者,您可以使用验证语义谓词: DIGIT: '
更具体地说,我正在考虑定义一个长度不限的通用lexer规则,然后在解析时计算它重复了多少次,如果它等于5,然后将它重命名为另一种类型的令牌,但我如何才能做到这一点?或者有什么简单的方法吗?您需要指定5次,例如:
ZIPCODE: '0'..'9' '0'..'9' '0'..'9' '0'..'9' '0'..'9';
或者,您可以使用验证语义谓词:
DIGIT: '0'..'9';
zipcode
@init { int N = 0; }
: (DIGIT { N++; } )+ { N <= 5 }?
;
数字:“0”…'9';
zipcode
@init{int N=0;}
:(数字{N++;})+{N
在解析时,计算它重复了多少次,如果它等于5,那么将它重命名为另一种类型的令牌,但我如何才能做到这一点?或者有什么简单的方法
是的,您可以使用消歧语义谓词()来实现这一点:
它将按如下方式解析输入12345 12345678
:
但您也可以根据匹配文本的某些属性更改lexer中标记的类型,如下所示:
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 : ;
这将导致对相同的输入进行如下解析:
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 : ;
您好,这在语法分析器中有效。可以在Lexer语法中使用吗?好的,我现在在Lexer语法中使用了它。但是我只能有一个这样的规则。如果我想将长度为5的标记命名为短标记,同时将长度为8的标记命名为长标记,是否可以?Antlr投诉“以下标记定义永远无法匹配”。我的意思是,每次{}?计算为false时,这些字符都将被忽略,但我希望lexer检查其他可能的匹配项。谢谢,我尝试了第二种方法。这正是我要找的。