3

私は、ユーザーが属性を持ついくつかのオブジェクトを定義できるようにする単純な文法を持っています。例えば:

carpark : my carpark
lots: 100

car: BMW
color: red
wheels: 4

motocycle
age: 4
color: red

carpark : my second carpark

car:...
...
car:...
...
...

これらの単純な割り当てをチェックするために、ANTLRを使用して文法を作成しました。

今、私は例えば割り当ての順序や意味をチェックするのに問題があります。既存の駐車場から継承できると仮定しましょう

carpark: my third carpark
extends: my second carpark

「2台目の駐車場」がすでに存在するかどうかを確認するにはどうすればよいですか?

さらに、色などの属性の一部をオプションにし、他の属性を必須にし、順序は重要ではないようにします

car: BMW
color: red
age: 4
//should be allowed as
car: BMW
age: 4
color: red

簡単なルールは

cardefinition
    :   CAR COLON value NEWLINE attributedefinition*
    ;

attributedefinition
    :   attributekey COLON value NEWLINE!
    ;

ただし、必須属性は定義されていない可能性があります。必須の属性定義のようなルールを追加することはできますが、その場合、任意の順序で定義を許可するのは困難です。

したがって、この種のチェックはパーサーまたはツリーパーサーの一部である必要があります

4

1 に答える 1

1

パーサー文法内で有効なスーパーパーク ( ) のチェックを行うこともできextends ...ますが、ツリー文法は (結合された) 文法のより乱雑でないバージョンです: そこで、そのようなことを行うのが好きです。

できることはSet<String> parks、ツリー ウォーカーのメンバーとして を作成することです。

tree grammar CarParkWalker;

options {
  tokenVocab=CarPark; // assuming your combined grammar is called CarPark.g
  ASTLabelType=CommonTree;
}

@members {
  private Set<String> parks = new HashSet<String>();
}

// rules here

String次に、AST がトラバースされている間に s を追加します。次に、 に出くわしたときに、が に存在extends VALUEするかどうかを確認するカスタム コードを追加VALUE.textします Set<String> parks。そうでない場合は、例外をスローします。

車 (または駐車場) の必須属性とオプション属性については、(結合された) 文法で 0 個以上のパラメーターを受け入れるだけで、ツリー文法規則がVehicleインスタンスを返すようにします。

/* tree grammar rules! */

vehicle returns [Vehicle v]
  :  car        {$v = $car.v;}
  |  motorcycle {$v = $motorcycle.v;}
  ;

car returns [Vehicle v]
@init{$v = new Car();}
  :  ^(Car ... )
  ;

motorcycle returns [Vehicle v]
@init{$v = new Motorcycle();}
  :  ^(Motorcycle ... )
  ;

aVehicleは次のようになります。

abstract class Vehicle {

  protected String make;
  protected String color;
  protected int age;
  protected int wheels;

  // ...
}

次に、すべての必須属性が設定されているかどうか、各車両について確認します。

自分で試してみて、これらすべてを実装するのに問題がある場合は、簡単なデモを投稿したいと思います。その場合はコメントを追加してください。

幸運を!

于 2011-09-06T09:28:12.930 に答える