1

基本的な知識が不足しています。今日ATLRで遊んで始めましたが、次の方法を教えてくれるソースがありませんでした。

私のプログラムが現在非常に醜い方法で読み取っている構成ファイルを解析したいと思います。基本的には次のようになります。

A [Data] [Data]
B [Data] [Data] [Data]

ここで、A / B / ...は、関連するデータが続くオブジェクトです(動的量、単純な数字のみ)。文法はそれほど難しいものではありませんが、ANTLRを今どのように使用するのですか?

  • レクサーのみ:A / Bはトークンであり、彼が読んだトークンを要求します。これを尋ねる方法と、不正な入力を検出する方法は?
  • レクサーとパーサー:A/Bはパーサールールです...パーサーが正常にA/Bを処理したことを知る方法は?同じオブジェクトがファイルに複数回表示される可能性があるため、すべてを考慮する必要があります。これは、構成ファイルにインスタンスをリストするようなものです。

編集:私の問題は文法ではなく、パーサー/レクサーが実際に見つけた/解析したものをどのように通知するかです。最良の方法は次のとおりです。再帰下降のようなルールを認識したときに関数を呼び出す

4

3 に答える 3

2

ANTLR プロダクション ルールには、構成ファイルの内容を取得するために使用できる戻り値を含めることができます。

簡単なデモを次に示します。

grammar T;

parse returns [java.util.Map<String, List<Integer>> map]
@init{$map = new java.util.HashMap<String, List<Integer>>();}
 : (line {$map.put($line.key, $line.values);} )+ EOF
 ;

line returns [String key, List<Integer> values]
 : Id numbers (NL | EOF)
   {
     $key = $Id.text;
     $values = $numbers.list;
   }
 ;

numbers returns [List<Integer> list]
@init{$list = new ArrayList<Integer>();}
 : (Num {$list.add(Integer.parseInt($Num.text));} )+
 ;

Num   : '0'..'9'+;
Id    : ('a'..'z' | 'A'..'Z')+;
NL    : '\r'? '\n' | '\r';
Space : (' ' | '\t')+ {skip();};

以下のクラスを実行する場合:

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

public class Main {
  public static void main(String[] args) throws Exception {
    String input = "A 12 34\n" +
                   "B 5 6 7 8\n" +
                   "C 9";
    TLexer lexer = new TLexer(new ANTLRStringStream(input));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    Map<String, List<Integer>> values = parser.parse();
    System.out.println(values);
  }
}

以下がコンソールに出力されます。

{A=[12, 34], B=[5, 6, 7, 8], C=[9]}
于 2012-07-01T18:49:50.837 に答える
1

何かが解析されたときにコードを実行する方法を探している場合は、アクションまたは AST を使用する必要があります (ドキュメントで調べてください)。

于 2012-07-01T18:37:41.763 に答える
1

文法は次のようになります (ANTLR ではなく疑似コードです)。

FILE ::= STATEMENT ('\n' STATEMENT)*    
STATEMENT ::= NAME ITEM*
ITEM = '[' \d+ ']'
NAME = \w+
于 2012-07-01T18:29:24.140 に答える