换行规则
NewLine: '\r'? '\n';
不定长序列规则
row: field (',' field)*;
循环与尾递归
ANTLR
支持的循环写法:
object: '{' pair (',' pair)*
'}' | '{' '}';
BNF 支持的尾递归写法:
object: '{' members '}';
members: pair | pair
members;
十六进制数字规则
fragment
HEX : [0-9a-fA-F] ;
浮点数规则
NUMBER
: '-'? INT '.' INT EXP? // 1.35, 1.35E-9, 0.3, -4.5
| '-'? INT EXP // 1e10 -3e4
| '-'? INT // -3, 45
;
fragment
INT : '0' | [1-9] [0-9]* ;
// no leading
zeros
fragment
EXP : [Ee] [+\-]? INT ; // \- since - means "range" inside
[...]
其中,中括号的减号需要转义,因为中括号中用减号做范围符号,例如:[a-zA-Z]
空白分隔符规则
一般语言中,用空白分隔符(比如:空格,制表符,换行符等)来分隔有意义的符号。
WS : [ \t\n\r]+ -> skip ;
中括号中有四个选项,分别是:空格、\t、\n、\r
不区分大小写的关键字规则
STRICT :
[Ss][Tt][Rr][Ii][Cc][Tt] ;
中括号中的转义符
STRING: '"'
(ESC | ~["\\])*
'"';
其中,中括号中的选项有 2 个,分别是:" 和 \
fragmentESC
: '\\' (["\\/bfnrt] | UNICODE)
;
其中,中括号中的选项有 8 个,分别是:"、\、/、b、f、n、r、t、
DOT 中嵌套 HTML STRING
的处理方法
规则1:
HTML_STRING :
'
(TAG|~[<>])*
'>' ;
fragmentTAG
: '
.*? '>' ;
上述规则,在匹配如下字符串:
时,做如下分解:
'
'A' ->
'<'
->
'A' ->
'>' ->
'>'
最后一个尖括号匹配失败。
规则2:
HTML_STRING :
'
(HTML_STRING|~[<>])*
'>' ;
类 C 的命令式编程语言框架
从下图中不难看出,表达式是这类语言的核心模块。
Multi-Mode in lexer grammar
1. ANTLR
只支持在单独的词法文件中编写多模式指令,在词法、语法混合的语法文件中不能写多模式指令
2. 包含多模式指令的词法文件,不支持通过 import
指令导入到其他语法文件中,只能通过如下选项指令导入:
options {
tokenVocab=LexerName;
}
单个字符匹配的词法规则
Any: . ;
上述词法规则匹配任意一个字符。这个规则避免了如下规则:
Text: .*;
匹配范围太过宽泛的问题(这导致其他词法规则都没有匹配的机会)。
但坏处也很明显,所有被匹配的单个字符都作为单独的符号(Token)投递给了语法分析器。