【背景】
折腾antlr期间,注意到:
很多.g语法文件,顶部有部分内容是:
@lexer::header { xxx }
或:
@parser::header { xxx }
或:
header { xxx }
现在,基本明白其含义了。
去总结一下。
【antlr中的.g语法文件中的lexer和parser的header的语法和含义】
1.
@lexer::header
和
@parser::header
分别对应着Lexer和Parse
即生成的:
xxxLexer.java
和
xxxParser.java
比如我此处的:
preprocess.g
所生成的:
preprocessLexer.java
preprocessParser.java
而对应的:
无前缀的header
对应着:
你当前所写的.g文件,是Lexer还是parser,决定了对应的含义是lexer的header还是parser的header
然后在对应的生成的文件中,加上对应的内容。
把header中的内容,原封不动的拷贝到对应的生成的文件中。
2.举例:
preprocess.g
中的:
@lexer::header { import java.io.*; import java.util.*; import org.antlr.runtime.BitSet; }
则生成的:
preprocessLexer.java
中,文件的最顶端,就有了:
import java.io.*;
import java.util.*;
import org.antlr.runtime.BitSet;
作用是啥?
很明显:
当你需要:
把生成的文件,比如
preprocessLexer.java
(和对应的
preprocessParser.java
一起
)
放到其他(java项目)
中去测试你的语法是否正确时,
则很多时候,需要加上对应的,
源码中所缺少的一些内容
此时,为了避免:
每次对于生成的文件(preprocessLexer.java)
都手动加上对应的内容
import java.io.*; import java.util.*; import org.antlr.runtime.BitSet;
则可以通过在写.g的时候,就加到header中
3.
比如:
此处就是:
想要在
preprocessLexer.java
中加上:
(1)
import java.io.*; import java.util.*;
是为了后续测试代码中,用到其他一些代码,比如Java的File等内容
(2)
import org.antlr.runtime.BitSet;
是为了后续的代码中,用到了BitSet,无法编译通过
则:
之前每次都是手动在生成的preprocessLexer.java中去加上这些内容
很麻烦
现在可以:
一次性的,在
preprocess.g
中,加上对应的
import java.io.*; import java.util.*; import org.antlr.runtime.BitSet;
则可以使得:
之后生成的preprocessLexer.java
自动加上了上述对应的内容
免去麻烦地每次手动去添加了。
4.同理:
(1)想要加上,别的,比如package等内容时,也可以放到对应的header中
比如:
@lexer::header { package com.crifan.antlrv3demo; import java.io.*; import java.util.*; import org.antlr.runtime.BitSet; }
其中:
package com.crifan.antlrv3demo;
对应着:
我在Eclipse中,写测试代码时,是用到了命名空间com.crifan.antlrv3demo
当然,对应着文件组织结构也是对应的com/crifan下面有antlrv3demo.java
(2)别的语言时,也可以加上其他对应的内容
假如你是用antlr生成C#的代码
其中,如果有需要,则可以去加上对应的
using xxx;
之类的内容。
以便免去手动添加了。
【总结】
说白了,不论是lexer还是parser的header,目的都很简单:
即使把对应这部分的代码,原封不动的拷贝到,所生成的xxxLexer.java/xxxParser.java的头部。
好处是:
比如是java的代码,放在java的项目中,需要代码中加上package或者import的话,那么:
通过.g的lexer或parser加上header以便自动生成的时候,就带了对应的package或import等内容;
就省去了我们自己手动修改对应文件,手动去添加了。