<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Lexer-rules.md</id>
	<title>Lexer-rules.md - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Lexer-rules.md"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Lexer-rules.md&amp;action=history"/>
	<updated>2026-04-06T17:52:38Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Lexer-rules.md&amp;diff=687&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“{{MARKDOWN}} # Lexer Rules  一个lexer grammar由lexer rules组成，可以选择分为多个modes。 Lexical modes允许我们将单个lexer grammar拆分为多个sublexers。 lexer只能返回与当前mode中的规则匹配的Token。  Lexer规则指定Token定义，并且或多或少遵循parser rules的语法，只是lexer rules不能有参数、返回值或局部变量。 Lexer规则名称必须以大写字母开头，这将它们与parser rule名称区…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Lexer-rules.md&amp;diff=687&amp;oldid=prev"/>
		<updated>2022-02-25T05:26:14Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“{{MARKDOWN}} # Lexer Rules  一个lexer grammar由lexer rules组成，可以选择分为多个modes。 Lexical modes允许我们将单个lexer grammar拆分为多个sublexers。 lexer只能返回与当前mode中的规则匹配的Token。  Lexer规则指定Token定义，并且或多或少遵循parser rules的语法，只是lexer rules不能有参数、返回值或局部变量。 Lexer规则名称必须以大写字母开头，这将它们与parser rule名称区…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{MARKDOWN}}&lt;br /&gt;
# Lexer Rules&lt;br /&gt;
&lt;br /&gt;
一个lexer grammar由lexer rules组成，可以选择分为多个modes。 Lexical modes允许我们将单个lexer grammar拆分为多个sublexers。 lexer只能返回与当前mode中的规则匹配的Token。&lt;br /&gt;
&lt;br /&gt;
Lexer规则指定Token定义，并且或多或少遵循parser rules的语法，只是lexer rules不能有参数、返回值或局部变量。 Lexer规则名称必须以大写字母开头，这将它们与parser rule名称区分开来:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
/** Optional document comment */&lt;br /&gt;
TokenName : alternative1 | ... | alternativeN ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
您还可以定义一些特殊的规则，这些规则不是Token，而是有助于识别Token。 这些fragment rule不会产生parser可见的Token：&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
fragment&lt;br /&gt;
HelperTokenRule : alternative1 | ... | alternativeN ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
例如，`DIGIT` 是一个非常常见的片段规则:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
INT : DIGIT+ ; // 引用DIGIT辅助规则&lt;br /&gt;
fragment DIGIT : [0-9] ; //本身不是Token&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Lexical Modes&lt;br /&gt;
&lt;br /&gt;
Modes允许您按上下文对lexical rules进行分组，例如XML标记的内部和外部。 这就像有多个sublexers，每个上下文对应一个sublexers。 lexer只能返回通过在当前Mode中输入规则匹配的Tokens。 Lexers从所谓的默认Mode开始。 除非指定Mode命令，否则所有规则都将被视为处于默认Mode。 combined grammars中不允许使用Mode，只能在lexer grammars中使用。 (请参阅 grammar `XMLLexer` [Tokenizing XML](http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference)。)&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
rules in default mode&lt;br /&gt;
...&lt;br /&gt;
mode MODE1;&lt;br /&gt;
rules in MODE1&lt;br /&gt;
...&lt;br /&gt;
mode MODEN;&lt;br /&gt;
rules in MODEN&lt;br /&gt;
...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Lexer Rule Elements&lt;br /&gt;
&lt;br /&gt;
Lexer rules允许两种parser rules无法使用的结构： .. range运算符和用方括号括起来的字符集表示法[characters]。 不要将字符集与parser rules的参数混淆。这里[characters] 仅表示lexer中的字符集。 以下是所有lexer rule元素的摘要：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Syntax&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
在当前输入位置匹配Token T。 Token总是以大写字母开头。&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;’literal’&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
匹配该字符或字符序列。例如，“while”或“=”。&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[char set]&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;匹配字符集中指定的一个字符。 Interpret &amp;lt;tt&amp;gt;x-y&amp;lt;/tt&amp;gt; as the set of characters between range &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt;, inclusively. 以下转义字符被解释为单个特殊字符: &amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\uXXXX&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;\u{XXXXXX}&amp;lt;/tt&amp;gt;. To get &amp;lt;tt&amp;gt;]&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt; you must escape them with &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;. To get &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; you must escape it with &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt; too, except for the case when &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; is the first or last character in the set.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;You can also include all characters matching Unicode properties (general category, boolean, or enumerated including scripts and blocks) with &amp;lt;tt&amp;gt;\p{PropertyName}&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\p{EnumProperty=Value}&amp;lt;/tt&amp;gt;. (You can invert the test with &amp;lt;tt&amp;gt;\P{PropertyName}&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;\P{EnumProperty=Value}&amp;lt;/tt&amp;gt;).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;For a list of valid Unicode property names, see &amp;lt;a href=&amp;quot;http://unicode.org/reports/tr44/#Properties&amp;quot;&amp;gt;Unicode Standard Annex #44&amp;lt;/a&amp;gt;. (ANTLR also supports &amp;lt;a href=&amp;quot;http://unicode.org/reports/tr44/#General_Category_Values&amp;quot;&amp;gt;short and long Unicode general category names and values&amp;lt;/a&amp;gt; like &amp;lt;tt&amp;gt;\p{Lu}&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\p{Z}&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\p{Symbol}&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\p{Blk=Latin_1_Sup}&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;\p{Block=Latin_1_Supplement}&amp;lt;/tt&amp;gt;.)&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;As a shortcut for &amp;lt;tt&amp;gt;\p{Block=Latin_1_Supplement}&amp;lt;/tt&amp;gt;, you can refer to blocks using &amp;lt;a href=&amp;quot;http://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt&amp;quot;&amp;gt;Unicode block names&amp;lt;/a&amp;gt; prefixed with &amp;lt;tt&amp;gt;In&amp;lt;/tt&amp;gt; and with spaces changed to &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;. For example: &amp;lt;tt&amp;gt;\p{InLatin_1_Supplement}&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;\p{InYijing_Hexagram_Symbols}&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;\p{InAncient_Greek_Numbers}&amp;lt;/tt&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A few extra properties are supported:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;\p{Extended_Pictographic}&amp;lt;/tt&amp;gt; (see &amp;lt;a href=&amp;quot;http://unicode.org/reports/tr35/&amp;quot;&amp;gt;UTS #35&amp;lt;/a&amp;gt;)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;\p{EmojiPresentation=EmojiDefault}&amp;lt;/tt&amp;gt; (code points which have colorful emoji-style presentation by default but which can also be displayed text-style)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;\p{EmojiPresentation=TextDefault}&amp;lt;/tt&amp;gt; (code points which have black-and-white text-style presentation by default but which can also be displayed emoji-style)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;\p{EmojiPresentation=Text}&amp;lt;/tt&amp;gt; (code points which have only black-and-white text-style and lack a colorful emoji-style presentation)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Property names are &amp;lt;b&amp;gt;case-insensitive&amp;lt;/b&amp;gt;, and &amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt; are treated identically&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;以下是几个例子：&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WS : [ \n\u000D] -&amp;gt; skip ; // 与[\n\r]相同&lt;br /&gt;
&lt;br /&gt;
UNICODE_WS : [\p{White_Space}] -&amp;gt; skip; // 匹配所有Unicode空格&lt;br /&gt;
&lt;br /&gt;
ID : [a-zA-Z] [a-zA-Z0-9]* ; // 匹配常用identifier规范&lt;br /&gt;
&lt;br /&gt;
UNICODE_ID : [\p{Alpha}\p{General_Category=Other_Letter}] [\p{Alnum}\p{General_Category=Other_Letter}]* ; //全Unicode字母ID匹配&lt;br /&gt;
&lt;br /&gt;
EMOJI : [\u{1F4A9}\u{1F926}] ; // 注意Unicode码点&amp;gt; U FFFF&lt;br /&gt;
&lt;br /&gt;
DASHBRACK : [\-\]]+ ; // match - or ] one or more times&lt;br /&gt;
&lt;br /&gt;
DASH : [---] ; //匹配单个字符 - ，即介于 - 和 - 之间的“任意字符”（注意第一个和最后一个 - 不转义）&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;’x’..’y’&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
匹配范围x和y之间的任何单个字符(包括x和y)。例如，‘a’..‘z’。‘a’..‘z’等同于[a-z]。&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;T&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
调用lexer规则T; 通常允许递归，但不允许左递归。T可以是常规Token或fragment rule。&lt;br /&gt;
 	&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ID : LETTER (LETTER|'0'..'9')* ;&lt;br /&gt;
 	&lt;br /&gt;
fragment&lt;br /&gt;
LETTER : [a-zA-Z\u0080-\u00FF_] ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;.&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
点是匹配任何单个字符的单字符通配符。例子：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESC : '\\' . ; // match any escaped \x character&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;{«action»}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
从4.2开始，Lexer actions可以出现在任何地方，而不仅仅是出现在最外层alternative的末尾。 lexer根据规则中动作的位置在适当的输入位置执行动作。 要对具有多个alternatives的Rule执行单个操作，可以将alternatives括在括号中，然后将操作放在后面：&lt;br /&gt;
 	&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
END : ('endif'|'end') {System.out.println(&amp;quot;found an end&amp;quot;);} ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;该action符合目标语言的语法。 ANTLR将Action的内容逐字复制到生成的代码中; parser actions中没有像$x.y这样的表达式翻译。&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
仅执行最外层Token Rule内的Action。 换句话说，如果STRING调用ESC_CHAR并且ESC_CHAR具有一个Action，则当Lexer开始在STRING中匹配时，该操作不会执行。&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;{«p»}?&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
计算语义谓词«p»。 如果«p»在运行时的计算结果为false，则周围的规则将变为“不可见”(不可用)。 表达式 «p» 符合目标语言语法。 虽然语义谓词可以出现在lexer规则中的任何地方，但将它们放在规则末尾是最有效的。 有一点需要注意，语义谓词必须在lexer actions之前。 请参阅Lexer Rules中的Predicates。&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;~x&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
匹配不在x描述的集合中的任何单个字符。 Set x can be a single character literal, a range, or a subrule set like ~(’x’|’y’|’z’) or ~[xyz]. 以下是使用~的例子，匹配~[\r\n]*字符以外的任何字符的rule：&lt;br /&gt;
&amp;lt;pre&amp;gt; 	&lt;br /&gt;
COMMENT : '#' ~[\r\n]* '\r'? '\n' -&amp;gt; skip ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
就像parser rules一样，lexer rules允许括号和EBNF运算符中的subrules: `?`, `*`, `+`。 `COMMENT` rule说明了`*`和`?`运算符。 `+`的常见用法是`[0-9]+`来匹配整数。 Lexer subrules也可以在那些EBNF运算符上使用非贪婪`?`后缀。&lt;br /&gt;
&lt;br /&gt;
## Recursive Lexer Rules&lt;br /&gt;
&lt;br /&gt;
与大多数词汇语法工具不同，ANTLR的lexer rules可以是递归的。 当您想要匹配嵌套的标记(如嵌套的动作块：`{...{...}...}` 时，这非常方便。&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lexer grammar Recur;&lt;br /&gt;
 &lt;br /&gt;
ACTION : '{' ( ACTION | ~[{}] )* '}' ;&lt;br /&gt;
 &lt;br /&gt;
WS : [ \r\t\n]+ -&amp;gt; skip ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Redundant String Literals&lt;br /&gt;
&lt;br /&gt;
请注意，不要在多个lexer rules的右侧指定相同的字符串文字。 这样的文本是不明确的，可以匹配多个token types。 ANTLR使此文字对parser不可用。 跨Mode的Rule也是如此。 例如，以下lexer grammar定义了两个具有相同字符序列的标记：&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lexer grammar L;&lt;br /&gt;
AND : '&amp;amp;' ;&lt;br /&gt;
mode STR;&lt;br /&gt;
MASK : '&amp;amp;' ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
parser grammar不能引用字面上的 ’&amp;amp;’，但是它可以引用Token的名称:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
parser grammar P;&lt;br /&gt;
options { tokenVocab=L; }&lt;br /&gt;
a : '&amp;amp;' // results in a tool error: no such token&lt;br /&gt;
    AND // no problem&lt;br /&gt;
    MASK // no problem&lt;br /&gt;
  ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
下面是一个构建和测试序列：&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
$ antlr4 L.g4 # yields L.tokens file needed by tokenVocab option in P.g4&lt;br /&gt;
$ antlr4 P.g4&lt;br /&gt;
error(126): P.g4:3:4: cannot create implicit token for string literal '&amp;amp;' in non-combined grammar&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Lexer Rule Actions&lt;br /&gt;
&lt;br /&gt;
ANTLR lexer在匹配lexical rule后创建Token对象。 每个Token请求都以 `Lexer.nextToken` 开始，一旦识别出Token，它就会调用 “emit”。 `emit`从lexer的当前状态收集信息以构建Token。 访问字段`_type`、`_text`、`_channel`、`_tokenStartCharIndex`、`_tokenStartLine`、和`_tokenStartCharPositionInLine`。 您可以使用各种setter方法 (例如 `setType`) 设置它们的状态。 例如，如果`enumIsKeyword`为false，则以下规则将`enum`转换为identifier。&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
ENUM : 'enum' {if (!enumIsKeyword) setType(Identifier);} ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ANTLR在lexer actions中不执行特殊的`$x`属性转换(与v3不同)。&lt;br /&gt;
&lt;br /&gt;
lexical rule最多只能有一个动作，而不管该规则中有多少种alternatives。&lt;br /&gt;
&lt;br /&gt;
## Lexer Commands&lt;br /&gt;
&lt;br /&gt;
为了避免将语法与特定目标语言绑定，ANTLR支持lexer命令。 与arbitrary embedded actions不同，这些命令遵循特定的语法，并且仅限于几个常见命令。 Lexer命令出现在lexer规则定义的最外层alternative的末尾。 与arbitrary actions一样，每个Token规则只能有一个。 lexer命令由`-&amp;gt;`操作符和一个或多个命令名组成，这些命令名可以选择性地接受参数：&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
TokenName : «alternative» -&amp;gt; command-name&lt;br /&gt;
TokenName : «alternative» -&amp;gt; command-name («identifier or integer»)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
alternative可以有多个命令用逗号分隔。 以下是有效的命令名：&lt;br /&gt;
&lt;br /&gt;
* skip&lt;br /&gt;
* more&lt;br /&gt;
* popMode&lt;br /&gt;
* mode( x )&lt;br /&gt;
* pushMode( x )&lt;br /&gt;
* type( x )&lt;br /&gt;
* channel( x )&lt;br /&gt;
&lt;br /&gt;
有关用法，请参阅书中的源代码，示例如下所示：&lt;br /&gt;
&lt;br /&gt;
### skip&lt;br /&gt;
&lt;br /&gt;
'skip'命令告诉lexer程序获取另一个Token并丢弃当前文本。&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
ID : [a-zA-Z]+ ; //匹配identifiers&lt;br /&gt;
INT : [0-9]+ ; //匹配integers&lt;br /&gt;
NEWLINE:'\r'? '\n' ; // 将换行符返回到parser (是结束语句信号)&lt;br /&gt;
WS : [ \t]+ -&amp;gt; skip ; // 去掉空白&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### mode(), pushMode(), popMode, and more&lt;br /&gt;
&lt;br /&gt;
MODE命令改变模式堆栈，从而改变lexer的模式。 'more' 命令迫使lexer获得另一个Token，但不会丢弃当前文本。 Token类型将是匹配的“final”规则的类型（即没有“more”或“skip”命令的类型）。&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
// Default &amp;quot;mode&amp;quot;: Everything OUTSIDE of a tag&lt;br /&gt;
COMMENT : '&amp;lt;!--' .*? '--&amp;gt;' ;&lt;br /&gt;
CDATA   : '&amp;lt;![CDATA[' .*? ']]&amp;gt;' ;&lt;br /&gt;
OPEN : '&amp;lt;' -&amp;gt; pushMode(INSIDE) ;&lt;br /&gt;
 ...&lt;br /&gt;
XMLDeclOpen : '&amp;lt;?xml' S -&amp;gt; pushMode(INSIDE) ;&lt;br /&gt;
SPECIAL_OPEN: '&amp;lt;?' Name -&amp;gt; more, pushMode(PROC_INSTR) ;&lt;br /&gt;
// ----------------- Everything INSIDE of a tag ---------------------&lt;br /&gt;
mode INSIDE;&lt;br /&gt;
CLOSE        : '&amp;gt;' -&amp;gt; popMode ;&lt;br /&gt;
SPECIAL_CLOSE: '?&amp;gt;' -&amp;gt; popMode ; // close &amp;lt;?xml...?&amp;gt;&lt;br /&gt;
SLASH_CLOSE  : '/&amp;gt;' -&amp;gt; popMode ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
另请查看：&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lexer grammar Strings;&lt;br /&gt;
LQUOTE : '&amp;quot;' -&amp;gt; more, mode(STR) ;&lt;br /&gt;
WS : [ \r\t\n]+ -&amp;gt; skip ;&lt;br /&gt;
mode STR;&lt;br /&gt;
STRING : '&amp;quot;' -&amp;gt; mode(DEFAULT_MODE) ; // token we want parser to see&lt;br /&gt;
TEXT : . -&amp;gt; more ; // collect more text for string&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
弹出Mode堆栈的底层将导致异常。 使用`mode`切换模式会更改当前堆栈顶部。  多个`more`与只有一个`more`是一样的，位置并不重要。&lt;br /&gt;
&lt;br /&gt;
### type()&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lexer grammar SetType;&lt;br /&gt;
tokens { STRING }&lt;br /&gt;
DOUBLE : '&amp;quot;' .*? '&amp;quot;'   -&amp;gt; type(STRING) ;&lt;br /&gt;
SINGLE : '\'' .*? '\'' -&amp;gt; type(STRING) ;&lt;br /&gt;
WS     : [ \r\t\n]+    -&amp;gt; skip ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
对于多个 'type()'命令，只有最右边才有效果。&lt;br /&gt;
&lt;br /&gt;
### channel()&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
BLOCK_COMMENT&lt;br /&gt;
	: '/*' .*? '*/' -&amp;gt; channel(HIDDEN)&lt;br /&gt;
	;&lt;br /&gt;
LINE_COMMENT&lt;br /&gt;
	: '//' ~[\r\n]* -&amp;gt; channel(HIDDEN)&lt;br /&gt;
	;&lt;br /&gt;
... &lt;br /&gt;
// ----------&lt;br /&gt;
// Whitespace&lt;br /&gt;
//&lt;br /&gt;
// Characters and character constructs that are of no import&lt;br /&gt;
// to the parser and are used to make the grammar easier to read&lt;br /&gt;
// for humans.&lt;br /&gt;
//&lt;br /&gt;
WS : [ \t\r\n\f]+ -&amp;gt; channel(HIDDEN) ;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
从4.5开始，您还可以像enumerations一样，使用lexer rules之上的以下构造定义通道名称：&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
channels { WSCHANNEL, MYHIDDEN }&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>