我正在尝试为bat / cmd文件创建一个(简单的)Lexer(用于语法着色)。作为此任务的一部分,我需要将关键字与(任意)标识符分开。但是根据this answer,ANTLR尝试让最长的比赛胜过较短的比赛。到目前为止,我的语法看起来像这样
lexer grammar CmdLexer;
Identifier
: IdentifierNonDigit
( IdentifierNonDigit
| Digit
)+
;
Number
: Digit+
;
fragment IdentifierNonDigit
: [a-zA-Z_\u0080-\uffff]
;
fragment Digit
: [0-9]
;
Punctuation
: [\u0021-\u002f\u003a-\u0040\u005b-\u0060\u007b-\u007f]+
;
Keyword
: A P P E N D
| A T
| A T T R I B
| B R E A K
| C A L L
| C D
| C H C P
| C H D I R
| C L S
| C O L O R
| C O P Y
| D A T E
| D E L
| D I R
| D O
| E C H O
| E D I T
| E N D L O C A L
| E Q U
| E X I S T
| E X I T
| F C
| F O R
| F T Y P E
| G O T O
| G E Q
| G T R
| I F
| I N
| L E Q
| L S S
| M D
| M K D I R
| M K L I N K
| M O R E
| M O V E
| N E Q
| N O T
| N U L
| P A T H
| P A U S E
| P O P D
| P U S H D
| R D
| R E N
| R E N A M E
| S E T
| S E T L O C A L
| S H I F T
| S T A R T
| T I T L E
| T R E E
| T Y P E
| W H E R E
| W H O A M I
| X C O P Y
;
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');
Whitespace
: [ \t]+
-> skip
;
Newline
: ( '\r' '\n'?
| '\n'
)
-> skip
;
LineComment
: ( '@'? R E M ~[\r\n]*
| '@'? '::' ~[\r\n]*
)
-> skip
;
但它始终将所有内容都匹配为Identifier
,甚至是append
或CALL
之类的单词。我在这里看不到模式如何解决此问题,但如何给某个规则更高的优先级(此处Keyword
高于其他规则(此处Identifier
)?
但是根据这个答案,ANTLR试图让最长的比赛胜过较短的比赛。
确实如此,那应该是您想要的。请注意,此规则(所谓的最大munch规则)与append
是否匹配为关键字或标识符无关。与appendix
是否与关键字append
相匹配,后跟标识符ix
有关;或作为单个标识符appendix
。由于后者显然是大多数情况下想要的,因此最大的munch规则很有用。
在这种情况下,重要的是,如果多个规则产生相同长度的匹配项,将会发生什么。在这种情况下,ANTLR将应用语法中首先定义的规则。因此,如果您更改定义的顺序,以使Keyword
在Identifier
之前,则在两个规则产生相同长度的匹配项时,Keyword
规则将优先(并且最长的匹配项仍会获胜)情况并非如此)。因此,像append appendix
这样的输入将被标记为关键字append
,后跟标识符appendix
,这应该是您想要的。
PS:我不确定您的词法分析器将在何处/如何使用,但是通常您希望区分不同的关键字,而不是使用一个匹配所有关键字的规则。如果令牌将用作解析器的输入,则在不知道它是哪个关键字的情况下,某些东西是关键字的信息不是很有用。