2009-05-01 25 views
0

除了完成任何真正的工作之外,我還有一個癢。我的癢就是編寫一個視圖引擎,它可以模仿另一種語言(Template Toolkit/Perl)的模板系統。如果我有時間/去學習一些新的項目,這是其中之一。寫一個TemplateLanguage/VewEngine

我花了很多時間看着CoCo/R和ANTLR,老實說,這會讓我的大腦受到傷害,但CoCo/R正在沉入其中。不幸的是,大部分例子都是關於創建一個讀取源代碼的編譯器代碼,但似乎沒有涵蓋如何爲模板創建處理器。

是的,這些都是一樣的事情,但我無法圍繞如何定義模板的語言,其中大部分源代碼是html,而不是實際的代碼被解析和運行。

這種東西有沒有好的初學者資源?我已經採取了Spark的方式,這在回購中似乎沒有語法。

也許這是矯枉過正,而且可能只是測試 - 用文件中的c#替換模板語法並編譯它。 http://msdn.microsoft.com/en-us/magazine/cc136756.aspx#S2

如果你在我的鞋子裏,而且不是一個語言創建專家,你會從哪裏開始?

回答

3

Spark語法是用一種流利的領域特定語言實現的。

它在幾層中聲明。識別html語法的規則在MarkupGrammar.cs中聲明 - 這些規則基於直接從xml規範複製的語法規則。

標記規則是指在CodeGrammar.cs中聲明的csharp語法規則的有限子集 - 這些是子集,因爲Spark只需要識別足夠的csharp就可以將字符串周圍的單引號調整爲雙引號,匹配大括號等。

單個規則本身的類型爲ParseAction<TValue> delegate,它接受Position並返回ParseResult。 ParseResult是一個簡單的類,它包含由動作解析的TValue數據項和一個已經超出生成TValue內容的新的Position實例。

直到你引入一個small number of operators,這在Parsing expression grammar中被描述,它可以結合單個解析動作來構建關於不同語法結構形狀的非常詳細和健壯的表達式,這對它本身並不是很有用。

使用委託作爲分析操作的技術來自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步。編寫一個遞歸函數(稱爲interp reter),它可以走你的樹並執行那裏的指令。如果您的語言支持eval()(例如Perl,Python,Ruby),則使用另一種替代方法(而不是步驟1--3):使用正則表達式替換將模板轉換爲eval()字符串在主機語言中,並運行eval()來實例化模板。

+0

那麼,前3個步驟基本上是ANTLR/COCO/R吧?這是一個選擇推出自己的解析器,或依靠語法的問題。 另一種方法是我可以環繞我的頭(將模板轉換爲c#輸出。什麼是正確vs vs easy vs最佳開始方法? 最後,測試對於這類事情來說是最好的選擇 – claco 2009-05-01 20:36:48

0

有很多事情要做。但它確實適用於簡單的GET語句和測試。這是一個開始。

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

最後,我已經在ANTLR太多時間給loudejs'的方法一展身手。我想在整個過程中花費更多時間,而不是解析器/詞法分析器。也許在版本2中,我可以用Spark的方式去理解一些事情,當我的大腦理解更多的東西時。

0

Vici Parser(以前稱爲LazyParser.NET)是一個開源的標記器/模板分析器/表達式分析器,可以幫助您開始。

如果這不是你正在尋找的,那麼你可以通過查看源代碼來獲得一些想法。