ExpTree.java :  » Parser » SJPT » ro » infoiasi » donald » compiler » lexer » Java Open Source

Java Open Source » Parser » SJPT 
SJPT » ro » infoiasi » donald » compiler » lexer » ExpTree.java
package ro.infoiasi.donald.compiler.lexer;

import ro.infoiasi.donald.compiler.lexer.exceptions.*;
import ro.infoiasi.donald.compiler.simple.*;
import java.util.*;

public class ExpTree extends BinTree {  
  private Alphabet alpha = new Alphabet();

  public ExpTree() {
    super();
  }

  public ExpTree(ExpList el) throws ExpParseError {
    super();
    alpha = el.getAlphabet();
    addRootSubTree(create(el));
  }

  private static ExpTree create(AbstractList el) throws ExpParseError {
    el = removeParenthesis(el);
    ExpTree et = new ExpTree();
    if (!el.isEmpty()) {
      OperatorToken minOpToken = null;
      int minI = 0;
      for (int i = 0; i<el.size(); i++) {
        Class c = el.get(i).getClass();
        if (c == OperatorToken.class) {
          OperatorToken opToken = (OperatorToken)el.get(i);
          if (minOpToken == null ||
              (minOpToken.compareTo(opToken)>0)) {
            minOpToken = opToken;
            minI = i;
          }
        } else if (c == ParenthesisLeft.class) {
          // skip paranthesis
          ParenthesisLeft paraLeft = (ParenthesisLeft)el.get(i);
          ParenthesisRight paraRight = paraLeft.pair();
          i += paraRight.tokenNo() - paraLeft.tokenNo();
        }
      }
      //System.out.println("[["+minI+"]]");
      if (minOpToken == null) {
        if (el.size()>1 || el.get(0).getClass() != SymbolToken.class) {
          throw new ExpParseError("No operator found",
            ((ExpToken)el.get(0)).strIndex(),
            ((ExpToken)el.get(el.size()-1)).strIndex());
        } else {
          et.addRoot(el.get(0));
        }
      } else {
        et.addRoot(minOpToken);
        if (minOpToken.operator().isUnaryLeft()) {
          if (minI != el.size()-1) {
            throw new ExpParseError("Operator is unary and binds to the left only",
              minOpToken.strIndex());
          }
          ExpTree et1 = create((AbstractList)(el.subList(0,minI)));
          if (et1.IsEmpty()) {
            throw new ExpParseError("Operator is unary and binds to the left only",
              minOpToken.strIndex());
          }
          et.addLeftSubTree(et1, et.root());
        } else if (minOpToken.operator().isUnaryRight()) {

        } else if (minOpToken.operator().isBinary()) {
          ExpTree et1 = create((AbstractList)(el.subList(0,minI)));
          ExpTree et2 = create((AbstractList)(el.subList(minI+1,el.size())));
          if (et1.IsEmpty() || et2.IsEmpty()) {
            //??? I still have some doubts - the | operator allows an empty operand
            throw new ExpParseError("Operator is binary", minOpToken.strIndex());
          }
          et.addLeftSubTree(et1, et.root());
          et.addRightSubTree(et2, et.root());
        } else {
          throw new ExpParseError("Operator is not unary or binary",
            ((ExpToken)el.get(0)).strIndex());
        }
      }
    }
    return et;
  }

  private static AbstractList removeParenthesis(AbstractList el) {
    boolean over = false;
    while (!el.isEmpty() && !over) {
      over = true;
      if (el.get(0).getClass() == ParenthesisLeft.class &&
          el.get(el.size()-1).getClass() == ParenthesisRight.class) {
        ParenthesisLeft paraLeft = (ParenthesisLeft)el.get(0);
        ParenthesisRight paraRight = (ParenthesisRight)el.get(el.size()-1);
        if (paraLeft.pair() == paraRight) {
          el = (AbstractList)el.subList(1,el.size()-1);
          over = false;
        }
      }
    }
    return el;
  }

  public Alphabet getAlphabet() {
    return alpha;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.