我有一个简单的语法,允许用户定义一些带有属性的对象。 例如:
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
我该如何检查'我的第二个停车场'是否已经存在?
此外,我希望像color这样的属性是可选的,其他属性是强制性的,顺序不应该是重要的
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!
;
但是可能没有定义强制属性。 我可以添加一个额外的规则,如mandatoryattributedefinition,但很难允许任何顺序的定义
所以这种检查应该是解析器还是树解析器的一部分
答案 0 :(得分:1)
你可以在解析器语法中检查有效的超级公园(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
然后在遍历AST时向其添加String
s。然后当您偶然发现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;
// ...
}
然后检查每辆车是否已设置所有必需属性。
如果在尝试自己之后,你在实现这一切时遇到了麻烦,我愿意发布一个小演示。在这种情况下只需添加评论。
祝你好运!