示例#1
0
 /*  63:    */
 /*  64:    */ public Type typeCheck(SymbolTable stable) /*  65:    */ throws TypeCheckError
       /*  66:    */ {
   /*  67:120 */ if (this._type != null) {
     /*  68:120 */ return this._type;
     /*  69:    */ }
   /*  70:123 */ if (this._variable.isLocal())
   /*  71:    */ {
     /*  72:124 */ SyntaxTreeNode node = getParent();
     /*  73:    */ do
     /*  74:    */ {
       /*  75:126 */ if ((node instanceof Closure))
       /*  76:    */ {
         /*  77:127 */ this._closure = ((Closure) node);
         /*  78:128 */ break;
         /*  79:    */ }
       /*  80:130 */ if ((node instanceof TopLevelElement)) {
         /*  81:    */ break;
         /*  82:    */ }
       /*  83:133 */ node = node.getParent();
       /*  84:134 */ } while (node != null);
     /*  85:136 */ if (this._closure != null) {
       /*  86:137 */ this._closure.addVariable(this);
       /*  87:    */ }
     /*  88:    */ }
   /*  89:142 */ this._type = this._variable.getType();
   /*  90:146 */ if (this._type == null)
   /*  91:    */ {
     /*  92:147 */ this._variable.typeCheck(stable);
     /*  93:148 */ this._type = this._variable.getType();
     /*  94:    */ }
   /*  95:152 */ addParentDependency();
   /*  96:    */
   /*  97:    */
   /*  98:155 */ return this._type;
   /*  99:    */ }
示例#2
0
文件: Predicate.java 项目: srnsw/xena
  /**
   * Type check a predicate expression. If the type of the expression is number convert it to
   * boolean by adding a comparison with position(). Note that if the expression is a parameter, we
   * cannot distinguish at compile time if its type is number or not. Hence, expressions of
   * reference type are always converted to booleans.
   *
   * <p>This method may be called twice, before and after calling <code>dontOptimize()</code>. If
   * so, the second time it should honor the new value of <code>_canOptimize</code>.
   */
  public Type typeCheck(SymbolTable stable) throws TypeCheckError {
    Type texp = _exp.typeCheck(stable);

    // We need explicit type information for reference types - no good!
    if (texp instanceof ReferenceType) {
      _exp = new CastExpr(_exp, texp = Type.Real);
    }

    // A result tree fragment should not be cast directly to a number type,
    // but rather to a boolean value, and then to a numer (0 or 1).
    // Ref. section 11.2 of the XSLT 1.0 spec
    if (texp instanceof ResultTreeType) {
      _exp = new CastExpr(_exp, Type.Boolean);
      _exp = new CastExpr(_exp, Type.Real);
      texp = _exp.typeCheck(stable);
    }

    // Numerical types will be converted to a position filter
    if (texp instanceof NumberType) {
      // Cast any numerical types to an integer
      if (texp instanceof IntType == false) {
        _exp = new CastExpr(_exp, Type.Int);
      }

      if (_canOptimize) {
        // Nth position optimization. Expression must not depend on context
        _nthPositionFilter = !_exp.hasLastCall() && !_exp.hasPositionCall();

        // _nthDescendant optimization - only if _nthPositionFilter is on
        if (_nthPositionFilter) {
          SyntaxTreeNode parent = getParent();
          _nthDescendant =
              (parent instanceof Step) && (parent.getParent() instanceof AbsoluteLocationPath);
          return _type = Type.NodeSet;
        }
      }

      // Reset optimization flags
      _nthPositionFilter = _nthDescendant = false;

      // Otherwise, expand [e] to [position() = e]
      final QName position = getParser().getQNameIgnoreDefaultNs("position");
      final PositionCall positionCall = new PositionCall(position);
      positionCall.setParser(getParser());
      positionCall.setParent(this);

      _exp = new EqualityExpr(Operators.EQ, positionCall, _exp);
      if (_exp.typeCheck(stable) != Type.Boolean) {
        _exp = new CastExpr(_exp, Type.Boolean);
      }
      return _type = Type.Boolean;
    } else {
      // All other types will be handled as boolean values
      if (texp instanceof BooleanType == false) {
        _exp = new CastExpr(_exp, Type.Boolean);
      }
      return _type = Type.Boolean;
    }
  }
示例#3
0
文件: Predicate.java 项目: srnsw/xena
 /** Returns a reference to its parent closure or null if outermost. */
 public Closure getParentClosure() {
   if (_parentClosure == null) {
     SyntaxTreeNode node = getParent();
     do {
       if (node instanceof Closure) {
         _parentClosure = (Closure) node;
         break;
       }
       if (node instanceof TopLevelElement) {
         break; // way up in the tree
       }
       node = node.getParent();
     } while (node != null);
   }
   return _parentClosure;
 }
示例#4
0
 public void createSyntaxTree(
     SyntaxTreeNode node, SyntaxTree tree, LinkedList<LinkedList<String>> partitions) {
   SyntaxTreeNode whenNode = new SyntaxTreeNode();
   node.addSuccessor(whenNode);
   pre.createSyntaxTree(whenNode, tree, partitions);
   eff.createSyntaxTree(whenNode, tree, partitions);
 }
示例#5
0
  /** Parse all direct children of the <xsl:stylesheet/> element. */
  public final void parseOwnChildren(Parser parser) {
    final SymbolTable stable = parser.getSymbolTable();
    final String excludePrefixes = getAttribute("exclude-result-prefixes");
    final String extensionPrefixes = getAttribute("extension-element-prefixes");

    // Exclude XSLT uri
    stable.pushExcludedNamespacesContext();
    stable.excludeURI(Constants.XSLT_URI);
    stable.excludeNamespaces(excludePrefixes);
    stable.excludeNamespaces(extensionPrefixes);

    final Vector contents = getContents();
    final int count = contents.size();

    // We have to scan the stylesheet element's top-level elements for
    // variables and/or parameters before we parse the other elements
    for (int i = 0; i < count; i++) {
      SyntaxTreeNode child = (SyntaxTreeNode) contents.elementAt(i);
      if ((child instanceof VariableBase) || (child instanceof NamespaceAlias)) {
        parser.getSymbolTable().setCurrentNode(child);
        child.parseContents(parser);
      }
    }

    // Now go through all the other top-level elements...
    for (int i = 0; i < count; i++) {
      SyntaxTreeNode child = (SyntaxTreeNode) contents.elementAt(i);
      if (!(child instanceof VariableBase) && !(child instanceof NamespaceAlias)) {
        parser.getSymbolTable().setCurrentNode(child);
        child.parseContents(parser);
      }

      // All template code should be compiled as methods if the
      // <xsl:apply-imports/> element was ever used in this stylesheet
      if (!_templateInlining && (child instanceof Template)) {
        Template template = (Template) child;
        String name = "template$dot$" + template.getPosition();
        template.setName(parser.getQName(name));
      }
    }

    stable.popExcludedNamespacesContext();
  }
示例#6
0
 /*  27:    */
 /*  28:    */ public void addParentDependency() /*  29:    */ {
   /*  30: 73 */ SyntaxTreeNode node = this;
   /*  31: 74 */ while ((node != null) && (!(node instanceof TopLevelElement))) {
     /*  32: 75 */ node = node.getParent();
     /*  33:    */ }
   /*  34: 78 */ TopLevelElement parent = (TopLevelElement) node;
   /*  35: 79 */ if (parent != null)
   /*  36:    */ {
     /*  37: 80 */ VariableBase var = this._variable;
     /*  38: 81 */ if (this._variable._ignore) {
       /*  39: 82 */ if ((this._variable instanceof Variable)) {
         /*  40: 83 */ var = parent.getSymbolTable().lookupVariable(this._variable._name);
         /*  41: 85 */ } else if ((this._variable instanceof Param)) {
         /*  42: 86 */ var = parent.getSymbolTable().lookupParam(this._variable._name);
         /*  43:    */ }
       /*  44:    */ }
     /*  45: 90 */ parent.addDependency(var);
     /*  46:    */ }
   /*  47:    */ }
示例#7
0
 /**
  * Adds a single prefix mapping to this syntax tree node.
  *
  * @param prefix Namespace prefix.
  * @param uri Namespace URI.
  */
 protected void addPrefixMapping(String prefix, String uri) {
   if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return;
   super.addPrefixMapping(prefix, uri);
 }
示例#8
0
 public void setParser(Parser parser) {
   super.setParser(parser);
   _name = makeStylesheetName("__stylesheet_");
 }
  public static List<TableSchemaAttributeDetail> resolve(
      SyntaxTreeListNode<SyntaxTreeNode> projectionList, TableSchema schema)
      throws SQLSemanticException {
    SyntaxTreeNode node = projectionList.getNode();
    List<TableSchemaAttributeDetail> result = new LinkedList<TableSchemaAttributeDetail>();
    if (node.getClass().equals(SyntaxTreeRenameNode.class)) { // Case 0 :: renamed aggregate
      SyntaxTreeRenameNode rdnode = (SyntaxTreeRenameNode) node;
      if (rdnode.getChild().getClass().equals(SyntaxTreeIdentifierNode.class)) {
        SyntaxTreeIdentifierNode inode = (SyntaxTreeIdentifierNode) rdnode.getChild();
        if (inode.generatingToken.tokenClass
            == SQLToken.SQLTokenClass
                .AGGREGATE) { // aggregates are not renamed in the projection, but in the
                              // aggregation
          int index = schema.indexOfAttributeName(rdnode.name, 0);
          result.add(schema.getAttributes().get(index));
        } else {
          throw new SQLSemanticException(
              SQLSemanticException.Type.InternalError); // only rename aggregates
        }
      } else {
        throw new SQLSemanticException(SQLSemanticException.Type.InternalError);
      }

    } else if (node.getClass()
        .equals(SyntaxTreeIdentifierNode.class)) { // Case 1 :: identifier or unnamed aggregate
      SyntaxTreeIdentifierNode idnode = (SyntaxTreeIdentifierNode) node;
      if (idnode.generatingToken.tokenClass
          == SQLToken.SQLTokenClass.STAR) { // Case 1a ::add all attributes from the child schema
        result = schema.getAttributes();

      } else if (idnode.generatingToken.tokenClass
          == SQLToken.SQLTokenClass
              .QSTARID) { // Case 1b :: add all attributes that have the right qualifier
        List<TableSchemaAttributeDetail> allAttributes = schema.getAttributes();
        String attributeQualifier = idnode.generatingToken.getQualifierForIdentifier();
        if (!schema.getQualifiers().contains(attributeQualifier)) {
          throw new SQLSemanticException(
              SQLSemanticException.Type.NoSuchTableException, attributeQualifier);
        }

        for (TableSchemaAttributeDetail attribute : allAttributes) {
          if (attribute.qualifier.equals(attributeQualifier)) {
            result.add(attribute);
          }
        }

      } else if (idnode.generatingToken.tokenClass
          == SQLToken.SQLTokenClass
              .QID) { // Case 1c :: add the first attribute that has the right name and right
                      // qualifier
        Pair<String, String> nameParts = idnode.generatingToken.getFragmentsForIdentifier();
        int currentIndex = schema.indexOfQualifiedAttributeName(nameParts.first, nameParts.second);
        if (currentIndex < 0)
          throw new SQLSemanticException(
              SQLSemanticException.Type.NoSuchAttributeException, nameParts.second);
        result.add(schema.getAttributes().get(currentIndex));

      } else if (idnode.generatingToken.tokenClass
          == SQLToken.SQLTokenClass
              .UID) { // Case 1d :: add the first attribute that has the right name
        Pair<String, String> nameParts = idnode.generatingToken.getFragmentsForIdentifier();
        int index = schema.indexOfAttributeName(nameParts.second, 0);
        if (index < 0)
          throw new SQLSemanticException(
              SQLSemanticException.Type.NoSuchAttributeException, nameParts.second);
        result.add(schema.getAttributes().get(index));

      } else {
        throw new SQLSemanticException(SQLSemanticException.Type.InternalError);
      }

    } else {
      throw new SQLSemanticException(SQLSemanticException.Type.InternalError);
    }

    if (projectionList.getNext() != null) { // recursively resolve rest of the list and append
      result.addAll(resolve(projectionList.getNext(), schema));
    }

    return result;
  }
  /**
   * Implementiert den LR-Parse-Algorithmus aus dem Drachenbuch (Algorithmus 4.30/ S. 302 in der 2.
   * deutschen Auflage). Erweitert um die Erzeugung des (vollständigen) Parsebaums und dessen
   * Reduzierung auf den Abstrakten Syntaxbaum. Erweitert um die Behandlung von ε-Übergängen
   * Speichert die gelesenen Token um sie mit den Terminalknoten zu verknüpfen. LR-Parse-Algorithmus
   * aus dem Drachenbuch : <code>
   * Eingabe: ein Eingabestring w und eine LR-Parsertabelle mit den Funtkionen ACTION und GOTO für eine Grammatik G
   * Ausgabe: wenn w in L(G) ist, die Reduzierungsschritte einer Bottom-Up-Analyse für w, andernfalls eine Fehlermeldung
   * Methode: Zunächst liegt s0, der Ausgangszustand, auf dem Stack und w$ befindet sich im Eingabepuffer. Dann führt der Parser das folgende Programm aus:
   *
   * Sei a das erste Symbol von w$;
   * while(1){
   * Sei s der oberste Zustand auf dem Stack;
   * if (ACTION[s,a] = shift t){
   * verschiebe t auf den Stack;
   * Sei a das nächste Eingabesymbol;
   * }
   * else if (ACTION[s,a] = reduce A → β){
   * Entferne |β| Symbole vom Stack;
   * Zustand t liegt jetzt oben auf dem Stack;
   * verschiebe GOTO[t,A] auf den Stack;
   * gib die Produktion A → β aus;
   * }
   * else if (ACTION[s,a] = accept){
   * break; // Analyse ist beendet
   * }
   * else{
   * Fehlerbehandlung aufrufen;
   * }
   * }
   * </code>
   *
   * @param lexer ILexer für die Eingabe
   * @param parseTable LR-Parsertabelle mit den Funtkionen ACTION und GOTO
   * @return den vollständigen (konkreten) Parsebaum
   * @throws LRParserException falls kein Parsebaum erzeugt werden konnte.
   */
  public ISyntaxTree parse(ILexer lexer, ParseTable parseTable) {

    Stack<IToken> tokenStack = new Stack<IToken>();
    Stack<SyntaxTreeNode> nodeStack = new Stack<SyntaxTreeNode>();
    Stack<State> stateStack = new Stack<State>();
    stateStack.push(parseTable.getInitialState());
    IToken currentToken = readNextToken(lexer);
    //		tokenStack.push(currentToken);
    TerminalSymbol currentTerminalSymbol = new TerminalSymbol(currentToken.getText());

    while (true) {
      State currentState = stateStack.peek();
      Action currentAction = parseTable.getAction(currentState, currentTerminalSymbol);
      // TODO printConfiguration():String und logConfiguration:boolean
      logger.finer(stateStack + " : " + currentToken + " : " + currentAction);
      if (currentAction instanceof ShiftAction) {
        State targetState = ((ShiftAction) currentAction).getTargetState();
        stateStack.push(targetState);
        tokenStack.push(currentToken);
        currentToken = readNextToken(lexer);
        currentTerminalSymbol = new TerminalSymbol(currentToken.getText());

      } else if (currentAction instanceof ReduceAction) {
        Production p = ((ReduceAction) currentAction).getProduction();
        for (int i = 0; i < p.getRhs().size(); i++) {
          stateStack.pop();
        }
        State s = stateStack.peek();
        State targetState = parseTable.getGoto(s, p.getLhs()).getTargetState();
        stateStack.push(targetState);

        // AST aufbauen
        // SyntaxTreeNode für das NonTerminalSymbol im Kopf der reduzierten Produktion anlegen
        SyntaxTreeNode currentNode = new SyntaxTreeNode(p.getLhs());
        for (int i = p.getRhs().size() - 1;
            i >= 0;
            i--) { // Für jedes Symbol im Rumpf der reduzierten Produktion (von rechts nach links)
          Symbol aSymbol = p.getRhs().get(i);
          // Zu jedem Symbol im Rumpf der reduzierten Produktion liegt der zugehörige Knoten (in
          // umgedrehter Reihenfolge - s.o.) auf dem Stack
          SyntaxTreeNode aChildNode = null;
          if (aSymbol instanceof TerminalSymbol) {
            // Für TerminalSymbol einen einfachen Knoten (Blatt) mit dem zugehörigen Token anlegen
            aChildNode = new SyntaxTreeNode(tokenStack.pop(), (TerminalSymbol) aSymbol);
          } else if (aSymbol instanceof NonTerminalSymbol) {
            // Knoten für NonTerminalSymbol vom Stack nehmen
            aChildNode = nodeStack.pop();
          }
          currentNode.insertTree(aChildNode);
        }
        // Neuen Knoten auf den Stack legen
        nodeStack.push(currentNode);
      } else if (currentAction instanceof AcceptAction) {
        logger.finer("Done.");
        // Wurzel des Parsebaums vom Stack holen
        SyntaxTreeNode syntaxTree = nodeStack.pop();
        return syntaxTree;
      } else if (currentAction instanceof ErrorAction) {
        // Zum aktuellen Eingabe-Token konnte keine gültige Action ermittelt werden
        // Daher wird jetzt erstmal versucht ob es eine Action für ε gibt.
        if (!(parseTable.getAction(currentState, Grammar.EPSILON) instanceof ErrorAction)) {
          // Es gibt eine Action für ε --> Aktuelles Eingabetoken zurückstellen
          // TODO Prüfen, ob dies die richtige Art und Weise ist um einen ε-Übergang herzustellen
          // (Der Syntaxbaum für ein einfaches Programm sah jedenfalls richtig aus...)
          storedToken = currentToken;
          currentToken = new EpsilonToken(currentToken.getLineNumber(), currentToken.getOffset());
          currentTerminalSymbol = Grammar.EPSILON;
          //					if (!tokenStack.isEmpty()){
          //						tokenStack.pop();
          //					}
          //					tokenStack.push(currentToken);
          continue;
        }

        logger.warning(
            "Parse Error: Unexpected Token "
                + currentToken.getText()
                + " in line "
                + currentToken.getLineNumber()
                + ":"
                + currentToken.getOffset());
        StringBuffer strBufPossibleTokens = new StringBuffer();
        int i = 0;
        for (TerminalSymbol t :
            parseTable.getActionTableForState(currentState).getAllLegalTerminals()) {
          if (i > 0) strBufPossibleTokens.append(", ");
          strBufPossibleTokens.append(t);
          i++;
        }
        logger.warning("Parse Error: Expected Tokens are: " + strBufPossibleTokens);
        throw new LRParserException(
            "Parse Error: Unexpected Token "
                + currentToken.getText()
                + " in line "
                + currentToken.getLineNumber()
                + ":"
                + currentToken.getOffset());
      }
    }
  }