プログラミングユーティリティ

C++ 符号化シンボル

この節の内容は、第 2 章「字句解析」「C++ 符号化シンボル」と全く同じ内容です。lexyacc に置き換えて読んでください。

字句連結

一部の字句の判断はコンテキストに依存します。たとえば、字句アナライザは通常は空白文字を削除しますが、引用符で囲まれた文字列の空白文字は削除しません。また、名前は宣言の中のシンボルテーブルに入力できますが、式の中のシンボルテーブルには入力できません。これらの状況に対処する方法の 1 つは、字句アナライザによって検査され、アクションによって設定される広域フラグを作成することです。以下にその例を示します。

%{ 
        int dflag; 
%} 
...  その他の宣言 ...  
%% 
prog     : decls stats 
         ; 
decls    :      /* 空 */ 
         { 
             dflag = 1; 
         } 
         | decls declaration 
         ; 
stats    :     /* 空 */
         { 
             dflag = 0; 
         } 
         | stats statement 
         ; 

.  .  .  その他の規則 .  .  .

この例では、0 個以上の宣言とそれに続く 0 個以上の文で構成されるプログラムが指定されています。文を読み取ると dflag は 0 になり、宣言を読み取ると dflag は 1 になります。ただし、最初の文の最初のトークンは除きます。

パーサーは、宣言セクションが終了して文が始まったことを認識する前に、このトークンを読み取る必要があります。多くの場合、この 1 つのトークン例外は、字句の検査には影響しません。この考え方は、難しい構造を表現する場合の手がかりになります。

予約語

一部のプログラミング言語では、通常はラベル名や変数名として予約されている if などのワードを使用できます。これらのプログラミング言語では、そのような使い方をしても本来の意味で使用されている名前とは衝突しません。しかし、これを yacc で実現するのは非常に困難です。

if のあるインスタンスがキーワードであるか変数であるかを伝える情報を字句アナライザに渡すのは容易ではありません。前節の情報を読むと、「字句連結」がここで役に立つことがわかります。