ANTLR - проверять семантику / смысл значений - PullRequest
3 голосов
/ 06 сентября 2011

У меня есть простая грамматика, которая позволяет пользователю определять некоторые объекты с атрибутами.Например:

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!
    ;

Но тогда обязательные атрибуты не могут быть определены.Я мог бы добавить дополнительное правило, подобное обязательному определению атрибута, но тогда трудно разрешить определения в любом порядке

Так что, если этот вид проверки должен быть частью синтаксического анализатора или синтаксического анализатора дерева

1 Ответ

1 голос
/ 06 сентября 2011

Вы могли бы выполнять проверку действительных суперпарков (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;

  // ...
}

А затем проверьте, установлены ли для каждого транспортного средства все обязательные атрибуты.

Если, попробовав себя, у вас возникли проблемы с реализацией всего этого, я готов выложить небольшую демонстрацию этого. Просто добавьте комментарий в этом случае.

Удачи!

...