3

我有一个简单的语法,它允许用户定义一些带有属性的对象。例如:

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

但是可能没有定义强制属性。我可以添加一个额外的规则,比如强制属性定义,但是很难以任何顺序允许定义

那么这种检查应该是解析器还是树解析器的一部分

4

1 回答 1

1

可以extends ...在解析器语法中检查有效的超级公园(

你可以做的是创建一个Set<String> parks作为你的 tree walker 的成员:

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遍历 AST 时将 s 添加到其中。然后,当 extends VALUE您偶然发现一个. 如果不是,则抛出异常。VALUE.textSet<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 ... )
  ;

aVehicle可能看起来像:

abstract class Vehicle {

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

  // ...
}

然后检查是否为每辆车设置了所有强制属性。

如果在尝试自己之后,你在实现这一切时遇到了困难,我愿意发布一个小演示。在这种情况下只需添加评论。

祝你好运!

于 2011-09-06T09:28:12.930 回答