2

さて、ここに私の問題があります:カスタムJavascript実装を使用するアプリケーションがありますが、正規表現はサポートされていません。

ただし、それでもテンプレートを解析できるようにしたいと思います。できればC++を使用してください。

テンプレートは次のようになります(ASPスタイルのテンプレート)。

<% var foo = someFunction("with a string");
   var bar =  anotherFunction(["with", "an", "array"]); %>

<b>This is html, and this is a variable: <%= bar %></b>

<% if(foo) { %>
    <b> foo is 'true'</b>
<% } else { %>
    <b> foo is 'false'. terrible. </b>
<% } %>

したがって、一般的な構造は非常に単純です(そして、私は、比較的解析可能だと思います)。

私の質問は、while()正規表現を使用する代わりに、各文字を通過するループでそのようなテンプレートを解析することは可能ですか?

そして、それをしようとする私の試みはひどく失敗したので、どうやってそれを行うことができますか?

ありがとうございました!

4

4 に答える 4

3

このようなテンプレートは非常に簡単に解析できます。

重要なのは、このようなテンプレートは基本的に、ボイラープレート(HTML)テキストとスクリプトテキストの2種類の文字列のシーケンスで構成されていることを認識することです。

ボイラープレートのテキストは、基本的に「%>」で始まり、「<%」で終わります(begin-templateとend-templateに特別な場合があります)。スクリプトテキストは他のすべてです。はい、「<%」、「%>」、または「end-of-template」を監視するそれぞれのwhileループで両方を選択できます。シーケンスは、前後に交互に暗黙的に行われます。これにより、非常に単純なパーサーになります。

  while not eof
       boilerplate="";
       while next_characters~="<%" or eof
          boilerplate concat next_characters
       end
       scripttext="";
       while next_characters~="%>" or eof
          scripttext concat next_characters
       end
  end

(個々のキャラクター管理の詳細はコーダーに任せます)。

あなたが言わなかったことは、あなたが解析された結果でやりたかったことです。解析結果から「出力を生成」することが目標である場合は、それをプログラムに変換する必要があります。それは実際にはかなり簡単です。

基本的には、結果をファイルに書き込んでコンパイルします。収集されたボイラープレートテキストの各部分について、ボイラープレートテキストを印刷する印刷ステートメントを発行します。選択したターゲット言語の文字列リテラルで文字を有効にするために文字をエスケープするか、ボイラープレートを複数のブロックに分割して印刷する必要がある場合があります。スクリプトテキストのブロックごとに、変更せずに出力します。関数ヘッダーを作成するにはプロローグテキストチャンクを発行し、関数を終了するにはポストログテキストチャンクを発行する必要があります。

それでおしまい。

[そのような「テンプレート」とprintステートメントを使用した単純なプログラムとの間の些細な変換のため、そのようなテンプレートプログラミングが非常に魅力的であるとは思いません。それは私にいくつかの印刷キーワードを節約します、そしてそれはそれです。]

于 2012-07-08T04:39:06.063 に答える
1

これは私があなたの場合に試みることです:

  1. 既知のトークンのセットを返すトークナイザーを作成します(それらが表す正確な文字列が添付されています。例ID("someFunction"):)

  2. 受け入れられたテンプレート形式を説明する上記のトークンを使用して、正式な文法を記述します

  3. 文法を認識するパーサーを作成します(例:プッシュダウンオートマトンLRパーサーまたはLALRパーサー))

:文法が、実装しているパーサーの制限に準拠していることを確認してください。そうでない場合は、文法を書き直すか、パーサーを変更します

:実装のエラーはデバッグが難しい場合があるため、パーサーを徹底的にテストするようにしてください

:有効なテンプレートであるかどうかだけでなく、解析されたテンプレートのセマンティクス(意味)を取得する場合は、解析ステップ中にいくつかの追加操作も実行する必要があります。これらの追加の手順には、変数/関数のIDの保存(トークンに添付された文字列を覚えていますか?)、参照時にそれらを検索する、関数のパラメーター番号を確認するなどが含まれます。

于 2012-07-02T17:04:11.740 に答える
1

有限ステートマシンの使用について考えたことはありますか?ここにあなたが見るためのいくつかのリンクがあります。

つまり、FSMは、有限数の状態とこれらの状態間の遷移で構成されます。したがって、構文解析のプロセスは次のように表される可能性があります(擬似コード)。

myFSM = new FSM( /* states, transitions */ );
// now your FSM is at initial state.

while not end of file {       
  switch (myFSM->currentState) {   
    case 'IF':
      // Does current line contain closing if? or else? If so, do a transition
      // to state that grabs everything in if construct 
      ...
    case 'TEXT': 
      // Lines do not have any lexical constructs, and we are outside any blocks
      ...
    ...

  }
}

もちろん、これは非常に単純化されています。実際のパーサーは異なって見えます。しかし、私はあなたがアイデアを得たことを望みます。

于 2012-07-02T18:41:11.773 に答える
0

すでに既存のソリューションがあるかもしれません。

ロジックレステンプレートライブラリ:

https://github.com/leonidas/transparency/wiki/Frequently-Asked-Questions

(最後の質問を参照してください)。

于 2012-07-08T09:35:43.057 に答える