而不是使用解析整个 Java 源文件的解析器,或者自己编写一些只解析您感兴趣的部分的东西,您可以使用一些 3rd 方工具,如 ANTLR。
ANTLR 能够只定义那些你感兴趣的标记(当然还有那些可能会弄乱你的标记流的标记,比如多行注释和字符串和字符文字)。因此,您只需要定义一个能够正确处理这些标记的词法分析器(tokenizer 的另一个词)。
这称为语法。在 ANTLR 中,这样的语法可能如下所示:
lexer grammar FuzzyJavaLexer;
options{filter=true;}
SingleLineComment
: '//' ~( '\r' | '\n' )*
;
MultiLineComment
: '/*' .* '*/'
;
StringLiteral
: '"' ( '\\' . | ~( '"' | '\\' ) )* '"'
;
CharLiteral
: '\'' ( '\\' . | ~( '\'' | '\\' ) )* '\''
;
将以上内容保存在一个名为FuzzyJavaLexer.g
. 现在在此处下载 ANTLR 3.2并将其保存在与您的文件相同的文件夹中FuzzyJavaLexer.g
。
执行以下命令:
java -cp antlr-3.2.jar org.antlr.Tool FuzzyJavaLexer.g
这将创建一个FuzzyJavaLexer.java
源类。
当然,您需要测试词法分析器,您可以通过创建一个名为FuzzyJavaLexerTest.java
并在其中复制以下代码的文件来完成:
import org.antlr.runtime.*;
public class FuzzyJavaLexerTest {
public static void main(String[] args) throws Exception {
String source =
"class Test { \n"+
" String s = \" ... \\\" // no comment \"; \n"+
" /* \n"+
" * also no comment: // foo \n"+
" */ \n"+
" char quote = '\"'; \n"+
" // yes, a comment, finally!!! \n"+
" int i = 0; // another comment \n"+
"} \n";
System.out.println("===== source =====");
System.out.println(source);
System.out.println("==================");
ANTLRStringStream in = new ANTLRStringStream(source);
FuzzyJavaLexer lexer = new FuzzyJavaLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
for(Object obj : tokens.getTokens()) {
Token token = (Token)obj;
if(token.getType() == FuzzyJavaLexer.SingleLineComment) {
System.out.println("Found a SingleLineComment on line "+token.getLine()+
", starting at column "+token.getCharPositionInLine()+
", text: "+token.getText());
}
}
}
}
接下来,通过执行以下操作编译您的FuzzyJavaLexer.java
和FuzzyJavaLexerTest.java
:
javac -cp .:antlr-3.2.jar *.java
最后执行FuzzyJavaLexerTest.class
文件:
// *nix/MacOS
java -cp .:antlr-3.2.jar FuzzyJavaLexerTest
或者:
// Windows
java -cp .;antlr-3.2.jar FuzzyJavaLexerTest
之后,您将看到以下内容打印到您的控制台:
===== source =====
class Test {
String s = " ... \" // no comment ";
/*
* also no comment: // foo
*/
char quote = '"';
// yes, a comment, finally!!!
int i = 0; // another comment
}
==================
Found a SingleLineComment on line 7, starting at column 2, text: // yes, a comment, finally!!!
Found a SingleLineComment on line 8, starting at column 13, text: // another comment
很容易,嗯?:)