【acorn.jsとVanilla JS】JavaScriptでキーワード(予約語)だけを出力する方法

自分でコードをパース(読み取り)してJavaScriptのメソッドや予約語が使われているか知りたいときに下記のコードを使う事ができるので紹介します。

ライブラリを使わずに予約語を出力する

JavaScriptのコードをパースしてキーワードを配列に出力する際に外部のライブラリを使用せずに行いたい場合は、以下のようなアプローチを取ることができます。

下記はファンクションベースで書いた場合です。

// JavaScriptのコード
const code = 'function greet() { console.log("Hello, world!"); }';

// キーワードを格納する配列
const keywords = [];

// JavaScriptの予約語(キーワード)のリスト
const reservedWords = [
  'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete',
  'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if',
  'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package',
  'private', 'protected', 'public', 'return', 'super', 'switch', 'static', 'this', 'throw',
  'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'
];

// コードをスペースと特定の記号で分割
const tokens = code.split(/[\s\(\){};,]/);

// 分割したトークンをチェックしてキーワードを抽出
tokens.forEach(token => {
  if (reservedWords.includes(token)) {
    keywords.push(token);
  }
});

// 結果を出力
console.log(keywords);

上記のコードでは、予約語(キーワード)のリストを用意し、与えられたコードをスペースと特定の記号((){};,)で分割します。分割されたトークンをループして、予約語のリストに含まれるかどうかをチェックし、キーワードとして抽出します。

同じことをクラスベースで書いた場合はこのようになります。

class KeywordExtractor {
  constructor(code) {
    this.code = code;
    this.keywords = [];
    this.reservedWords = [
      'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete',
      'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if',
      'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package',
      'private', 'protected', 'public', 'return', 'super', 'switch', 'static', 'this', 'throw',
      'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'
    ];
  }

  extractKeywords() {
    const tokens = this.code.split(/[\s\(\){};,]/);

    tokens.forEach(token => {
      if (this.reservedWords.includes(token)) {
        this.keywords.push(token);
      }
    });

    return this.keywords;
  }
}

// JavaScriptのコード
const code = 'function greet() { console.log("Hello, world!"); }';

// インスタンス化してキーワードを抽出
const extractor = new KeywordExtractor(code);
const keywords = extractor.extractKeywords();

// 結果を出力
console.log(keywords);

上記のコードでは、KeywordExtractorというクラスを作成し、コンストラクタで与えられたコードとキーワードのリストをプロパティとして保持します。また、extractKeywordsメソッドを定義してキーワードの抽出処理を実装します。

KeywordExtractorクラスのインスタンスを作成し、extractKeywordsメソッドを呼び出すことでキーワードを抽出できます。

ただし、この方法は単純な文字列マッチングを行っており、コードの文脈によって誤検出する可能性があります。言語の構文やコメントなども考慮する場合には、パーサーライブラリの使用が推奨されます。

Acorn.jsとは

Acorn.jsはJavaScriptのパーサーライブラリであり、JavaScriptのコードを解析して抽象構文木(Abstract Syntax Tree, AST)を生成する機能を提供します。これにより、JavaScriptコードの解析や静的解析、ソースコードの変換や検証などのさまざまな用途に利用することができます。

以下にAcorn.jsの主な使い道をいくつか挙げます:

  1. コード解析: Acorn.jsは、与えられたJavaScriptのコードをパースして抽象構文木を生成します。これにより、コードの構造や要素を理解し、コードの解析や分析に活用することができます。
  2. 静的解析: 抽象構文木を使用して、JavaScriptコードの静的解析を行うことができます。変数のスコープ解析、依存関係の解析、コードの依存性グラフの構築など、さまざまな静的解析タスクに利用できます。
  3. コード変換: 抽象構文木を変更することで、JavaScriptコードの変換を行うことができます。例えば、コードのリファクタリング、コードの自動生成、ソースコードのトランスパイルなどの用途に利用できます。
  4. コード検証: Acorn.jsを使用して、与えられたJavaScriptコードの構文の妥当性を検証することができます。構文エラーのチェックや文法的な問題の検出など、コードの品質管理やエラーハンドリングに役立ちます。

これらはAcorn.jsの一般的な使い道ですが、実際にはさまざまな応用が可能です。また、Acorn.jsは軽量で高速なパーサーライブラリであるため、ブラウザやNode.jsなどの環境で広く利用されています。

Acorn.jsの開発者

Acorn.jsは、Marijn Haverbekeによって開発されました。Marijn Haverbekeは、プログラミング言語JavaScriptの教育用書籍『Eloquent JavaScript』の著者でもあります。Acorn.jsは、JavaScriptのパーサーとして広く使用されており、ECMAScript(JavaScriptの標準仕様)に準拠しています。

Acron.jsを使ってJavaScriptの予約語を出力する

Acron.jsはオープンソースでGitHubからソースコードを見てみましょう。

では下記のコマンドでacron.jsをインストールしましょう。

npm i acorn

では下記の様に、import文でモジュールとして使用する方法を紹介します。

import acorn from 'acorn';

// JavaScriptのコード
const code = 'function greet() { console.log("Hello, world!"); }';

// キーワードを格納する配列
const keywords = [];

// Acornを使用してコードをパース
const ast = acorn.parse(code, { ecmaVersion: 2021 });

// ASTをトラバースしてキーワードを抽出
acorn.walk.simple(ast, {
  Expression(node) {
    if (node.type === 'Identifier' && acorn.isKeyword(node.name)) {
      keywords.push(node.name);
    }
  },
});

// 結果を出力
console.log(keywords);

修正したコードでは、import文を使用してacornモジュールをインポートし、その後のコードでacornを直接使用しています。また、acornパッケージのデフォルトエクスポートをacornとしてインポートしています。

この修正版のコードは、ESモジュールとしてブラウザ環境や対応する環境で使用することができます。ただし、ブラウザ環境で使用する場合は、acornのブラウザ向けのバージョンを読み込む必要があります。ブラウザ環境での具体的な設定方法については、acornのドキュメンテーションを参照してください。

Acorn.jsの強み

Acorn.jsを使用する場合、JavaScriptの予約語(キーワード)をパースする際に、自作のライブラリと比べて以下のようなメリットがあります:

  1. 信頼性と正確性: Acorn.jsは、JavaScriptの標準仕様(ECMAScript)に準拠しているため、パース処理が正確で信頼性があります。構文の細かなニュアンスやエッジケースを考慮して実装されており、予約語の検出や構文解析の品質が高いです。
  2. 安定性とメンテナンス: Acorn.jsは、オープンソースプロジェクトとして開発されており、幅広いコミュニティや開発者によってメンテナンスされています。バグ修正や新しいECMAScriptのバージョンへの対応などのアップデートが行われ、安定した状態を保っています。
  3. 拡張性とカスタマイズ性: Acorn.jsは、パーサーライブラリとして柔軟性があります。ASTを操作したり、カスタムのパーサープラグインを追加したりすることができます。このため、特定のニーズに合わせた機能の追加や拡張が比較的容易に行えます。
  4. パフォーマンスと効率性: Acorn.jsは高速なパーサーライブラリであり、効率的にパース処理を実行することができます。パフォーマンスが重要な場合や大規模なコードベースに対しても、高速なパースが可能です。
  5. エコシステムとサポート: Acorn.jsは広く使用されており、関連するツールやライブラリ、フレームワークなどとの連携が容易です。また、ドキュメンテーションやサンプルコード、コミュニティのサポートも充実しており、問題が発生した場合にもサポートを受けることができます。

自作のライブラリと比べて、Acorn.jsは信頼性、安定性、拡張性、パフォーマンス、エコシステムなどの面で利点があります。また、JavaScriptのパースにおいては、正確で標準に準拠した処理が重要となるため、Acorn.jsの使用は推奨されます。

ASTとは


AST(Abstract Syntax Tree)は、プログラミング言語のソースコードの構文構造を表現する木構造のデータ構造です。ASTは、ソースコードの解析や処理を容易にするために使用されます。

ASTは、ソースコードを構成するトークンや式、文、関数などの要素をノードとして表現します。ノードは親子関係で結びつき、構文的な意味や階層構造を反映します。

ASTのノードは通常、プログラミング言語の構文要素に対応しています。たとえば、変数宣言や関数呼び出し、演算子の使用など、ソースコード内のさまざまな構造がノードとして表現されます。

ASTは通常、パーサーと呼ばれるツールやライブラリを使用して生成されます。パーサーは、ソースコードを入力として受け取り、その構文を解析してASTを生成します。ASTは、コンパイラや静的解析ツール、コード変換ツールなどで使用され、ソースコードの解析や処理を行います。

ASTを使用することで、ソースコードの構造や意味を効率的に理解し、コードの解析、変換、検証、リファクタリングなどのさまざまな処理を行うことができます。また、ASTは言語に依存せずに構文解析を行うため、さまざまなプログラミング言語に適用できる汎用的な手法です。