1

私はANTLRを使用してKey-Valueデータ形式を解析することを検討してきました。非常に単純ですが、キーは階層を表します。

入力構文の簡単な例:

/a/b/c=2
/a/b/d/e=3
/a/b/d/f=4

私の考えでは、これは次のように構造化されたツリーを表しています。

(a (b (= c 2) (d (= e 3) (= f 4))))

私が得ることができる最も近いものは、次の文法を使用することです:

/* Parser Rules */
start: (component NEWLINE?)* EOF -> (component)*;

component: FORWARD_SLASH ALPHA_STRING component -> ^(ALPHA_STRING component)
  | FORWARD_SLASH ALPHA_STRING EQUALS value -> ^(EQUALS ALPHA_STRING value);

value: ALPHA_STRING;

/* Lexer Rules */
NEWLINE : '\r'? '\n';
ALPHA_STRING : ('a'..'z'|'A'..'Z'|'0'..'9')+;
EQUALS : '=';
FORWARD_SLASH : '/';

生成するもの:

(a (b (= c 2))) (a (b (d (= e 3)))) (a (b (d (= f 4))))

ここでANTLRなどの汎用ツールに質問しすぎているかどうかはわかりませんが、これはこのアプローチで得られる限りの近さです。つまり、ここからツリーの一部を使用して、必要なデータ構造を手動で作成します。

では、文法から直接必要なツリー構造を作成できますか?もしそうなら、どのように?そうでない場合は、なぜそうではありませんか?それはANTLRの技術的限界ですか、それとも関連する言語の種類に関係するCS-yのようなものですか?

4

2 に答える 2

2

ここでANTLRなどの汎用ツールに質問しすぎているかどうかはわかりません...

トークンパーサーを要求しすぎていると思います。入力/a/b/c=2の場合、トークンパーサーはこれを確認します。

FORWARD_SLASH ALPHA_STRING FORWARD_SLASH ALPHA_STRING FORWARD_SLASH ALPHA_STRING EQUALS ALPHA_STRING

この場合の興味深い点は、トークン自体のテキストであり、トークンパーサーはそれをあまり気にすることができませんでした。トークンを掘り下げ、保存し、整理し、希望の配置で吐き出すには、少なくとも手動でコーディングされたアクションを使用する必要があります。

...つまり、ここからツリーの一部を使用して、必要なデータ構造を手動で作成します。

1つまたは複数のANTLRツリーパーサーを使用してクエストを支援するオプションがありますが、それらもトークンテキストではなくトークンタイプに関係しています。最終的には、途中でアクションをコーディングする必要があると思います。

あなたの文法と同じトークン語彙を使用するカスタムツリー文法を使用して、私はこれを減らすことができました(支援のためのルートノードを使用して):

(START (a (b (= c 2))) (a (b (d (= e 3)))) (a (b (d (= f 4)))))

これに:

(START (a (b (= c 2) (d (= e 3)))) (a (b (d (= f 4)))))

悪いスタートではありませんが(興味があれば、ツリーの文法を投稿できます)、これにはセマンティック述語が必要です。ANTLRは、私の側でいくつかのコーディングなしではこれを行うことができませんでした。

では、文法から直接必要なツリー構造を作成できますか?...そうでない場合は、なぜそうではありませんか?それはANTLRの技術的限界ですか、それとも関連する言語の種類に関係するCS-yですか?

これは、ある種の技術的制限です。字句解析後、ANTLR本体(つまり、挿入できるコードではない)は、トークンに作用し、トークンに含まれる可能性のあるテキストには作用しません1。テキスト「a」がトークンAにマップされ、テキスト「b」がトークンにマップされた場合B(など)、ツリーパーサーは、現在は不可能だったレバレッジを提供しますが、それでもいくつかのアクションをコーディングする必要があると思います。 /または必要なものを取得するためのセマンティック述語。


1カスタムテキストを使用してトークンを作成できることを除いて、これはこの問題とは関係ありません。

于 2012-11-22T23:08:47.873 に答える
1

できることは、ASTを使用するのではなく、独自のツリーと操作を定義することです。そうすれば、ルール「コンポーネント」が実行されるたびに新しいツリーを作成する必要はなく、新しいノードを追加するだけです。アイデアが明確だといいのですが?

于 2012-11-22T11:13:49.027 に答える