ANTLR能否根据以下字符区分lexer规则?
为了解析测试文件,我希望允许标识符以数字开头 我的规则是:ANTLR能否根据以下字符区分lexer规则?,antlr,lexer,Antlr,Lexer,为了解析测试文件,我希望允许标识符以数字开头 我的规则是: ID : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '&' | '/' | '-' | '.')* ; 但是,我还需要匹配此文件中的数字。我的原则是: INT : '0'..'9'+ ; 显然,Antlr不会让我这么做,因为INT永远不会匹配 有没有办法允许这样做?具体地说,我希望匹配一个整数,后跟一
ID : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '&' | '/' | '-' | '.')*
;
但是,我还需要匹配此文件中的数字。我的原则是:
INT : '0'..'9'+
;
显然,Antlr不会让我这么做,因为INT永远不会匹配
有没有办法允许这样做?具体地说,我希望匹配一个整数,后跟一个ID,不带空格,作为一个ID,并且仅当它后跟一个空格时,才创建一个INT标记
例如:
3BOB -> [ID with text "3BOB"]
3 BOB -> [INT with text "3"] [ID with text "BOB"]
只需更改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”在仍然符合ID的情况下被赋予INT属性,请将INT定义放在第一位
Antlr的令牌匹配是贪婪的,因此它不会在“123BOB”中的“123”上停止,而是将继续,直到没有一个令牌匹配字符串并获取最后一个匹配的令牌。因此,您的标识符现在可以从数字开始
关于令牌顺序的备注也可以在中找到。只需更改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”在仍然符合ID的情况下被赋予INT属性,请将INT定义放在第一位
Antlr的令牌匹配是贪婪的,因此它不会在“123BOB”中的“123”上停止,而是将继续,直到没有一个令牌匹配字符串并获取最后一个匹配的令牌。因此,您的标识符现在可以从数字开始
您还可以在中找到有关代币顺序的备注。您的规则中的以下细微更改应该可以起到作用:
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
;
您只需允许您的标识符以可选数字开头,并强制使用以下字符。规则中的以下细微更改即可实现此目的:
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
;
您只需允许标识符以可选数字开头,并强制使用以下字符。我不清楚这有什么帮助。这是如何让我的标识符以数字开始的?@chollida,我试着做一个更好的解释,看看它是否有帮助。我不清楚这会有什么帮助。这是怎么让我的标识符从数字开始的?@chollida,我试着做一个更好的解释,看看是否有帮助。