2

私はこの問題を抱えているでしょう:このルールを考えると

   defField: type VAR ( ',' VAR)* SEP ;  

   VAR : ('a'..'z'|'A'..'Z')+ ;

   type: 'Number'|'String' ;

   SEP : '\n'|';' ;

私がしなければならないのは、テンプレートをルール「defField」に関連付けることです。これは、フィールドのxmlスキーマを表す文字列を返します。つまり、次のとおりです。

   Number a,b,c ;-> "<xs:element name="a" type = "xs:Number"\>" ,also for b and c.

私の問題は * of Kleene にあります。つまり、「*」に照らして上記で説明したことを行うためのテンプレートをどのように作成すればよいのでしょうか??

ありがとうございます!!!

4

1 に答える 1

6

演算子を使用してVAR、a 内のすべてのトークンを収集します。java.util.List+=

defField
  :  t=type v+=VAR (',' v+=VAR)* SEP 
  ;  

現在v(リスト) にはすべてVARの が含まれています。

次に、StringTemplateGroup のメソッドにパラメータとしてtandを渡します。v

defField
  :  t=type v+=VAR (',' v+=VAR)* SEP -> defFieldSchema(type={$t.text}, vars={$v})
  ;  

(ファイル: T.stg )defFieldSchema(...)のように、StringTemplateGroup で宣言する必要があります。

group T;

defFieldSchema(type, vars) ::= <<
<vars:{ v | \<xs:element name="<v.text>" type="xs:<type>"\>
}>
>>

コレクションを反復処理するための構文は次のとおりです。

<COLLECTION:{ EACH_ITEM_IN_COLLECTION | TEXT_TO_EMIT }>

Ansvarsは をList含むので、そのメソッドに頼るのではなく、CommonTokensその属性を取得しました。.texttoString()

デモ

次の文法を取ります (ファイルTg ):

grammar T;

options {
  output=template;
}

defField
  :  t=type v+=VAR (',' v+=VAR)* SEP -> defFieldSchema(type={$t.text}, vars={$v})
  ;  

type
  :  NUMBER
  |  STRING
  ;

NUMBER
  :  'Number'
  ;

STRING
  :  'String' 
  ;

VAR 
  :  ('a'..'z'|'A'..'Z')+ 
  ;

SEP 
  :  '\n'
  |  ';' 
  ;

SPACE
  :  ' ' {skip();}
  ;

これは、次のクラス (ファイル: Main.java )でテストできます。

import org.antlr.runtime.*;
import org.antlr.stringtemplate.*;
import java.io.*;

public class Main {
  public static void main(String[] args) throws Exception {
    StringTemplateGroup group = new StringTemplateGroup(new FileReader("T.stg"));
    ANTLRStringStream in = new ANTLRStringStream("Number a,b,c;");
    TLexer lexer = new TLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    TParser parser = new TParser(tokens);
    parser.setTemplateLib(group);
    TParser.defField_return returnValue = parser.defField();
    StringTemplate st = (StringTemplate)returnValue.getTemplate();
    System.out.println(st.toString());
  }
}

このクラスを実行するとわかるように、入力が解析され"Number a,b,c;"、次の出力が生成されます。

<xs:element name="a" type="xs:Number">
<xs:element name="b" type="xs:Number">
<xs:element name="c" type="xs:Number">

編集

デモを実行するには、次のファイルがすべて同じディレクトリにあることを確認してください。

  • T.g(結合された文法ファイル)
  • T.stg(StringTemplateGroup ファイル)
  • antlr-3.3.jar(この記事の執筆時点での最新の安定した ANTLR ビルド)
  • Main.java(テストクラス)

次に、OS のシェル/プロンプトから (すべてのファイルがある同じディレクトリから) 次のコマンドを実行します。

java -cp antlr-3.3.jar org.antlr.Tool Tg # レクサーとパーサーを生成する

javac -cp antlr-3.3.jar *.java # すべての .java ソース ファイルをコンパイルします

java -cp .:antlr-3.3.jar Main # メインクラスを実行 (*nix)
                                           # また
java -cp .;antlr-3.3.jar Main # メイン クラスを実行する (Windows)         

おそらく言及する必要#はありませんが、その後にテキストを含めることはコマンドの一部であってはなりません。これらは、これらのコマンドの目的を示すための単なるコメントです。

于 2011-05-22T20:15:52.707 に答える