java - 如何在我的 antlr4 语法中实现将写入域但不耦合域服务的方法?
问题描述
我已经为我的域生成了一个 DSL。我已经实现了我的DSL的所有读取访问方法,现在我正在考虑如何解决写入方法。也许有人可以给我一个很好的建议。
为了能够实现和测试我的 DSL,我选择使用一个接口来处理所有数据访问。在我的测试中,我可以模拟和填充这些数据集合,稍后当我将 DSL 集成到一些域服务中时,这些集合将填充真实数据。对于阅读访问,这很好用。但是我怎样才能解决写访问。我当前的实现没有与可以写入数据的服务耦合。所以我想我可以收集所有的写作对象,我的 dsl 的调用者将检索这个集合并进行写作。如何用我的语法返回这样的集合,目前我只返回真或假。也许有更好的方法,但我不想在我的 DSL 实现中包含编写服务。
这是我的语法的一部分, setCommand 和 setIfCommand 尚未正确实现
grammar EXPRESS;
prog: expr+ EOF;
expr:
statement #StatementExpr
|NOT expr #NotExpr
| expr AND expr #AndExpr
| expr (OR | XOR) expr #OrExpr
| function #FunctionExpr
| LPAREN expr RPAREN #ParenExpr
| writeCommand #WriteExpr
;
writeCommand: setCommand | setIfCommand;
statement: ID '=' getCommand NEWLINE #Assign;
setCommand: 'set' LPAREN variable = variableType '|' value = parameter RPAREN;
setIfCommand: 'setIf' LPAREN variableType '|' expr '?' p1 = parameter ':' p2 = parameter RPAREN;
这是我的访客的一部分
@Override
public Value visitSetCommand(FELParser.SetCommandContext ctx) {
//'set' LPAREN variable = variableType '|' value = parameter RPAREN SEMI;
Value variable = this.visit(ctx.variableType());
Value newValue = this.visit(ctx.parameter());
memory.put(variable.asString(), newValue);
return Value.TRUE;
}
@Override
public Value visitSetIfCommand(FELParser.SetIfCommandContext ctx) {
//'setIf' LPAREN variableType '|' expr '?' p1 = parameter ':' p2 =
parameter RPAREN SEMI;
Value variable = this.visit(ctx.variableType());
Value expression = this.visit(ctx.expr());
Value trueValue = this.visit(ctx.p1);
Value falseValue = this.visit(ctx.p2);
if (expression.asBoolean()){
memory.put(variable.asString(), new Value(trueValue));
}
else{
memory.put(variable.asString(), new Value(falseValue));
}
return Value.TRUE;
}
这里有一个测试用例
@Test
public void whenSetCommand_ThenTrueAndValueInBuffer() {
String expression = "set(buffer, foo|bar) isSet(buffer,foo)";
ParseTree tree = getParseTree(expression);
Mockito.when(data.getFieldValues()).thenReturn(fieldValues);
Value answer = new FELCustomVisitor(data).visit(tree);
assertThat(answer.asBoolean()).isTrue();
}
public void beforeEach(){
data = initPDIXDataMock();
Mockito.when(data.getFieldValues()).thenReturn(new HashMap<>());
Mockito.when(data.getFormAttachments()).thenReturn(new HashMap<>());
Mockito.when(data.getInstanceAttachments()).thenReturn(new HashMap<>());
Mockito.when(data.getMandatorAttachments()).thenReturn(new HashMap<>());
Mockito.when(data.getFormAttributes()).thenReturn(new HashMap<>());
Mockito.when(data.getInstanceAttributes()).thenReturn(new HashMap<>());
Mockito.when(data.getMandatorAttributes()).thenReturn(new HashMap<>());
}
一个想法是将它添加到返回对象中,在我的例子中是值。在那里,我可以添加需要由我的 DSL 的调用服务处理的方法列表。这是我的价值对象
public class Value {
public static final Value TRUE = new Value(true);
public static final Value FALSE = new Value(false);
public static final Value NULL = new Value(null);
private final Object value;
public Value(Object value) {
this.value = value;
}
public Boolean asBoolean() {
return (Boolean) this.value;
}
public String asString(){
return (String) this.value;
}
public double asDouble(){
return Double.parseDouble(asString());
}
@Override
public String toString() {
return String.format("Value{type: %s, value: %s}",
this.value == null ? "null" : this.value.getClass().getSimpleName(), this.value);
}
public PDIXAttribute asAttribute() {
return (PDIXAttribute) this.value;
}
public PDIXAttachments asAttachment() {
return (PDIXAttachments) this.value;
}
解决方案
推荐阅读
- apache-spark-sql - 在 snappy 工作中随机获取 java.lang.ClassCastException
- mocha.js - 如何使用赛普拉斯提取和检查日期更改?
- excel - 按日期复制和粘贴数据 - excel vba
- typescript - Vue.js - Typescript:对象文字中的预期方法简写
- sql - Mandt 多次指定但不在查询中
- r - 如何比较多行中的两列
- c# - 使用 C# 将大 Excel 表存储到数组中
- c++ - 不同命名空间中类的前向声明
- clips - defrule 永远不会出现在议程中| 剪辑
- asp.net - Azure 错误进程“msbuild.exe”以代码“1”退出