2012-02-21 12 views
1

私は初期のANTLR 3.1文法を3.4に更新しようとしているANTLR初心者です。私が打っている障害は、私が生成したパーサーにあります。 NextNode()を呼び出すコード行があり、代わりにNextTree()を呼び出して、パーサが目的の動作を実行するようにします。の右側を処理するコードの生成部分は、(C#で)私のパーサで生成されたパーサーでRewriteRuleSubtreeStream.NextTree()を強制的に呼び出すように式を変更するにはどうすればよいですか?

ssisType 
: 

( typeCode ='DT_I1' 
| typeCode ='DT_I2' 
| typeCode ='DT_I4' 
| typeCode ='DT_I8' 
| typeCode ='DT_R4' 
| typeCode ='DT_R8' 
| typeCode ='DT_CY' 
| typeCode ='DT_DATE' 
| typeCode ='DT_BOOL' 
| typeCode ='DT_NUMERIC' 
| typeCode ='DT_DECIMAL' 
| typeCode ='DT_UI1' 
| typeCode ='DT_UI2' 
| typeCode ='DT_UI4' 
| typeCode ='DT_UI8' 
| typeCode ='DT_GUID' 
| typeCode ='DT_BYTES' 
| typeCode ='DT_STR' 
| typeCode ='DT_WSTR' 
| typeCode ='DT_DBDATE' 
| typeCode ='DT_DBTIME' 
| typeCode ='DT_DBTIME2' 
| typeCode ='DT_DBTIMESTAMP' 
| typeCode ='DT_DBTIMESTAMP2' 
| typeCode ='DT_DBTIMESTAMPOFFSET' 
| typeCode ='DT_FILETIME' 
| typeCode ='DT_IMAGE' 
| typeCode ='DT_TEXT' 
| typeCode ='DT_NTEXT') -> ^(SSISTYPE $typeCode) 

当該マイANTLR式は次のとおり

cast : ('(' ssisType (',' INT)* ')') term -> ^(CAST ^(ssisType INT*) term) 
; 

ssisTypeは以下のように定義されます式は次のとおりです。

retval.Tree = root_0; 
    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.Tree:null); 

     root_0 = (CommonTree)adaptor.Nil(); 
     // 99:44: -> ^(CAST ^(ssisType (INT)*) term) 
     { 
      DebugLocation(99, 47); 
      // SsisGrammar.g:99:47: ^(CAST ^(ssisType (INT)*) term) 
      { 
      CommonTree root_1 = (CommonTree)adaptor.Nil(); 
      DebugLocation(99, 49); 
      root_1 = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(CAST, "CAST"), root_1); 

      DebugLocation(99, 54); 
      // SsisGrammar.g:99:54: ^(ssisType (INT)*) 
      { 
      CommonTree root_2 = (CommonTree)adaptor.Nil(); 
      DebugLocation(99, 57); 
      root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2); 

      DebugLocation(99, 66); 
      // SsisGrammar.g:99:66: (INT)* 
      while (stream_INT.HasNext) 
      { 
       DebugLocation(99, 66); 
       adaptor.AddChild(root_2, stream_INT.NextNode()); 

      } 
      stream_INT.Reset(); 

      adaptor.AddChild(root_1, root_2); 
      } 
      DebugLocation(99, 72); 
      adaptor.AddChild(root_1, stream_term.NextTree()); 

      adaptor.AddChild(root_0, root_1); 
      } 

     } 

root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextNode(), root_2); 

理由は、ツリーの最上位ノードは、NEXTNODEを使用して追加されていない子供が含まれていることである

root_2 = (CommonTree)adaptor.BecomeRoot(stream_ssisType.NextTree(), root_2); 

になります。

私は自分の望む行動を生み出すために表現を変えることができますか?式の中のいくつかの箇所に^を挿入しようとしましたが、間違った結果が生成されるか、文法が構築されません。

おかげで非常に多く、

-Craig

答えて

1

あなたはその私の知る限り行うことはできません:あなたは^((ルート)の直後に置いて何が常に単一のノード、ノーツリーとみなされます。

アン若干異なる方法:入力を解析します

cast 
: ('(' ssisType (',' INT)* ')') term -> ^(CAST ^(SSISTYPE ssisType INT*) term) 
; 

ssisType 
: 'DT_I1' 
| 'DT_I2' 
// ... 
; 

:以下ASTに

(DT_I2, 42, 666)123456 

:これは魅力のように働いた

enter image description here

+0

、ありがとう! – Craig

+0

@Craigようこそ。 –