2009-05-01 7 views
0

実際の作業を終えるのとは別に、かゆみがあります。テンプレートシステムを他の言語(Template Toolkit/Perl)とよく似たビューエンジンを作成するのが苦労します。これは、私が時間があった/それらの新しい種類のプロジェクトを学ぶためにそれを行うの1つです。TemplateLanguage/VewEngineの書き方

私はCoCo/RとANTLRを見るのに時間を費やしましたが、正直なところ、私の頭が痛くなりますが、CoCo/Rの一部が沈んでいます。残念なことに、ほとんどの例では、コードを作成することはできませんが、どのようにテンプレート用のプロセッサを作成するかは分かりません。

はい、それらは同じですが、実際のコードが解析されて実行されるのではなく、ソースのほとんどがhtmlであるテンプレートの言語を定義する方法を頭に入れてはいけません。

この種のものには、初心者のリソースはありますか?私はスパークでガーナーを連れてきましたが、レポには文法がないようです。

おそらくそれは残酷で、テンプレートの構文をファイルのc#でテスト置換してコンパイルするだけかもしれません。 http://msdn.microsoft.com/en-us/magazine/cc136756.aspx#S2

あなたが私の靴の中にあって、言語作成の専門家でない場合は、どこから始めますか?トークンリストにご入力テンプレート文字列を分割する

答えて

3

Spark文法は、流暢なドメイン固有の言語で実装されています。

これはいくつかのレイヤーで宣言されています。 html構文を認識する規則は、MarkupGrammar.csで宣言されています。これらの規則は、XML仕様から直接コピーされた文法規則に基づいています。

マークアップルールは、CodeGrammar.csで宣言されたcsharp構文規則の限定されたサブセットを指します。これらはサブセットです。文字列を二重引用符で囲むために十分なcsharpを認識すればよいからです。

個々のルール自体は、ParseAction<TValue> delegateのタイプであり、Positionを受け入れ、ParseResultを返します。 ParseResultは、アクションによって解析されたTValueデータ項目と、TValueを生成したコンテンツを先に進んだ新しいPositionインスタンスを含む単純なクラスです。

small number of operatorsで説明されているように、単独の構文解析アクションを組み合わせてさまざまな構文構造の形について非常に詳細で強力な表現を作成することができます。

パースアクションとしてデリゲートを使用するテクニックは、Luke Hのブログ記事Monadic Parser Combinators using C# 3.0にあります。私はまた、Creating a Domain Specific Language for Parsingについての投稿を書いた。

Spark.dllアセンブリを参照し、CharGrammarベースのクラスを継承して、特定の構文のまったく新しい文法を作成することも可能です。これはおそらく、このテクニックを試してみるのが最も簡単な方法です。その例はCharGrammarTester.csにあります。

0

ステップ1.正規表現(正規表現置換)は、例えば、あなたのトークンに変換

hel<b>lo[if foo]bar is [bar].[else]baz[end]world</b>! 

write('hel<b>lo') 
if('foo') 
write('bar is') 
substitute('bar') 
write('.') 
else() 
write('baz') 
end() 
write('world</b>!') 

にステップ2を分割しました構文木にリストする:

* Sequence 
** Write 
*** ('hel<b>lo') 
** If 
*** ('foo') 
*** Sequence 
**** Write 
***** ('bar is') 
**** Substitute 
***** ('bar') 
**** Write 
***** ('.') 
*** Write 
**** ('baz') 
** Write 
*** ('world</b>!') 

class Instruction { 
} 
class Write : Instruction { 
    string text; 
} 
class Substitute : Instruction { 
    string varname; 
} 
class Sequence : Instruction { 
    Instruction[] items; 
} 
class If : Instruction { 
    string condition; 
    Instruction then; 
    Instruction else; 
} 

ステップ3.再帰関数あなたの木を歩いてそこの指示を実行することができます。

あなたの言語がeval()(Perl、Python、Rubyなど)をサポートしている場合、別の代替アプローチ(手順1〜3の代わりに):regexp置換を使用してテンプレートをevalホスト言語でeval()を実行してテンプレートをインスタンス化します。

+0

最初の3つのステップは基本的にANTLR/COCO/Rですか?それはあなた自身のパーサーを振るか、文法に頼るかの選択です。 代替案は私の頭を包み込むことができるものです(テンプレートをC#出力に翻訳する)。起動時に簡単なものと最も良いものとを比較する方法はありますか? 最後に、この種のテストには – claco

+0

ステップ2はANTLRやCOCO/Rに似ていますが、私にとって最良の方法は、可能な限りシンプルにすることですが、有用なままです。例えばif条件が算術式をサポートする必要がない場合(if 3 * 4> 10])、ANTLRやCOCO/Rは必要ありません。テンプレートを左から右にスキャンし、保留中のifsをスタックに置くだけで、[終了]が表示されたら、何を閉じる。 – pts

0

すごくたくさんあることがあります。しかし、それは簡単なGETステートメントとテストのために働きます。それがスタートです。

http://github.com/claco/tt.net/

は最後に、私はすでにloudejs'メソッド行くを与えるためにANTLRであまりにも多くの時間を過ごしました。私は、パーサ/レクサーではなく、全体のプロセスに少し時間を費やしたかったのです。おそらくバージョン2では、私の脳が物事をもう少し理解すると、スパークの方法で動くことができます。

0

Vici Parser(以前はLazyParser.NETとして知られていました)は、オープンソースのトークナイザ/テンプレートパーサ/式パーサで、使い始めることができます。

もしあなたが探しているものでないなら、あなたはソースコードを見ていくつかのアイデアを得るかもしれません。