Domanda

Ho una semplice grammatica che permette all'utente di definire alcuni oggetti con gli attributi. Ad esempio:

carpark : my carpark
lots: 100

car: BMW
color: red
wheels: 4

motocycle
age: 4
color: red

carpark : my second carpark

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

ho creato una grammatica con ANTLR per controllare tali assegnazioni semplici.

Ora ho problemi di controllo, ad esempio l'ordine o il significato delle assegnazioni. Assumiamo che posso ereditare da un parcheggio

esistente
carpark: my third carpark
extends: my second carpark

Come devo controllare se 'il mio secondo parcheggio' esiste già?

Inoltre voglio alcuni degli attributi come il colore è facoltativo, altre obbligatorie e l'ordine non dovrebbe essere importante

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

Una regola semplice sarebbe

cardefinition
    :   CAR COLON value NEWLINE attributedefinition*
    ;

attributedefinition
    :   attributekey COLON value NEWLINE!
    ;

Ma poi attributi obbligatori non può essere definito. Potrei aggiungere una regola aggiuntiva come mandatoryattributedefinition ma poi è difficile da permettere definizioni in qualsiasi ordine

Quindi, dovrebbe questo tipo di controllo far parte del parser o di un parser albero

È stato utile?

Soluzione

You could do the checking of valid super-parks (extends ...) inside the parser grammar, but a tree grammar is less cluttered version of your (combined) grammar: so I like to do such stuff in there.

What you could do is create a Set<String> parks as a member of your tree walker:

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

and then add Strings to it while the AST is traversed. Then when you stumble upon an extends VALUE, you add some custom code where you check if VALUE.text is present in your Set<String> parks. If not, throw an exception.

About mandatory an optional attributes of cars (or car-parks), simply accept zero or more parameters in your (combined) grammar and let your tree grammar rules return a Vehicle instance:

/* 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 ... )
  ;

where a Vehicle may look like:

abstract class Vehicle {

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

  // ...
}

And then check if for each vehicle if all mandatory attributes have been set.

If, after trying yourself, you're having trouble implementing all this, I'm willing to post a little demo of it. Just add a comment in that case.

Good luck!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top