有些字符是不属于源程序范畴内的,这些字符在分析过程中应该忽略掉。在ANTLR中可以在词法定义中加入skip();,(如果是C#为目标语言为Skip();)。在规则的定义的之后与表示定义结束的分号之前加入“{skip();}”。例如下面定义了一个跳过空白的词法定义。
WS : ( ' ' | '\t' | '\n' | '\r' ) +{skip();} ;
空白符号WS中有空格符、制表符、回车和换行符,当遇到这些字符时词法分析程序会调用skip()方法跳过这些字符。
B : 'A' | 'B' {Skip();} | 'C' ;
上面的例子中符号B只在匹配字符“B”时跳过,从这个例子可以看出{Skip();}要写在忽略内容的后面,如果它处于某选择分支中那么它只对某分支起作用。下面我们定义一些实际中经常出现的词法定义。
INT : DIGIT+;
DIGIT : ‘0’ .. ‘9’;
INT 定义了整型数,整型数是由1个或多0到9的数字组成的。下面我们来定义浮点数,浮点数的整数部分至少要有一位数字,小数部分是可有可无的,如要有小数部分则至少要有1位小数位。
FLOAT : DIGIT+ (‘.’ DIGIT+)?;
下面是一个对于java语言中注释的定义。
COMMENT : '/*' .* '*/' {skip();} ;
LINE_COMMENT :'//' ~ ('\n' | '\r') * '\r'? '\n' {skip();} ;
/* */ 和 // 代表的注释部分被忽略掉,下面我们给出完全的示例并运行它。
grammar T;
options {
language=CSharp;
output=AST;
}
a : INT;
INT : DIGIT+;
DIGIT : ‘0’ .. ‘9’;
COMMENT : '/*' .* '*/' {Skip();} ;
LINE_COMMENT :'//' ~ ('\n' | '\r') * '\r'? '\n' {Skip();} ;
WS : ( ' ' | '\t'| '\n' | '\r' ) + {Skip();} ;
文法中的COMMENT、LINE_COMMENT和WS规则只是为了滤掉相应内容,没有必要与语法规则关联,这样它们也可以正确的工作。COMMENT符号使用了“.”符号来匹配一切字符直到匹配“/”字符为止。LINE_COMMENT从“//”字符开始匹配除了“\r\n”以外的所有字符直到匹配“\r\n”为止。其中有可以没有回车符只有换行符所以“\r”是可选项。