技術

2.6. 残りの構文解析

LLVMによるプログラミング言語の実装チュートリアル日本語訳
第2章 万華鏡: 構文解析器とASTの実装
第6節 残りの構文解析

まだやってないのは、関数プロトタイプの処理である。
万華鏡では、関数プロトタイプは、関数本体の定義と同じように”extern”関数の定義にも使用される。
これを行うコードは、まぁ馬鹿正直で面白いところはあまりない。(式の処理について理解してたらだけど。)

/// プロトタイプ<br />
///   ::= id '(' id* ')'<br />
static PrototypeAST *ParsePrototype() {<br />
  if (CurTok != tok_identifier)<br />
    return ErrorP(&quot;Expected function name in prototype&quot;);</p>
<p>  std::string FnName = IdentifierStr;<br />
  getNextToken();</p>
<p>  if (CurTok != '(')<br />
    return ErrorP(&quot;Expected '(' in prototype&quot;);</p>
<p>  // 引数の名前のリストを読み取る。<br />
  std::vector&lt;std::string&gt; ArgNames;<br />
  while (getNextToken() == tok_identifier)<br />
    ArgNames.push_back(IdentifierStr);<br />
  if (CurTok != ')')<br />
    return ErrorP(&quot;Expected ')' in prototype&quot;);</p>
<p>  // 成功。<br />
  getNextToken();  // ')'を消費。</p>
<p>  return new PrototypeAST(FnName, ArgNames);<br />
}

これによって、関数定義はとても簡単になる。
プロトタイプに、関数本体を実装するための式をプラスするだけでよい。

/// definition ::= 'def' prototype expression<br />
static FunctionAST *ParseDefinition() {<br />
  getNextToken();  // &quot;def&quot;を消費。<br />
  PrototypeAST *Proto = ParsePrototype();<br />
  if (Proto == 0) return 0;</p>
<p>  if (ExprAST *E = ParseExpression())<br />
    return new FunctionAST(Proto, E);<br />
  return 0;<br />
}

さらに、ユーザー関数の前方宣言と同じように”sin”や”cos”などの関数の”extern”宣言をサポートする。
“extern”は、関数本体がないプロトタイプそのものである。

/// external ::= 'extern' prototype<br />
static PrototypeAST *ParseExtern() {<br />
  getNextToken();  // &quot;extern&quot;を消費。<br />
  return ParsePrototype();<br />
}

最後に、ユーザーが書いた任意のトップレベルの式をそのまま評価するようにする。
これを、無名で引数が無い関数として定義する事によって処理する。

/// toplevelexpr ::= expression<br />
static FunctionAST *ParseTopLevelExpr() {<br />
  if (ExprAST *E = ParseExpression()) {<br />
    // 無名のプロトタイプを作成する。<br />
    PrototypeAST *Proto = new PrototypeAST(&quot;&quot;, std::vector&lt;std::string&gt;());<br />
    return new FunctionAST(Proto, E);<br />
  }<br />
  return 0;<br />
}

さてこれによって、全てのパーツはそろった。
次は、これまで我々が書いてきたコードを実際に実行するために、小さなドライバを構築してみよう。

コメントを残す

メールアドレスが公開されることはありません。



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください