antlr v4 使用指南连载4——词法规则入门之黄金定律
词法规则入门#
黄金定律一二
- 若输入串能被多个词法规则匹配,那么声明在词法文件最前面的规则生效。
parser
parser grammar HelloParser;
options {
language=Java;
tokenVocab=HelloLexer;
}
start : HI ID;
lexer例1
lexer grammar HelloLexer; //Definea grammar called Hello
ID : [a-zA-Z]+;
HI : 'H' 'I';
WS : [\t\r\n ]+->skip; //skip spaces,tabs,newlines,\r(Windows)
lexer例2
lexer grammar HelloLexer; //Definea grammar called Hello
HI : 'H' 'I';
ID : [a-zA-Z]+;
WS : [\t\r\n ]+->skip; //skip spaces,tabs,newlines,\r(Windows)
当输入串为HI antlr时,对于语法规则start,只有使用例2的词法文件时,才能匹配成功。原因在于,这两个例子中,HI可以被词法规则HI、ID匹配。对于例1,输入串HI,被词法ID优先匹配,antlr也被ID词法匹配,所以无法匹配语法规则start : HI ID;。对于例2,输入串HI,被词法HI优先匹配,antlr被ID词法匹配。
- 输入串将被最长匹配的词法规则匹配。下面用一个稍微复杂一点的例子来说明,本来可以不用例子,一句话也能说明白。比如ABCD肯定会被能完全匹配ABCD的词法规则匹配,而不是将ABCD拆开分别被匹配,例如被两个词法ABC、D匹配。
parser
parser grammar HelloParser;
options {
language=Java;
tokenVocab=HelloLexer;
}
numeric_literal : INTEGER | NUMERIC;
lexer
//lexer
lexer grammar HelloLexer; //Definea grammar called Hello
ZERO : '0';
DOT : '.';
UNDERLINE : '_';
HI : 'H' 'I';
fragment
DIGIT : [0-9];
INTEGER : ZERO|[1-9] DIGIT*;
NUMERIC : INTEGER DOT DIGIT+;
ALPHABET : [a-zA-Z];
ID : (ALPHABET|UNDERLINE) (DIGIT|ALPHABET|UNDERLINE)+;
WS : [\t\r\n ]+->skip; //skip spaces,tabs,newlines,\r(Windows)
对于输入串12.03,只会被NUMERIC词法匹配,而不会被拆成12、.、0、3分别被INTEGER、DOT、INTEGER、INTEGER匹配。这就是最长匹配原则,也叫贪婪匹配。
未完待续>>>