簡體   English   中英

AngularJS Webapp中的Peg.js

[英]Peg.js in AngularJS webapp

我有一個AngularJS Web應用程序。

我想在我的應用程序中使用peg.js。 我剛剛編寫了一個peg.js語法:CriteriaValue.pegjs,並使用以下命令行生成了解析器: pegjs CriteriaValue.pegjs ,該語法生成​​了CriteriaValue.js。

有人可以向我解釋如何使用解析器嗎?

var result = parser.parse('my string'); 不起作用。

我已經創建了一個插件: http ://plnkr.co/edit/Ae05SeZAjKOQ75B3lvLc?p=preview

簡短答案

  • 在CriteriaValue.js中,將第一行中的module.exports更改為parser
  • 在index.html中,交換<script>標記,以便首先顯示CriteriaValue.js
  • (可選)在script.js中,將解析結果輸出為格式化的JSON字符串,以便查看實際值

這是pl人: http ://plnkr.co/edit/kiBp2Na9s4PXpenCzQjx?p=preview

長答案

運行您的原始插件,並檢查控制台日志; 您會發現2個錯誤:

  • ReferenceError: Can't find variable: parser (script.js:3)
  • ReferenceError: Can't find variable: error (CriteriaValue.js:1)

第一個錯誤是由於以下事實:script.js或CriteriaValue.js從未在全局范圍內創建任何parser對象。

查看CriteriaValue.js,您可以看到它實際上是將生成的解析器對象分配給不存在的modules.export 這是PEG.js的默認行為,因為它假定您將解析器與node.js一起使用。 您看到此錯誤的原因是,沒有module對象,因此我們無法將其分配給此不存在的對象的export屬性。 將分配更改為parser ,這是我們可以分配的(因為PEG.js不使用嚴格模式 ),避免了此錯誤,並使parser可用於script.js。

最后,需要在script.js使用解析器之前創建解析器。 因此<script>交換的原因。

為了將來創建CriteriaValue.js,請執行以下操作:

pegjs --export-var parser CriteriaValue.pegjs

這將生成文件,以便將對象分配給變量parser而不是module.exports

AngularJS出現的地方

正如@dirkk在評論中所說,將解析器定義為全局變量是一種不好的做法,當然不是將AngularJS方式實現為服務的AngularJS方式。

最快(但不一定最好)的方法是獲取已經生成的CriteriaValue.js代碼,並在其周圍包裝一個服務。 例如:

angular.module('yourApp.services', [])
.factory('Parser', function() {
  // The generated code, except replace "parser = " with "return "
});

另一個選擇是使用PEG.buildParser()獲取.pegjs文件並在客戶端上生成解析器:

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),則可以更改的代碼要少得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM