基本情報技術者 2016年 秋期 午後 問02
コンパイラの字句解析と構文解析に関する次の記述を読んで、設問1,2に答えよ。
コンパイラの字句解析では、原始プログラムを文字列として読み込んで、文字列中の文字の並びが字句として認識できるかどうかを解析し、その結果を字句の並びとして出力する。字句とは、原始プログラム中の名前や定数など、構文規則で規定されている文字の並びの最小単位である。構文解析では、字句解析が出力した字句を読み込みながら、字句の並びが構文規則で規定されている文法に合っているかどうかを解析し、その結果を構文木などの中間表現で出力する。
設問1:
問題文を見る 字句解析の処理について、次の記述中のに入れる正しい答えを、解答群の中から選べ。
123.や123.4e-1など、構文規則で規定されている符号なし浮動小数点定数を例として字句解析の処理を考える。
“→”は、左側の構文要素が右側で定義されることを示す。
“|”は、“又は”を意味する。
“[”と“]”で囲まれた部分は、省略可能を意味する。
〔符号なし浮動小数点定数の構文規則〕
符号なし浮動小数点定数 → 小数点定数[指数部] | 数字列 指数部
小数点定数 → [数字列].数字列 | 数字列.
指数部 → e[符号]数字列
数字列 → 数字 | 数字列 数字
符号 → + | -
数字 → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
構文規則は、状態遷移図で表現することもできる。符号なし浮動小数点定数の構文規則に対する状態遷移図を、図1に示す。字句解析では、文字の並び中の文字を読み込みながら初期状態から状態を遷移させて、文字の並びを読み終えたときの状態が最終状態ならば、その文字の並びは符号なし浮動小数点定数であると判定する。ここで、円の中の数字は状態番号を示す。初期状態の状態番号は0であり、最終状態は二重円で示している。また、文字の並びは左から右に向けて1文字ずつ処理される。

a, bに関する解答群
ア:.
イ:e
ウ:指数部
エ:数字
オ:符号
模範解答
a:ア、b:イ
解説
解答の導き方
この問題では、図1の矢印に書かれた文字を判断します。字句解析とは、文字を左から読み、名前や数値などのまとまりとして認識する処理です。状態遷移図は、読み込んだ文字に応じて、処理の状態を移す様子を表しています。
まず、aを考えます。図1では、状態0から状態2へ進む矢印の後、状態2から状態3へは「数字」で進みます。つまり、この経路では最初にaの文字を読み、その後に数字を読みます。
構文規則には、小数点定数として「[数字列].数字列」があります。小数点の前の数字列は省略できるため、数字から始めず、小数点から始まる形も認められます。その場合、最初に読むのは小数点です。したがって、aは小数点を表す「.」です。
次に、bを考えます。図1では、数字を読み続けた後の状態1から状態4へ進む矢印にbが書かれています。構文規則では、数字列の後に指数部を付けることができ、指数部は「e[符号]数字列」で始まります。よって、この矢印で読む文字は「e」です。
図1の経路を例で確認すると、次のようになります。
- 「123.」は、数字を読んで状態1に進み、小数点を読んで状態3に進みます。状態3は最終状態なので、符号なし浮動小数点定数と判定されます。
- 「123.4e-1」は、数字を読んで状態1、小数点を読んで状態3、「e」を読んで状態4、「-」を読んで状態5、最後の数字を読んで状態6に進みます。状態6も最終状態なので、符号なし浮動小数点定数と判定されます。
誤りやすいポイント
- aを「数字」と考えないようにします。状態0から数字を読む経路は、別に状態1へ用意されています。状態0から状態2へ進む経路は、小数点から始まる小数を表すためのものです。
- bを「符号」と考えないようにします。指数部では、まず「e」を読み、その後に符号を付ける場合があります。図1でも、状態4から状態5へ進む矢印が「符号」です。
- 「符号なし」は、数全体の先頭に「+」や「-」を付けないという意味です。指数部には符号を付けられるため、「123.4e-1」のような形も認められます。
FAQ
Q: 「123.」のように、小数点の後に数字がなくてもよいのですか?
A: はい。構文規則の「小数点定数 → [数字列].数字列」ではなく、もう一つの形「数字列.」に当たります。図1では、状態1から小数点を読んで状態3に進み、そのまま終了できます。
A: はい。構文規則の「小数点定数 → [数字列].数字列」ではなく、もう一つの形「数字列.」に当たります。図1では、状態1から小数点を読んで状態3に進み、そのまま終了できます。
Q: 「123.4e-1」の「-」も、bに当たりますか?
A: いいえ。bは「e」です。「-」は指数部の符号で、図1では状態4から状態5へ進むときに読みます。
A: いいえ。bは「e」です。「-」は指数部の符号で、図1では状態4から状態5へ進むときに読みます。
Q: なぜ、文字を読み終えた状態が大切なのですか?
A: 図1では、状態3と状態6が最終状態です。文字をすべて読み終えたときに最終状態にいれば、読み込んだ文字列が構文規則に合うと判定できます。
A: 図1では、状態3と状態6が最終状態です。文字をすべて読み終えたときに最終状態にいれば、読み込んだ文字列が構文規則に合うと判定できます。
関連キーワード: 字句解析、字句、状態遷移図、構文規則、浮動小数点定数
設問2:
問題文を見る 構文解析の処理について、次の記述中のに入れる正しい答えを、解答群の中から選べ。
構文規則で規定されている式を例として、構文解析の処理を考える。式の構文解析では、式を構成する演算子や名前などの字句を、式の左から右に読み込みながら、字句の並びが構文規則で規定されている文法に合っているかどうかを解析し、その結果を構文木として出力する。例えば、2項演算子op、名前v, w, xを構成要素とする式 v op w op x は、次の演算順序①、②になるように解釈され、その結果は、図2に示す2分木で表現する構文木として出力される。図2の構文木では、深さ優先でたどりながら、帰り掛けに節の演算子を評価する。
〔演算順序〕
① vとwに対して演算opを施す。
② ①の結果とxに対して演算opを施す。

式の構文規則では、式の構文を規定するだけではなく、演算子の優先順位も規定する。2項演算子op1とop2、名前v, w, x, y, zを構成要素とする式の構文規則を定義する。ここで、“演算子op1の優先順位は、演算子op2の優先順位よりも高い”とする。これを規定する場合、式の構文規則は次のとおりになる。この構文規則で受理される式の例を、例1に示す。
〔式の構文規則〕
式 → 項 | c
項 → 因子 | 項 op1 因子
因子 → 名前
名前 → v | w | x | y | z
例1: v op2 w op1 x
さらに、式の構文に括弧を追加し、“括弧を含む式では、演算の優先順位は、括弧内の演算の方が高い”とする。これを規定する場合、因子の構文規則は次のとおりになる。この構文規則で受理される式の例を、例2に示す。
〔因子の構文規則〕
因子 → 名前 | ( d )
例2: v op2 w op1 ( x op2 y ) op1 z
例2で示す式を解析したとき、出力される構文木はeとなる。
cに関する解答群
ア:式
イ:式 op2 因子
ウ:式 op2 項
エ:式 op2 名前
dに関する解答群
ア:因子
イ:項
ウ:式
エ:名前
eに関する解答群


模範解答
c:ウ、d:ウ、e:ウ
解説
解答の導き方
この問題では、演算子の優先順位と括弧の働きを、構文規則と構文木で表せるかが問われています。構文規則は、式をどのような形で組み立てられるかを示すルールです。構文木は、式の要素を木の形に並べ、どの演算を先に行うかを表したものです。
1. cには、op2を使った式の形を入れます
本文では、演算子op1の優先順位がop2より高いとされています。また、構文規則には「項 → 因子 | 項op1因子」とあります。つまり、項の中でop1を含む式を組み立てます。
op2はop1より優先順位が低いので、op2を使った式は、項より一段外側にある「式」の規則に加えます。形としては、左側に式、右側に項を置く「式op2項」です。
右側を「項」にすることで、その中にあるop1の演算をop2より先に組み立てられます。したがって、cには「式op2項」が入り、解答群ではウです。
2. dには、括弧の中に入る全体の式を入れます
因子の規則は「因子 → 名前 | ( d )」です。括弧の中には、名前だけでなく、op1やop2を含む式全体を入れられる必要があります。
「項」だけではop2を含む式を表せず、「名前」だけでは演算を含む式を表せません。よって、dには「式」が入り、解答群ではウです。
3. eの構文木は、優先順位と括弧、演算の結び付き方から決めます
例2の式は、v op2 w op1 ( x op2 y ) op1 zです。構文木では、演算子を親の節、演算の対象をその子として表します。
- 括弧内の「x op2 y」は、op2を根にして、左にx、右にyを置きます。
- op1はop2より優先順位が高いため、括弧内を除く部分では、wと括弧内の式をop1で結びます。
- さらにその結果をzとop1で結びます。規則「項 → 因子 | 項op1因子」は、op1を左から順に結び付ける形です。
- op2はop1より優先順位が低いため、最後にvと、それ以降の項をop2で結びます。したがって、構文木の根はop2になります。
この形に合うのはウです。アはop1を右側から結び付けていますが、構文規則が示す結び付き方とは異なります。イとエは根がop1になっており、op2よりop1の優先順位が高いという規則を表せていません。
なお、本文にある「帰り掛けに節の演算子を評価する」とは、子の演算を先に済ませ、その結果を使って親の演算を行うことです。そのため、構文木の根にあるop2は、子にある演算の後に評価されます。
誤りやすいポイント
- 優先順位の高い演算子を、構文木の根に置いてしまうこと
根の演算子は、子にある演算を済ませた後に評価されます。優先順位が低いop2が、op1より後に評価されるため、根になります。 - 括弧の中を「項」と考えてしまうこと
括弧内にはop2も含む式全体を置けます。そのため、因子の規則では「式」を使います。 - op1の結び付き方を逆にすること
「項 → 項op1因子」は、op1を左から順に結び付けます。構文木の形を選ぶときは、優先順位だけでなく、この結び付き方も確認します。
FAQ
Q: 演算子の優先順位は、構文規則のどこで表されていますか?
A: op1を「項」の規則で扱い、op2を「式」の規則で扱うことで表しています。op1を含む項が先に組み立てられるので、op1の優先順位が高くなります。
A: op1を「項」の規則で扱い、op2を「式」の規則で扱うことで表しています。op1を含む項が先に組み立てられるので、op1の優先順位が高くなります。
Q: 括弧の中にop2があってもよいのはなぜですか?
A: 因子の規則で括弧の中に「式」を置くからです。式はop2を含む形も取れるため、括弧内にop2を含む式を表せます。
A: 因子の規則で括弧の中に「式」を置くからです。式はop2を含む形も取れるため、括弧内にop2を含む式を表せます。
Q: 構文木では、どの演算子から評価しますか?
A: 子の節から先に評価し、親の節を後に評価します。たとえば、op2が根にあり、その子にop1の節があれば、op1を先に評価してからop2を評価します。
A: 子の節から先に評価し、親の節を後に評価します。たとえば、op2が根にあり、その子にop1の節があれば、op1を先に評価してからop2を評価します。
関連キーワード: 構文解析、構文規則、構文木、演算子の優先順位、演算子の結合規則



