public void parseContents(Parser parser) { _select = parser.parseExpression(this, "select", null); parseChildren(parser); // make sure required attribute(s) have been set if (_select.isDummy()) { reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "select"); } }
/** * When the name of this ParserExtension is encountered by a parser with which the extension is * registered, the parser calls this routine to parse the summation subexpression. The * subexpression has the form (<variable>,<lower-limit>,<upper-limit>,<expression>). This method * is not meant to be called directly */ public void doParse(Parser parser, ParserContext context) { int tok = context.next(); String open = context.tokenString; if (tok == ParserContext.OPCHARS && (open.equals("(") || (open.equals("[") && (context.options & Parser.BRACKETS) != 0) || (open.equals("{") && (context.options & Parser.BRACES) != 0))) { String close = open.equals("(") ? ")" : (open.equals("[") ? "]" : "}"); tok = context.next(); // Must be an identifier. if (tok != ParserContext.IDENTIFIER) throw new ParseError( "Expected the summation variable as the first argument of " + name + ".", context); String varName = context.tokenString; tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the index variable, " + varName + ".", context); parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the lower limit expression for " + name + ".", context); parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(",")) throw new ParseError( "Exprected a comma after the upper limit expression for " + name + ".", context); Variable v = new Variable(varName); context.mark(); // Temporoarily add the summation variable to the symbol table. context.add(v); ExpressionProgram saveProg = context.prog; context.prog = new ExpressionProgram(); // Compile the expression into a new program. parser.parseExpression(context); tok = context.next(); if (tok != ParserContext.OPCHARS || !context.tokenString.equals(close)) throw new ParseError( "Expected a \"" + close + "\" at the end of the paramter list for " + name + ".", context); context.revert(); // Restore the state of the ParserContext. saveProg.addCommandObject(new Cmd(v, context.prog)); context.prog = saveProg; } else throw new ParseError("Parentheses required around parameters of summation.", context); } // end doParse()
/** Parse the attributes of the xsl:sort element */ public void parseContents(Parser parser) { final SyntaxTreeNode parent = getParent(); if (!(parent instanceof ApplyTemplates) && !(parent instanceof ForEach)) { reportError(this, parser, ErrorMsg.STRAY_SORT_ERR, null); return; } // Parse the select expression (node string value if no expression) _select = parser.parseExpression(this, "select", "string(.)"); // Get the sort order; default is 'ascending' String val = getAttribute("order"); if (val.length() == 0) val = "ascending"; _order = AttributeValue.create(this, val, parser); // Get the sort data type; default is text val = getAttribute("data-type"); if (val.length() == 0) { try { final Type type = _select.typeCheck(parser.getSymbolTable()); if (type instanceof IntType) val = "number"; else val = "text"; } catch (TypeCheckError e) { val = "text"; } } _dataType = AttributeValue.create(this, val, parser); _lang = getAttribute("lang"); // bug! see 26869 // val = getAttribute("lang"); // _lang = AttributeValue.create(this, val, parser); // Get the case order; default is language dependant val = getAttribute("case-order"); _caseOrder = AttributeValue.create(this, val, parser); }
/** * Two-pass parsing of ATVs. In the first pass, double curly braces are replaced by one, and * expressions are delimited using DELIMITER. The second pass splits up the resulting buffer into * literal and non-literal expressions. Errors are reported during the first pass. */ private void parseAVTemplate(String text, Parser parser) { StringTokenizer tokenizer = new StringTokenizer(text, "{}\"\'", true); /* * First pass: replace double curly braces and delimit expressions * Simple automaton to parse ATVs, delimit expressions and report * errors. */ String t = null; String lookahead = null; StringBuffer buffer = new StringBuffer(); int state = OUT_EXPR; while (tokenizer.hasMoreTokens()) { // Use lookahead if available if (lookahead != null) { t = lookahead; lookahead = null; } else { t = tokenizer.nextToken(); } if (t.length() == 1) { switch (t.charAt(0)) { case '{': switch (state) { case OUT_EXPR: lookahead = tokenizer.nextToken(); if (lookahead.equals("{")) { buffer.append(lookahead); // replace {{ by { lookahead = null; } else { buffer.append(DELIMITER); state = IN_EXPR; } break; case IN_EXPR: case IN_EXPR_SQUOTES: case IN_EXPR_DQUOTES: reportError(getParent(), parser, ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); break; } break; case '}': switch (state) { case OUT_EXPR: lookahead = tokenizer.nextToken(); if (lookahead.equals("}")) { buffer.append(lookahead); // replace }} by } lookahead = null; } else { reportError(getParent(), parser, ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); } break; case IN_EXPR: buffer.append(DELIMITER); state = OUT_EXPR; break; case IN_EXPR_SQUOTES: case IN_EXPR_DQUOTES: buffer.append(t); break; } break; case '\'': switch (state) { case IN_EXPR: state = IN_EXPR_SQUOTES; break; case IN_EXPR_SQUOTES: state = IN_EXPR; break; case OUT_EXPR: case IN_EXPR_DQUOTES: break; } buffer.append(t); break; case '\"': switch (state) { case IN_EXPR: state = IN_EXPR_DQUOTES; break; case IN_EXPR_DQUOTES: state = IN_EXPR; break; case OUT_EXPR: case IN_EXPR_SQUOTES: break; } buffer.append(t); break; default: buffer.append(t); break; } } else { buffer.append(t); } } // Must be in OUT_EXPR at the end of parsing if (state != OUT_EXPR) { reportError(getParent(), parser, ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text); } /* * Second pass: split up buffer into literal and non-literal expressions. */ tokenizer = new StringTokenizer(buffer.toString(), DELIMITER, true); while (tokenizer.hasMoreTokens()) { t = tokenizer.nextToken(); if (t.equals(DELIMITER)) { addElement(parser.parseExpression(this, tokenizer.nextToken())); tokenizer.nextToken(); // consume other delimiter } else { addElement(new LiteralExpr(t)); } } }