【问题标题】:How to set a String into newly created Context's children如何将字符串设置为新创建的上下文的孩子
【发布时间】:2019-01-31 19:04:29
【问题描述】:

我有一个解析器,它使用 XContext 调用 visitX 方法,其中包含解析为 ArrayNode 和 FunctionName 的表达式。我可以检索函数的对象,并希望为此数组中的每个元素调用它,但该函数需要一个 ExpressionVisitor 和一个 YContext。我可以创建一个新的 YContext(XContext) 并且孩子们按预期是空的。我需要将我的 array.get(i) 作为 TerminalNode 添加到 children 数组中,以便接收 YContext 的函数可以检查孩子的数量 (1),然后获取值(例如,ctx.exprValues().exprList() .expr(0)) 来自 YContext。

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。

【问题讨论】:

    标签: string antlr4 children


    【解决方案1】:

    解决方案很复杂,但根据表达式的定义方式是必要的。我跟踪了传递给函数的 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);
                }
    

    【讨论】:

      猜你喜欢
      • 2017-02-09
      • 1970-01-01
      • 2019-02-04
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      相关资源
      最近更新 更多