예제 #1
0
  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");
    }
  }
예제 #2
0
 /**
  * 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));
      }
    }
  }