2010-12-04 7 views
2

ちょっとiveがJavaでAntlrを使い始めました。私は2d配列にいくつかの値を直接格納してこの配列を返す方法を知りたがっていましたか?私はこれについてのチュートリアルを見つけることができません。すべての助けが訴えられます。Antlr Array Help

答えて

6

のは、あなたがスペースで区切られた数字を含むフラットテキストファイルを解析したいとしましょう。これを2番目のintの配列に解析すると、各行は配列の「行」です。

、このような「言語」のANTLRの文法は次のようになります。今

grammar Number; 

parse 
    : line* EOF 
    ; 

line 
    : Number+ (LineBreak | EOF) 
    ; 

Number 
    : ('0'..'9')+ 
    ; 

Space 
    : (' ' | '\t') {skip();} 
    ; 

LineBreak 
    : '\r'? '\n' 
    | '\r' 
    ; 

、あなたはparseルールがListList<Integer>のオブジェクトを返すようにしたいと思います。

line returns [List<Integer> row] 
@init { 
    $row = new ArrayList<Integer>(); 
} 
    : Number+ (LineBreak | EOF) 
    ; 

parse returns [List<List<Integer>> numbers] 
@init { 
    $numbers = new ArrayList<List<Integer>>(); 
} 
    : line* EOF 
    ; 

あなたlineルールは唯一、それは数字の1次元のリストを返し、ビットと同じになります。@init{ ... }ブロックで初期化することができますあなたのparseルール後returns [List<List<Integer>> numbers]を追加することによって、それを行います

次のステップは、Listを実際の解析対象の値で埋めることです。これはあなたのlineルールでNumber+ループ内のコード{$row.add(Integer.parseInt($Number.text));}を埋め込む行うことができます。

line returns [List<Integer> row] 
@init { 
    $row = new ArrayList<Integer>(); 
} 
    : (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF) 
    ; 

そして最後に、あなたが実際にあなたの2D numbersに追加するあなたのline規則によって返されるList秒を追加したいと思いますあなたのparseルールからリスト:以下

parse returns [List<List<Integer>> numbers] 
@init { 
    $numbers = new ArrayList<List<Integer>>(); 
} 
    : (line {$numbers.add($line.row);})* EOF 
    ; 

は、最終的な文法である:

grammar Number; 

parse returns [List<List<Integer>> numbers] 
@init { 
    $numbers = new ArrayList<List<Integer>>(); 
} 
    : (line {$numbers.add($line.row);})* EOF 
    ; 

line returns [List<Integer> row] 
@init { 
    $row = new ArrayList<Integer>(); 
} 
    : (Number {$row.add(Integer.parseInt($Number.text));})+ (LineBreak | EOF) 
    ; 

Number 
    : ('0'..'9')+ 
    ; 

Space 
    : (' ' | '\t') {skip();} 
    ; 

LineBreak 
    : '\r'? '\n' 
    | '\r' 
    ; 
次のクラスでテストすることができます

import org.antlr.runtime.*; 
import java.util.List; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     String source = 
       "1 2  \n" + 
       "3 4 5 6 7 \n" + 
       "  8 \n" + 
       "9 10 11  "; 
     ANTLRStringStream in = new ANTLRStringStream(source); 
     NumberLexer lexer = new NumberLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     NumberParser parser = new NumberParser(tokens); 
     List<List<Integer>> numbers = parser.parse(); 
     System.out.println(numbers); 
    } 
} 

今文法からレクサーとパーサを生成します。

java -cp antlr-3.2.jar org.antlr.Tool Number.g 

はすべて.javaのソースファイルのコンパイル:

javac -cp antlr-3.2.jar *.java 

をし、メインクラスを実行します。

次の出力を生成3210

[[1, 2], [3, 4, 5, 6, 7], [8], [9, 10, 11]] 

HTH

+0

が、これはあなたが歓迎@Jayだ偉大 – Jay

+0

ですありがとうございました。 –

0

私は、人々の名前を解析してNameオブジェクトを返す文法の一部を抜粋しています。どのように動作するかを示すには十分であるはずです。配列などの他のオブジェクトも同じ方法で処理されます。文法で

:あなたの通常のJavaコードで

grammar PersonNames; 

fullname returns [Name name] 
@init { 
    name = new Name(); 
} 
    : (directory_style[name] | standard[name] | title_without_fname[name] |  family_style[name] | proper_initials[name]) EOF; 

standard[Name name] 
: (title[name] ' ')* fname[name] ' ' (mname[name] ' ')* (nickname[name] ' ')? lname[name] (sep honorifics[name])*; 

fname[Name name] : (f=NAME | f=INITIAL) { name.set(Name.Part.FIRST, toNameCase($f.text)); }; 

public static Name parseName(String str) throws RecognitionException { 
    System.err.println("parsing `" + str + "`"); 
    CharStream stream = new ANTLRStringStream(str); 
    PersonNamesLexer lexer = new PersonNamesLexer(stream); 
    CommonTokenStream tokens = new CommonTokenStream(lexer); 
    PersonNamesParser parser = new PersonNamesParser(tokens); 

    return parser.fullname(); 
}