2013-01-04 39 views
0

我有一個更一般的問題。操縱AST來改變輸入文字

我目前正在使用ANTLR V3.4項目 - 這裏是我們的理念:

  • 解析某些輸入,並在地圖的過程中存儲其重要組成部分。
  • 在表單中顯示解析的輸入(請參閱此Example Picture)。表單字段由鍵命名並填充了Map的值,而文本輸入字段包含整個輸入。

所以,如果用戶輸入/改變在底部的文本,格式字段的內容也將改變,因爲在解析器語法即建立其被用作輸入來填充地圖(代碼動作的表單域)。

但是我們也想要另一個方向:如果用戶在其中一個表單域中更改了值,那麼這些更改應該反映在底部的文本中。

我想過使用AST創建,然後操縱來完成這項任務。我已經將樹重寫規則添加到了我的語法中。但我不太清楚如何在Map,AST和如何創建輸出之間建立連接。

我是否在正確的軌道?任何其他想法?

編輯

所以我跟着你的建議,並直接把假節點爲可以改變的數據結構,一切都很好。

但是現在我有其他2個問題:

  1. 如何添加令牌?輸入中有可選部分,因此某些表單域可能爲空。如果我將表單字段更改爲給定值,則必須在樹中創建新節點。我將如何做到這一點?我必須確定在哪裏放置新節點...
  2. 我如何刪除令牌?因此,如果我將某些表單字段的值更改爲'空',則必須刪除關聯的節點,但這可能會影響周圍的節點(例如,在每個標記之後的逗號中都有逗號)。我真的不知道該怎麼做。

這是我目前的語法:

parser grammar TestASTParser; 

options { 
    language = Java; 
    tokenVocab = TestASTLexer; 
    output = AST; 
} 

... 

entry 
: 
lemma=phrase 

(lgrammatt=grammatts)? (lsemantic=semantics)? (lsubsemantic=subsemantics)? 

SEP 

translat=phrase 

(tgrammatt=grammatts)? (tsemantic=semantics)? (tsubsemantic=subsemantics)? 

EOF 

    -> ^(ENTRY 
     ^(LEMMA ^(LEMMA_TEXT $lemma) ^(LEMMA_GRAMM $lgrammatt)? 
     ^(LEMMA_SEM $lsemantic)? ^(LEMMA_SUBSEM $lsubsemantic)?) 
     ^(SEPARATOR SEP) 
     ^(TRANSLATION 
      ^(TRANSLAT_TEXT $translat) ^(TRANSLAT_GRAMM $tgrammatt)? 
      ^(TRANSLAT_SEM $tsemantic)? ^(TRANSLAT_SUBSEM $tsubsemantic)?) 
     ) 

; 

phrase 
: 
    t=((options{ greedy = false; }:.)+) 

    -> PHRASE[$phrase.text] 
; 

grammatts 
: 
    OPEN_BRACKET grammlist CLOSE_BRACKET 
; 

semantics: 
    LEFT_CURLY phrase RIGHT_CURLY 
; 

subsemantics: 
    D_LEFT_CURLY phrase D_RIGHT_CURLY 
; 

grammlist 
: 
    grammatt (COMMA grammatt)* 
; 

grammatt: 
    (GENUS | GRAMMATT) 
; 

所以結果樹測試輸入

Angeber(in) [f] {Großkotz} {{xyz}} <> baterlunza(a) [m(f), refl] {boeser buba}

看起來像this(黃色節點總是存在的,其他一切都是可選) 。所以,如果我在表單字段中將「refl」更改爲「」,那麼節點「refl」應該消失,但是它之前的「,」也會消失。如果我刪除LEMMA_GRAMM以下的「f」,則整個子樹必須消失(因爲列表不能爲空)。或者,如果我想添加子元素到TRANSLATION,我將不得不創建相應的節點TRANSLAT_SUBSEM加花括號{{}}的子節點。

我真的不知道從哪裏開始。我的樹結構是否對此更好?我是否需要自己實施BaseTree?或者它只是普通的Java?

+0

你已經看過Eclipse JDT嗎?他們不在那裏使用EMF。所以他們可能會做一些類似的事情的機會很大。 – SpaceTrucker

+0

讓Map將鍵關聯到相應的AST節點如何?您可以從節點獲取初始值並直接進行更新。 – user1201210

+0

聽起來很有希望,我會試試看。 – codebat

回答

0

我不知道這是否直接適合您的情況。但是當使用Xtext時,您也會得到相應的EMF Model。然後,您的用戶界面基本上是視圖上半部分中的EMF模型的表單,以及視圖下半部分中EMF模型的文本序列化部分的Xtext編輯器。由於視圖的上部和下部都基於相同的EMF模型實例,因此任何一部分視圖中的更改都可以反映在其他任何部分中。 Xtext將爲您提供必要的解析和序列化的下部分文本。

由於您使用的是ANTLR,因此您可以將ANTLR語法遷移到Xtext。然而,這不是自動實現的,但不應該是一項太困難的任務。

+0

恩,謝謝你的回答和建議。不幸的是,在這種情況下,它沒有任何幫助,因爲我們不能在這個項目中使用Xtext(出於我不能解釋的原因)。實際上,我們甚至從Xtext轉移到了ANTLR。 ;)但是,不過謝謝。 – codebat