Quex
Quex 是一個詞法分析器的產生器,它能創建C或者C++語言的詞法分析器。Quex的一個顯著特徵是它能支持基於Unicode字符串的輸入,而且創建的分析器代碼是直接編碼格式的(而非查表格式),具有較高的分詞速度。另外,Quex在描述詞法分析的語法上採用了類似於C++的繼承語法和分模塊語法,這使得語法的復用非常簡單,語法結構更為清晰。
開發者 | Dr.-Ing. Frank-Rene Schäfer |
---|---|
當前版本 | 0.59.7(2011年8月14日 | )
作業系統 | Cross-platform |
類型 | Lexical analyzer generator |
許可協議 | LGPL |
網站 | quex.sourceforge.net |
特性
編輯直接編碼詞法分析器
編輯Quex使用傳統的湯普森創造法,從從正則表達式首先創建不確定性有限狀態機,然後通過壓縮和歸併轉換為確定性有限狀態機,通過Hopcroft優化算法,使得確定性有限狀態機的狀態個數達到最小。通過這些機制,使得構建詞法分析器的計算時間可以大大減少。相比其他詞法分析器生成器只能處理[ASCII]字符串的情況,Quex還可以支持Unicode字符集,並可以產生合理的運算時間的詞法分析器。 相比基於查表結構的詞法分析器,Quex產生的直接編碼方式的代碼具有更高的運算速度,而且直接編碼方式的代碼更接近於人類手工書寫的詞法分析器代碼,因此比查表結構的代碼具有良好的可讀性。
支持Unicode字符輸入
編輯Quex可以處理包含完整的Unicode代碼點範圍(0至10FFFFh)的字符輸入,同時Quex的詞法語法提供了支持Unicode的正則表達式格式。例如,與二進制屬性XID_Start的Unicode代碼點可以用表達式指定的\P{XID_Start}
或\P{XIDS}
來描述。Quex還可以生成代碼來調用iconv庫或ICU的字符格式轉換程序。Quex遵循Unicode Consortium提出的Unicode標準,若Unicode標準更新,則只需要將新版本的標準文件複製到到Quex相應的目錄即可完成Quex對Unicode的支持更新。
詞法分析模式
編輯和傳統的詞法分析器(如LEX和Flex),Quex支持詞法分析器中存在多個詞法分析子模塊(子模式)。除了傳統的正則表達式的模式匹配外,Quex還可以指定事件動作:例如代碼執行期間進入或退出一個模塊或發現任何模式匹配時。Quex這種模塊設計可以通過繼承方式,讓派生和繼承模塊很容易共享基類模塊的匹配模式和事件操作。
先進的緩衝處理
編輯Quex提供了先進的數據緩衝和重新裝載,保證了運行時的高效和靈活。Quex以插件的方式提供字符轉換的用戶接口,允許用戶使用自定義的字符集轉換程序。當需要新的緩衝區填充的時候,轉換程序被激活。默認情況下Quex使用的是iconv字符轉換庫,能夠提供多種字符編碼集之間的轉換。
範例
編輯can be translated into Quex source code as follows:
Quex使用的字符串匹配語法和經典lex和FLEX的詞法生成器工具採用的正則表達式語法類似。Flex中的例子程序可以很容易的轉換為Quex的語法。
header {
#include <cstdlib> // C++ version of 'stdlib.h'
}
define {
digit [0-9]
letter [a-zA-Z]
}
mode X :
<skip: [ \t\n\r]>
{
"+" => QUEX_TKN_PLUS;
"-" => QUEX_TKN_MINUS;
"*" => QUEX_TKN_TIMES;
"/" => QUEX_TKN_SLASH;
"(" => QUEX_TKN_LPAREN;
")" => QUEX_TKN_RPAREN;
";" => QUEX_TKN_SEMICOLON;
"," => QUEX_TKN_COMMA;
"." => QUEX_TKN_PERIOD;
":=" => QUEX_TKN_BECOMES;
"=" => QUEX_TKN_EQL;
"<>" => QUEX_TKN_NEQ;
"<" => QUEX_TKN_LSS;
">" => QUEX_TKN_GTR;
"<=" => QUEX_TKN_LEQ;
">=" => QUEX_TKN_GEQ;
"begin" => QUEX_TKN_BEGINSYM;
"call" => QUEX_TKN_CALLSYM;
"const" => QUEX_TKN_CONSTSYM;
"do" => QUEX_TKN_DOSYM;
"end" => QUEX_TKN_ENDSYM;
"if" => QUEX_TKN_IFSYM;
"odd" => QUEX_TKN_ODDSYM;
"procedure" => QUEX_TKN_PROCSYM;
"then" => QUEX_TKN_THENSYM;
"var" => QUEX_TKN_VARSYM;
"while" => QUEX_TKN_WHILESYM;
{letter}({letter}|{digit})* => QUEX_TKN_IDENT(strdup(Lexeme));
{digit}+ => QUEX_TKN_NUMBER(atoi(Lexeme));
. => QUEX_TKN_UNKNOWN(Lexeme);
}
通過使用符號「=>」操作符,可以將特定的匹配字符串和對應的詞法的Token的ID進行關聯。尖括號中的語法表示詞法分析器將跳過由空格和tab等組成的字符,圓括號內表示字符串匹配後,可調用C函數進行相應的處理。
對於更複雜的處理,可使用花括號包含所需要的處理語句,如下所示:
...
{digit}+ {
if( is_prime_number(Lexeme) ) ++prime_number_counter;
if( is_fibonacci_number(Lexeme) ) ++fibonacci_number_counter;
self.send(QUEX_TKN_NUMBER(atoi(Lexeme)));
}
...
以上的代碼,可以被用來統計處理字符串中的數值的個數。
另外可查閱
編輯- Lexical analysis
- 關於托馬斯構建法和Hopcroft優化方法,可查閱書籍例如 Compilers: Principles, Techniques, and Tools.