環境:Windows 10
STEP 1: 下載 JFlex 文件,我選擇的是 jflex-1.7.0.zip。下載完成后解壓到想安裝的位置。
文件結構如下(假設解壓目錄為 C:\):
C:\jflex-1.7.0\ +--bin\ (start scripts) +--doc\ (FAQ and manual) +--examples\ +--byaccj\ (calculator example for BYacc/J) +--cup-maven\ (calculator example for cup and maven) +--interpreter\ (interpreter example for cup) +--java\ (Java lexer specification) +--simple-maven\ (example scanner built with maven) +--standalone-maven\ (a simple standalone scanner, built with maven) +--zero-reader\ (Readers that return 0 characters) +--lib\ (precompiled classes) +--src\ +--main\ +--config\ (PMD source analyzer configuration) +--cup\ (JFlex parser spec) +--java\ +--jflex\ (source code of JFlex) +--anttask\ (source code of JFlex Ant Task) +--gui\ (source code of JFlex UI classes) +--unicode\ (source code for Unicode properties) +--jflex\ (JFlex scanner spec) +--resources\ (messages and default skeleton file) +--test\ (unit tests)
STEP 2:修改 jflex.bat
1)進入 jflex解壓目錄/jflex-1.7.0/bin,打開jflex.bat
2)修改兩個環境變量:
JAVA_HOME :Java JDK 的安裝路徑
JFLEX_HOME :JFlex 的安裝路徑
**由於直接打開 jflex.bat 會閃退,我是在 gitbash 中用 nano 編輯的。
STEP 3:將 jflex解壓目錄/jflex-1.7.0/bin 加入系統環境變量 Path
STEP 4:運行 jflex 檢查是否配置成功(依舊用的是 gitbash)
文檔說,命令格式為jflex <options> <inputfiles> (如果不在命令行輸入文件名,jflex會有一個彈出一個輸入文件名的窗口)
這里是所有選項的說明:
-d <directory> 在指定目錄<directory>生成文件
--encoding <name> 使用<name>格式的編碼讀入此法規范並書寫 java 文件
--skel <file> 使用外部骨架<file>
--nomin 在掃描生成時跳過 DFA 最小化的步驟
--jflex 執行 JLex 解釋規范
--dot 為 NFA, DFA, minimised DFA 生成 Graphviz dot 文件
--dump 顯示 NFA, initial DFA, minimised DFA 的轉換表
--legacydot 元字符 dot (.
) 匹配 [^\n]
而非 [^\n\r\u000B\u000C\u0085\u2028\u2029]
--verbose or -v 顯示生成進度消息(默認開啟)
--quiet or -q 只顯示錯誤信息
--warn-unused 警告未使用的宏(在 verbose 模式中默認開啟,quiet 模式中默認關閉)
--no-warn-unused 不警告未使用的宏
--time 顯示代碼生成進度的時間信息
--version 打印版本信息
--info 打印系統與 jdk 信息
--unicodever <ver> 打印所有 Unicode 版本<ver>支持的屬性
--help or -h 打印幫助信息
按照習俗,跑跑看 jflex --version:
GOOD JOB!
接下來運行一個手冊提供的簡單例子
這段 lexical specitication 描述了 Java 語言的部分規則,從手冊復制下來的時候每行會多出四個空格,要手動去掉。保存在 test.flex 文件中。
%%
%class Lexer
%unicode
%cup
%line
%column
%{
StringBuffer string = new StringBuffer();
private Symbol symbol(int type) {
return new Symbol(type, yyline, yycolumn);
}
private Symbol symbol(int type, Object value) {
return new Symbol(type, yyline, yycolumn, value);
}
%}
LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace = {LineTerminator} | [ \t\f]
/* comments */
Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}
TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/"
// Comment can be the last line of the file, without line terminator.
EndOfLineComment = "//" {InputCharacter}* {LineTerminator}?
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent = ( [^*] | \*+ [^/*] )*
Identifier = [:jletter:] [:jletterdigit:]*
DecIntegerLiteral = 0 | [1-9][0-9]*
%state STRING
%%
/* keywords */
<YYINITIAL> "abstract" { return symbol(sym.ABSTRACT); }
<YYINITIAL> "boolean" { return symbol(sym.BOOLEAN); }
<YYINITIAL> "break" { return symbol(sym.BREAK); }
<YYINITIAL> {
/* identifiers */
{Identifier} { return symbol(sym.IDENTIFIER); }
/* literals */
{DecIntegerLiteral} { return symbol(sym.INTEGER_LITERAL); }
\" { string.setLength(0); yybegin(STRING); }
/* operators */
"=" { return symbol(sym.EQ); }
"==" { return symbol(sym.EQEQ); }
"+" { return symbol(sym.PLUS); }
/* comments */
{Comment} { /* ignore */ }
/* whitespace */
{WhiteSpace} { /* ignore */ }
}
<STRING> {
\" { yybegin(YYINITIAL);
return symbol(sym.STRING_LITERAL,
string.toString()); }
[^\n\r\"\\]+ { string.append( yytext() ); }
\\t { string.append('\t'); }
\\n { string.append('\n'); }
\\r { string.append('\r'); }
\\\" { string.append('\"'); }
\\ { string.append('\\'); }
}
/* error fallback */
[^] { throw new Error("Illegal character <"+
yytext()+">"); }
執行命令 jflex ,會彈出如下窗口,選擇文件和目錄,點擊 Generate 即可生成 scanner,是一個叫 Lexer.java 的文件。
參考:http://www.jflex.de/manual.html#content(官方文檔)