Pregunta

Tengo una gramática simple que permite al usuario definir algunos objetos con atributos. Por ejemplo:

carpark : my carpark
lots: 100

car: BMW
color: red
wheels: 4

motocycle
age: 4
color: red

carpark : my second carpark

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

He creado una gramática con ANTLR para verificar esas tareas simples.

Ahora tengo problemas para verificar, por ejemplo, el orden o el significado de las tareas. Supongamos que puedo heredar desde un aparcamiento existente

carpark: my third carpark
extends: my second carpark

¿Cómo debo comprobar si 'mi segundo estacionamiento' ya existe?

Además, quiero que algunos de los atributos como el color sean opcionales, otros obligatorios y el orden no debería ser importante

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

Una regla simple sería

cardefinition
    :   CAR COLON value NEWLINE attributedefinition*
    ;

attributedefinition
    :   attributekey COLON value NEWLINE!
    ;

Pero entonces los atributos obligatorios pueden no definirse. Podría agregar una regla adicional como obligatoryattributeDefinition, pero es difícil permitir definiciones en cualquier orden

Entonces, ¿debería este tipo de comprobación ser parte del analizador o un analizador de árboles?

¿Fue útil?

Solución

pudo hacer la comprobación de súper parques válidos (extends ...) Dentro de la gramática del analizador, pero una gramática de árbol es una versión menos abarrotada de su gramática (combinada): así que me gusta hacer esas cosas allí.

Lo que podrías hacer es crear un Set<String> parks Como miembro de su caminante de árbol:

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

y luego agregar StringS a él mientras el AST está atravesado. Entonces cuando tropieces a un extends VALUE, agrega algún código personalizado donde verifica si VALUE.text está presente en tu Set<String> parks. Si no, lanza una excepción.

Sobre la obligación de un atributos opcionales obligatorios de los automóviles (o parques de automóviles), simplemente acepte cero o más parámetros en su gramática (combinada) y deje que las reglas de la gramática de su árbol devuelvan un Vehicle instancia:

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

donde un Vehicle puede parecer:

abstract class Vehicle {

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

  // ...
}

Y luego verifique si para cada vehículo si se han establecido todos los atributos obligatorios.

Si, después de intentarlo, tienes problemas para implementar todo esto, estoy dispuesto a publicar una pequeña demostración de ella. Simplemente agregue un comentario en ese caso.

¡Buena suerte!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top