为了解析测试文件,我想让标识符以数字开头。
我的规则是:
ID : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '&' | '/' | '-' | '.')*
;
但是我也需要匹配此文件中的数字。我的理由是:
INT : '0'..'9'+
;
显然Antlr不允许我这样做,因为INT永远不会匹配。
有没有办法允许这个?具体来说,我想匹配一个INTEGER,后跟一个ID,没有空格只是一个ID,只有当后面跟一个空格时才创建一个INT令牌。
例如:
3BOB -> [ID with text "3BOB"]
3 BOB -> [INT with text "3"] [ID with text "BOB"]
答案 0 :(得分:2)
只需更改ID和INT标记的定义顺序。
grammar qqq;
// Parser's rules.
root:
(integer|identifier)+
;
integer:
INT {System.out.println("INT with text '"+$INT.text+"'.");}
;
identifier:
ID {System.out.println("ID with text '"+$ID.text+"'.");}
;
// Lexer's tokens.
INT: '0'..'9'+
;
ID: ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')
('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '&' | '/' | '-' | '.')*
;
WS: ' ' {skip();}
;
UNPREDICTED_TOKEN
:
~(' ') {System.out.println("Unpredicted token.");}
;
在语法中定义标记的顺序非常重要:如果字符串可以归因于多个标记,则归因于首先定义的标记。在你的情况下,如果你想要将整数'123'归为INT,当它仍然符合ID时 - 首先放置INT定义。
Antlr的令牌匹配是贪婪的,因此它不会在'123BOB'中的'123'上停止,但会一直持续直到非令牌匹配字符串并使最后一个令牌匹配。所以你的标识符现在可以从数字开始。
也可以在this article by Mark Volkmann中找到关于令牌订单的评论。
答案 1 :(得分:1)
您的规则中的以下微小变化应该可以解决问题:
ID : ('0'..'9')* // optional numbers
('a'..'z' | 'A'..'Z' | '_' | '&' | '/' | '-' | '.') // followed by mandatory character which is not a number
('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '&' | '/' | '-' | '.')* // followed by more stuff (including numbers)
;
INT : '0'..'9'+ // a number
;
您只需允许您的标识符以可选数字开头,并强制使用以下字符。