簡潔な答え
- CriteriaValue.js
module.exports
で、最初の行を次のように変更します。parser
- index.html で、
<script>
CriteriaValue.js が最初になるようにタグを入れ替えます。
- (オプション) script.js で、実際の値を確認するために、解析の結果を書式設定された JSON 文字列として出力します。
これがプランカーです: http://plnkr.co/edit/kiBp2Na9s4PXpenCzQjx?p=preview
長い答え
元の plunker を実行し、コンソール ログを確認します。2 つのエラーに気付くでしょう:
ReferenceError: Can't find variable: parser (script.js:3)
ReferenceError: Can't find variable: error (CriteriaValue.js:1)
最初のエラーはparser
、script.js または CriteriaValue.js によってグローバル スコープでオブジェクトが作成されていないことが原因です。
CriteriaValue.js を見ると、実際には、生成されたパーサー オブジェクトが存在しない に割り当てられていることがわかりますmodules.export
。node.js でパーサーを使用することを想定しているため、これが PEG.js のデフォルトの動作です。エラーが表示される理由は、オブジェクトがないためです。そのためmodule
、この存在しないオブジェクトのexport
プロパティに割り当てることができません。割り当てを に変更するparser
と (PEG.js はstrict モードを使用しないため)、割り当てが可能になり、このエラーが回避parser
され、script.js で使用できるようになります。
最後に、script.js で使用する前にパーサーを作成する必要があります。<script>
それがスワップの理由です。
今後 CriteriaValue.js を作成するには、次のようにします。
pegjs --export-var parser CriteriaValue.pegjs
これにより、オブジェクトが のparser
代わりに変数に割り当てられるようにファイルが生成されますmodule.exports
。
AngularJS の出番
@dirkk がコメントで述べたように、パーサーをグローバル変数として定義することは悪い習慣であり、パーサーをサービスとして実装する AngularJS の方法ではありません。
これを行うための最も迅速な (ただし必ずしも最適とは限りません) 方法は、既に生成されている CriteriaValue.js コードを取得し、それをサービスでラップすることです。例えば:
angular.module('yourApp.services', [])
.factory('Parser', function() {
// The generated code, except replace "parser = " with "return "
});
別のオプションは、.pegjs ファイルを取得し、以下を使用してクライアントでパーサーを生成することですPEG.buildParser()
。
angular.module('yourApp.services', [])
.factory('Parser', ['$http', '$q', function($http, $q) {
var deferred = $q.defer();
$http.get('path/to/CriteriaValue.pegjs')
.success(function(grammar) {
try {
deferred.resolve(PEG.buildParser(grammar));
} catch (e) {
deferred.reject(e);
}
})
.error(function(message) {
deferred.reject('Unable to load grammar: ' + message);
});
return deferred.promise;
}]);
これにより、毎回サービスを書き直す必要がなくなるため、文法の更新が容易になりますが、アプリの読み込みが遅くなります。これが実現可能かどうかは、文法がどれほど複雑で、実際に変更する必要があるかによって異なります。
パーサーの作成方法に関係なく、生成されたパーサー オブジェクトを Angular アプリの残りの部分に直接公開する必要は必ずしもありません。代わりに、このパーサーを使用してアプリが実際に行うことについて、より高レベルの API を実装できます (例: validate(input)
、getAST(input)
など)。このようにすると、将来別のパーサー (Jison など) に切り替えることにした場合でも、変更するコードが大幅に少なくなります。