private static void parseBinaryOp(ASTNode node, int[] ops, int associativity) { if (node is ASTNodeAbstractExpr) { ASTNodeAbstractExpr absNode = (ASTNodeAbstractExpr)node; ASTNodeAbstractExpr.Partition part = absNode.partition(ops, 0, absNode.content.Count); if (part.separators.Count == 0) { //no occurrences of op } else { ASTNodeBinaryOp binOp = new ASTNodeBinaryOp(); binOp.associativity = associativity; binOp.exprs = part.pieces; binOp.ops = part.separators; absNode.condense(binOp, 0, absNode.content.Count); } } for (IEnumerator e = node.getChildren().GetEnumerator(); e.MoveNext();) { parseBinaryOp((ASTNode)e.Current, ops, associativity); } }
//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); }
private static void parsePathExpr(ASTNode node) { if (node is ASTNodeAbstractExpr) { ASTNodeAbstractExpr absNode = (ASTNodeAbstractExpr)node; int[] pathOps = { Token.SLASH, Token.DBL_SLASH }; ASTNodeAbstractExpr.Partition part = absNode.partition(pathOps, 0, absNode.content.Count); if (part.separators.Count == 0) { //filter expression or standalone step if (isStep(absNode)) { ASTNodePathStep step = parseStep(absNode); ASTNodeLocPath path = new ASTNodeLocPath(); path.clauses.Add(step); absNode.condense(path, 0, absNode.content.Count); } else { //filter expr ASTNodeFilterExpr filt = parseFilterExp(absNode); if (filt != null) { absNode.condense(filt, 0, absNode.content.Count); } } } else { //path expression (but first clause may be filter expr) ASTNodeLocPath path = new ASTNodeLocPath(); path.separators = part.separators; if (part.separators.Count == 1 && absNode.content.Count == 1 && vectInt(part.separators, 0) == Token.SLASH) { //empty absolute path } else { for (int i = 0; i < part.pieces.Count; i++) { ASTNodeAbstractExpr x = (ASTNodeAbstractExpr)part.pieces[i]; if (isStep(x)) { ASTNodePathStep step = parseStep(x); path.clauses.Add(step); } else { if (i == 0) { if (x.content.Count == 0) { //absolute path expr; first clause is null /* do nothing */ } else { //filter expr ASTNodeFilterExpr filt = parseFilterExp(x); if (filt != null) { path.clauses.Add(filt); } else { path.clauses.Add(x); } } } else { throw new XPathSyntaxException(); } } } } absNode.condense(path, 0, absNode.content.Count); } } for (IEnumerator e = node.getChildren().GetEnumerator(); e.MoveNext();) { parsePathExpr((ASTNode)e.Current); } }