6
2

More than 5 years have passed since last update.

Node.jsでつくるNode.js - Step 1:ソースのパース

Last updated at Posted at 2018-06-01

はじめに

「RubyでつくるRuby ゼロから学びなおすプログラミング言語入門」(ラムダノート, Amazon) という本を読んで、簡易的なプログラミング言語を作りたい熱が出てきました。そんなおりに PythonでつくるPythonという記事を読み、自分でもNode.jsでミニNode.js作りにチャンレンジするとにしました。
どこまで続くかわかりませんが、最後はブートストラップまで行くことを目指して始めます。

Step 1 - ソースコードのパース

「RubyでつくるRuby」の実装は2つの部分に分かれています。

  • ソースコードを解析するところ (parse)
  • ソースコードを実行するところ (evaluate)

parseの部分はあらかじめ作者が用意している minruby.rb が担当してくれていて、読者は実行のevaluateだけ作る構成になっています。

PythonでつくるPythonでもparseはastモジュールで行なっていました。

Node.jsでもAST(抽象構文木)という名前は耳にします。調べて見ると、次の2つの系列があるようです。(JavaScript ASTを始める最初の一歩より)

  • Esprima
  • Acorn

特にこだわりもないので、Esprimaを使ってみます。

$ npm install esprima

初めての AST

こんなコードを書いて、パースした結果のASTがどうなっているか見ました。


const esprima = require("esprima");

function parseSrc(src) {
  const ast = esprima.parseScript(src);
  return ast;
}

function printObj(obj) {
  console.dir(obj, {depth: 10});
}

// --------

const ast1 = parseSrc('1');
printObj(ast1);

'1' をパースした結果がこちらです。

Script {
  type: 'Program',
  body:
   [ ExpressionStatement {
       type: 'ExpressionStatement',
       expression: Literal { type: 'Literal', value: 1, raw: '1' } } ],
  sourceType: 'script' }

何やらそれっぽいです。
もう一丁、'2+3' をパースした結果もやってみます。

Script {
  type: 'Program',
  body:
   [ ExpressionStatement {
       type: 'ExpressionStatement',
       expression:
        BinaryExpression {
          type: 'BinaryExpression',
          operator: '+',
          left: Literal { type: 'Literal', value: 2, raw: '2' },
          right: Literal { type: 'Literal', value: 3, raw: '3' } } } ],
  sourceType: 'script' }

想像していたより複雑になってますが、ソースの構造が反映されているようです。今後これを出発点に進めていきます。

ASTが使われているところ

AST初心者なので、実際どんなところで使われているのか調べてみました。

ASTを使いこなせば、自分でAltJSを作るのも不可能ではなさそうです。

次回

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2