private AlignedExpressionTree decodeCfgParse(CfgParseTree t, int numAppliedArguments) {
    Preconditions.checkArgument(!t.getRoot().equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION));

    if (t.isTerminal()) {
      // Expression tree spans have an exclusive end index.
      int[] spanStarts = new int[] {t.getSpanStart()};
      int[] spanEnds = new int[] {t.getSpanEnd() + 1};
      List<String> words = Lists.newArrayList();
      for (Object o : t.getTerminalProductions()) {
        words.add((String) o);
      }
      ExpressionNode root = ((ExpressionNode) t.getRoot());
      return AlignedExpressionTree.forTerminal(root.getExpression(), root.getType(), 
          numAppliedArguments, spanStarts, spanEnds, words);
    } else {
      ExpressionNode parent = ((ExpressionNode) t.getRoot());
      ExpressionNode left = ((ExpressionNode) t.getLeft().getRoot());
      ExpressionNode right = ((ExpressionNode) t.getRight().getRoot());

      if (left.equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION)) {
        return decodeCfgParse(t.getRight(), numAppliedArguments);
      } else if (right.equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION)) {
        return decodeCfgParse(t.getLeft(), numAppliedArguments);
      } else {
        // A combination of expressions.
        CfgParseTree argTree = null;
        CfgParseTree funcTree = null;

        // The argument's expression node must have 0 applied arguments
        // while the function's node must have > 0.
        if (left.getNumAppliedArguments() == 0) {
          // Thing on the right is the function
          funcTree = t.getRight();
          argTree = t.getLeft();
        } else if (right.getNumAppliedArguments() == 0) {
          // Thing on the left is the function
          funcTree = t.getLeft();
          argTree = t.getRight();
        }

        Preconditions.checkState(funcTree != null && argTree!= null, "Tree is broken %s", t); 
        
        AlignedExpressionTree leftTree = decodeCfgParse(argTree, 0);
        AlignedExpressionTree rightTree = decodeCfgParse(funcTree, numAppliedArguments + 1);

        return AlignedExpressionTree.forNonterminal(parent.getExpression(), parent.getType(), 
            numAppliedArguments, leftTree, rightTree);
      }
    }
  }
private AlignedExpressionTree decodeCfgParse ( CfgParseTree t , int numAppliedArguments ) { Preconditions . checkArgument ( ! t . getRoot ( ) . equals ( ParametricCfgAlignmentModel . SKIP_EXPRESSION ) ) ; if ( t . isTerminal ( ) ) { int [ ] spanStarts = new int [ ] { t . getSpanStart ( ) } ; int [ ] spanEnds = new int [ ] { t . getSpanEnd ( ) + 1 } ; List < String > words = Lists . newArrayList ( ) ; for ( Object o : t . getTerminalProductions ( ) ) { words . add ( ( String ) o ) ; } ExpressionNode root = ( ( ExpressionNode ) t . getRoot ( ) ) ; return AlignedExpressionTree . forTerminal ( root . getExpression ( ) , root . getType ( ) , numAppliedArguments , spanStarts , spanEnds , words ) ; } else { ExpressionNode parent = ( ( ExpressionNode ) t . getRoot ( ) ) ; ExpressionNode left = ( ( ExpressionNode ) t . getLeft ( ) . getRoot ( ) ) ; ExpressionNode right = ( ( ExpressionNode ) t . getRight ( ) . getRoot ( ) ) ; if ( left . equals ( ParametricCfgAlignmentModel . SKIP_EXPRESSION ) ) { return decodeCfgParse ( t . getRight ( ) , numAppliedArguments ) ; } else if ( right . equals ( ParametricCfgAlignmentModel . SKIP_EXPRESSION ) ) { return decodeCfgParse ( t . getLeft ( ) , numAppliedArguments ) ; } else { CfgParseTree argTree = null ; CfgParseTree funcTree = null ; if ( left . getNumAppliedArguments ( ) == 0 ) { funcTree = t . getRight ( ) ; argTree = t . getLeft ( ) ; } else if ( right . getNumAppliedArguments ( ) == 0 ) { funcTree = t . getLeft ( ) ; argTree = t . getRight ( ) ; } Preconditions . checkState ( funcTree != null && argTree != null , "Tree is broken %s" , t ) ; AlignedExpressionTree leftTree = decodeCfgParse ( argTree , 0 ) ; AlignedExpressionTree rightTree = decodeCfgParse ( funcTree , numAppliedArguments + 1 ) ; return AlignedExpressionTree . forNonterminal ( parent . getExpression ( ) , parent . getType ( ) , numAppliedArguments , leftTree , rightTree ) ; } } }
Converts the CFG parse tree {@code t} into an {@code AlignedExpressionTree}.

@param t
@param numAppliedArguments
@return