private static void parseBalanced(ASTNode node, SubNodeFactory snf, int lToken, int rToken) { if (node is ASTNodeAbstractExpr) { ASTNodeAbstractExpr absNode = (ASTNodeAbstractExpr)node; int i = 0; while (i < absNode.content.Count) { int type = absNode.getTokenType(i); if (type == rToken) { throw new XPathSyntaxException(); //unbalanced } else if (type == lToken) { int j = absNode.indexOfBalanced(i, rToken, lToken, rToken); if (j == -1) { throw new XPathSyntaxException(); //mismatched } absNode.condense(snf.newNode(absNode.extract(i + 1, j)), i, j + 1); } i++; } } for (IEnumerator e = node.getChildren().GetEnumerator(); e.MoveNext();) { parseBalanced((ASTNode)e.Current, snf, lToken, rToken); } }
//i == index of token beginning func call (func name) private static void condenseFuncCall(ASTNodeAbstractExpr node, int funcStart) { ASTNodeFunctionCall funcCall = new ASTNodeFunctionCall((XPathQName)node.getToken(funcStart).val); int funcEnd = node.indexOfBalanced(funcStart + 1, Token.RPAREN, Token.LPAREN, Token.RPAREN); if (funcEnd == -1) { throw new XPathSyntaxException(); //mismatched parens } ASTNodeAbstractExpr.Partition args = node.partitionBalanced(Token.COMMA, funcStart + 1, Token.LPAREN, Token.RPAREN); if (args.pieces.Count == 1 && ((ASTNodeAbstractExpr)args.pieces[0]).content.Count == 0) { //no arguments } else { //process arguments funcCall.args = args.pieces; } node.condense(funcCall, funcStart, funcEnd + 1); }