Quex

Quex 是一個詞法分析器的產生器，它能創建C或者C++語言的詞法分析器。Quex的一個顯著特徵是它能支持基於Unicode字串的輸入，而且創建的分析器代碼是直接編碼格式的（而非查表格式），具有較高的分詞速度。另外，Quex在描述詞法分析的語法上採用了類似於C++的繼承語法和分模塊語法，這使得語法的復用非常簡單，語法結構更為清晰。

## 特性

### 直接編碼詞法分析器

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的語法。

```cpp
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函數進行相應的處理。

對於更複雜的處理，可使用花括號包含所需要的處理語句，如下所示：

```cpp
    ...
    {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.

## 基本資料

- 日語原文：quex
- 開發者：Dr.-Ing. Frank-Rene Schäfer
- 軟體版本週期：0.59.7
- 作業系統：Cross-platform
- 類型：Lexical analyzer generator
- 許可協議：LGPL
- 網站： quex.sourceforge.net