Вы могли бы выполнять проверку действительных суперпарков (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
s к нему при прохождении AST. Затем, когда вы сталкиваетесь с extends VALUE
, вы добавляете некоторый пользовательский код, где вы проверяете, присутствует ли VALUE.text
в вашем Set<String> parks
. Если нет, выведите исключение.
Об обязательных необязательных атрибутах автомобилей (или автостоянок), просто примите ноль или более параметров в вашей (комбинированной) грамматике и позвольте вашим правилам грамматики дерева вернуть 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 ... )
;
где Vehicle
может выглядеть так:
abstract class Vehicle {
protected String make;
protected String color;
protected int age;
protected int wheels;
// ...
}
А затем проверьте, установлены ли для каждого транспортного средства все обязательные атрибуты.
Если, попробовав себя, у вас возникли проблемы с реализацией всего этого, я готов выложить небольшую демонстрацию этого. Просто добавьте комментарий в этом случае.
Удачи!