我有一个解析器,该解析器使用XContext调用visitX方法,该XContext包含解析为ArrayNode和FunctionName的表达式。我可以检索该函数的对象,并希望为此数组中的每个元素调用此函数的调用,但是该函数需要一个ExpressionVisitor和一个YContext。我可以创建一个新的YContext(XContext),并且子级为空。我需要将我的array.get(i)作为TerminalNode添加到children数组中,以便接收YContext的函数可以检查child的数量(1),然后获取值(例如ctx.exprValues()。exprList() .expr(0))。
TerminalNodeImpl可以使用Token(这是一个接口),但我还没有找到使用可以采用JsonNode值(例如String,int,Object)的实现类来创建Token的方法。
YContext子级是一个List,但是我不确定是什么实现了可以使用JsonNode值构造的ParseTree。
我尝试使用这样的代码解析JsonNode值,但是我无法在令牌中得到任何可以在我的新上下文中使用addAnyChild的东西...
for (int i=0;i<mapArray.size();i++) {
ANTLRInputStream input = new ANTLRInputStream(mapArray.get(i).asText());
MappingExpressionLexer lexer = new MappingExpressionLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
我确信我忽略了一些简单的事情。在其他情况下,我已经可以将值压入堆栈,但是在这种情况下,我可以调用的所有函数都使用YContext,因此我需要以某种方式将值放入YContext.children。
答案 0 :(得分:0)
该解决方案很复杂,但根据表达式的定义方式是必需的。我跟踪了传递给该函数的ctx,以便了解其结构:
Function_callContext:
---------------------
TerminalNodeImpl $string 44 '$string'
ExprValuesContext
TerminalNodeImpl ( 2 '('
ExpressionListContext
NumberContext
TerminalNodeImpl 1 22 '1'
TerminalNodeImpl ) 3 ')'
TerminalNodeImpl $string 44 '$string'
Because the parser is looking for:
expr :
...
| VAR_ID exprValues # function_call
...
;
...
exprList : expr (',' expr)* ;
exprValues : '(' exprList ')' ;
VAR_ID : '$' ID ;
ID : [a-zA-Z] [a-zA-Z0-9_]*;
,我找到了CommonTokenFactory,让我创建可以放在TerminalNodeImpl中的令牌,以便建立正确的上下文。
这是代码(我现在只实现了NUMBER,但稍后会添加异常和其他类型...我的测试是使用$ map([1 .. 5],$ string)示例(其中[1..5]是成为数组的序列。
for (int i = 0; i < mapArray.size(); i++) {
Function_callContext callCtx = new Function_callContext(ctx);
// note: callCtx.children should be empty unless carrying an
// exception
ExprListContext elc = new ExprListContext(callCtx.getParent(),callCtx.invokingState);
ExprValuesContext evc = new ExprValuesContext(callCtx.getParent(),callCtx.invokingState);
evc.addAnyChild(new TerminalNodeImpl(CommonTokenFactory.DEFAULT.create(MappingExpressionParser.T__1,"(")));
CommonToken token = null;
JsonNode element = mapArray.get(i);
switch (element.getNodeType()) {
case ARRAY: {
break;
}
case BINARY:
break;
case BOOLEAN:
break;
case MISSING:
break;
case NULL:
break;
case NUMBER:
token = CommonTokenFactory.DEFAULT.create(MappingExpressionParser.NUMBER,element.asText());
TerminalNodeImpl tn = new TerminalNodeImpl(token);
NumberContext nc = new NumberContext(callCtx);
nc.addAnyChild(tn);
elc.addAnyChild(nc);
evc.addAnyChild(elc);
break;
case OBJECT:
break;
case POJO:
break;
case STRING:
break;
default:
break;
}
evc.addAnyChild(new TerminalNodeImpl(CommonTokenFactory.DEFAULT.create(MappingExpressionParser.T__1,")")));
callCtx.addAnyChild(var);
callCtx.addAnyChild(evc);
result = function.invoke(this, callCtx);
resultArray.add(result);
}