antlr-基础-词法规则

Lexer Rules

词法语法由词法规则组成,词法模型允许分割一个单一语法为多个子词法,lexer只能返回匹配

Lexer rule需要以大写字母命名,以区分parser rule

/** Optional document comment */
TokenName : alternative1 | ... | alternativeN ;

可以定义仅用于辅助识别tokens的Lexer rule,但是不是tokens;

fragment
HelperTokenRule : alternative1 | ... | alternativeN ;

这些碎片规则不会暴露给parser
例子中DIGIT是一个通用的碎片规则

INT : DIGIT+ ; // references the DIGIT helper rule
fragment DIGIT : [0-9] ; // not a token by itself

Lexical Modes
Modes可以用context组织lexical rules,多个子lexer具有同一个context,lexer 只能返回
修改模式

rules in default mode
...
mode MODE1;
rules in MODE1
...
mode MODEN;
rules in MODEN
...

Lexer Rule Elements
Syntax Description
T
’literal’
[char set]
’x’..’y’
T
.
{«action»}
{«p»}?
~x

Recursive Lexer Rules
lexer rule可以递归

lexer grammar Recur;
ACTION : '{' ( ACTION | ~[{}] )* '}' ;
WS : [ \r\t\n]+ -> skip ;

Redundant String Literals

Lexer Rule Actions

Lexer Commands

lexer command包含->操作符,后跟多个命令名

TokenName : «alternative» -> command-name
TokenName : «alternative» -> command-name («identifier or integer»)

命令名如下

  • skip
  • more
  • popMode
  • mode( x )
  • pushMode( x )
  • type( x )
  • channel( x )

skip
获取另一个token,并且输出当前token

ID : [a-zA-Z]+ ; // match identifiers
INT : [0-9]+ ; // match integers
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS : [ \t]+ -> skip ; // toss out whitespace

mode(), pushMode(), popMode, and more
mode转换模式栈
more强制lexer获取另一个token,并不输出现在的内容

// Default "mode": Everything OUTSIDE of a tag
COMMENT : '<!--' .*? '-->' ;
CDATA   : '<![CDATA[' .*? ']]>' ;OPEN : '<' -> pushMode(INSIDE) ;
 ...
XMLDeclOpen : '<?xml' S -> pushMode(INSIDE) ;
SPECIAL_OPEN: '<?' Name -> more, pushMode(PROC_INSTR) ;
// ----------------- Everything INSIDE of a tag ---------------------
mode INSIDE;
CLOSE        : '>' -> popMode ;
SPECIAL_CLOSE: '?>' -> popMode ; // close <?xml...?>
SLASH_CLOSE  : '/>' -> popMode ;

pop出底层的

lexer grammar Strings;
LQUOTE : '"' -> more, mode(STR) ;
WS : [ \r\t\n]+ -> skip ;
mode STR;
STRING : '"' -> mode(DEFAULT_MODE) ; // token we want parser to see
TEXT : . -> more ; // collect more text for string

type()
多个type只有最右边的有效

lexer grammar SetType;
tokens { STRING }
DOUBLE : '"' .*? '"'   -> type(STRING) ;
SINGLE : '\'' .*? '\'' -> type(STRING) ;
WS     : [ \r\t\n]+    -> skip ;

channel()

BLOCK_COMMENT
    : '/*' .*? '*/' -> channel(HIDDEN)
    ;
LINE_COMMENT
    : '//' ~[\r\n]* -> channel(HIDDEN)
    ;
... 
// ----------
// Whitespace
//
// Characters and character constructs that are of no import
// to the parser and are used to make the grammar easier to read
// for humans.
//
WS : [ \t\r\n\f]+ -> channel(HIDDEN) ;

可以定义channel名字像枚举一样,在lexer rules之前如下构造

channels { WSCHANNEL, MYHIDDEN }
posted @ 2016-11-29 20:22  zhangshihai1232  阅读(1298)  评论(0)    收藏  举报