Skip to main content

はじめの一歩

まずは、数字のみをパースし、評価する言語処理系を見ながら、ツールの使い方を学びましょう。

playgroundのURL: https://pl-workshop.github.io/pl-workshop/ を開いて下さい。

以下リロードをすると書いたプログラムが消えてしまいます。気をつけて下さい。

構文解析

今回は、構文解析にPEG.jsというライブラリを用います。PEG(Parsing Expression Grammer)によって定義された文法からパーサーを作るライブラリです。playgroundを開くと、文法定義部に、次のようなコードが書かれています。

start = Expression
Expression = Factor
Factor = num: Integer {
return {tag: "Number", value: num}
}

まず、startと書いてある場所から文法定義が始まっています。今回の場合は、Expressionがトップの定義となっています。そして、Expressionは、Factorであると定義されています。

そして、Factorの定義には、num: Integerという表記があります。これは、「FactorとはIntegerであり、Integerの結果はnumに代入される」ということを表しています。Integerは、数字が一個以上並んでいる部分にマッチして、その数字を返すように予め定義されている文法です。

Integerの定義
Integer = _ [0-9]+ { 
return parseInt(text(), 10);
}

_は0個以上の空白、改行を消費する文法で、次のような定義になっています。

_ = [ \\t\\n\\r]*
そして、その後の中括弧で囲まれた部分には、JavaScriptのコードを書くことができ、Factorがどのような値を返すかを定義することが出来ます。中括弧内では、先程Integerの結果が代入されたnumを使うことが出来ます。

return文で返した値が結果となります。今回は、{tag: "Number", value: num}を返しています。このように、ASTをJavaScriptのオブジェクトを使って表現していきます。

それでは、実際に構文解析してみましょう。入力に、好きな正の数字を入れてください。そして、Parse!ボタンを押してみましょう。

すると、右側にあるAST Viewerに、ASTを図示した結果が表示されます。Rootは木の根元を表しています。その下のNumberは、{tag: "Number", value: num}のtagが表示されたものです。そして、valueの下に、入力した数字が表示されているはずです。

評価

評価部に書いてあるコードを見てみましょう。

const eval = (ast) => {
switch (ast.tag) {
case "Number": return ast.value
}
}

astを受け取るeval関数が定義されています。eval関数の中では、ast.tagの値によってswitchされています。今回は、"Number"の分岐先では、ast.valueを返しています。

このeval関数が、評価時のエントリーポイントになるようにこのツールは作られています。

それでは、Eval!ボタンを押してみましょう。評価結果に、入力した数字が表示されているはずです。