ANTLR - Проверьте семантику/значение значений
-
26-10-2019 - |
Вопрос
У меня есть простая грамматика, которая позволяет пользователю определять некоторые объекты с помощью атрибутов. Например:
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
Как мне проверить, существует ли уже «моя вторая парковка»?
Кроме того, я хочу, чтобы некоторые атрибуты, такие как цвет, были необязательными, другие обязательны, а порядок не должен быть важен
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!
;
Но тогда обязательные атрибуты не могут быть определены. Я мог бы добавить дополнительное правило, такое как AdbatoryAtttributeDefinition, но тогда трудно разрешить определения в любом порядке
Так должно быть такова, что будет частью анализатора или анализатора дерева
Решение
Ты мог Проверка действительных супер-парков (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;
// ...
}
И затем проверьте, если бы были установлены все обязательные атрибуты.
Если после того, как вы попробовали себя, у вас возникнут проблемы с реализацией всего этого, я готов опубликовать небольшую демонстрацию этого. Просто добавьте комментарий в этом случае.
Удачи!