ANTLR - contrôle sémantique / sens des valeurs
-
26-10-2019 - |
Question
J'ai une grammaire simple qui permet à l'utilisateur de définir des objets avec des attributs. Par exemple:
carpark : my carpark
lots: 100
car: BMW
color: red
wheels: 4
motocycle
age: 4
color: red
carpark : my second carpark
car:...
...
car:...
...
...
J'ai créé une grammaire avec ANTLR pour vérifier ces affectations simples.
Maintenant, j'ai des problèmes de contrôle par exemple l'ordre ou le sens des missions. Lets suppose que je peux hériter d'un parking existant
carpark: my third carpark
extends: my second carpark
Comment dois-je vérifier si mon deuxième parking »existe déjà?
De plus, je veux quelques-uns des attributs tels que la couleur soit facultative, d'autres obligatoires et l'ordre ne devrait pas être important
car: BMW
color: red
age: 4
//should be allowed as
car: BMW
age: 4
color: red
Une règle simple serait
cardefinition
: CAR COLON value NEWLINE attributedefinition*
;
attributedefinition
: attributekey COLON value NEWLINE!
;
Mais les attributs obligatoires ne peut pas être défini. Je pourrais ajouter une règle supplémentaire comme mandatoryattributedefinition mais il est difficile de permettre à des définitions dans l'ordre
devrait vérifier ce genre de faire partie de l'analyseur ou un analyseur d'arbre
La solution
peut faire la vérification des super-parcs valides (de extends ...
) à l'intérieur de la grammaire de l'analyseur, mais une grammaire d'arbre est une version moins encombré de votre (combiné) la grammaire: donc j'aime faire une telle substance là-dedans.
Ce que vous pouvez faire est de créer un Set<String> parks
en tant que membre de votre arbre marcheur:
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
et puis ajouter String
s à pendant que l'AST est traversée. Puis, quand vous tombez sur un extends VALUE
, vous ajoutez un code personnalisé où vous vérifier si VALUE.text
est présent dans votre Set<String> parks
. Sinon, jetez une exception.
A propos obligatoires un des attributs facultatifs de voitures (ou les parkings), simplement accepter zéro ou plusieurs paramètres dans votre grammaire (combinée) et laissez vos règles de grammaire d'arbres renvoient une instance 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 ... )
;
où Vehicle
peut ressembler à:
abstract class Vehicle {
protected String make;
protected String color;
protected int age;
protected int wheels;
// ...
}
Et puis vérifier si pour chaque véhicule si tous les attributs obligatoires ont été définis.
Si, après vous essayer, vous éprouvez des difficultés la mise en œuvre de tout cela, je suis prêt à poster une petite démo de celui-ci. Il suffit d'ajouter un commentaire dans ce cas.
Bonne chance!