home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 139 / dpcs0999.iso / Web / CFserver / data1.cab / Java / CFJava.cab / CFJavaRuntime.cab / allaire / util / template / ExpressionParser.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-03-31  |  6.5 KB  |  310 lines

  1. package allaire.util.template;
  2.  
  3. import allaire.util.TypeConversionException;
  4. import allaire.util.TypelessValue;
  5. import netscape.util.Enumeration;
  6. import netscape.util.Hashtable;
  7. import netscape.util.Vector;
  8.  
  9. public class ExpressionParser {
  10.    protected TemplateRuntimeContext m_runtimeContext;
  11.    private Hashtable m_functionLibs = new Hashtable();
  12.    private static FunctionLibrary m_libString = new StringFunctionLibrary();
  13.    private static FunctionLibrary m_libRuntime = new RuntimeFunctionLibrary();
  14.  
  15.    public void removeAllFunctionLibraries() {
  16.       this.m_functionLibs.clear();
  17.    }
  18.  
  19.    public String resolveExpression(String var1) throws ExpressionException {
  20.       ExpressionLexer var2 = new ExpressionLexer(var1);
  21.  
  22.       try {
  23.          TypelessValue var3 = this.expression(var2);
  24.          if (var2.lookAhead().getType() != -1) {
  25.             throw new ExpressionException(100, "Unexpected token '" + var2.lookAhead().getValue().asString() + "' found at the end of the expression.");
  26.          } else {
  27.             return var3.asString();
  28.          }
  29.       } catch (ExpressionException var5) {
  30.          ((TemplateException)var5).addDiagnostics("Expression: " + var1);
  31.          throw var5;
  32.       }
  33.    }
  34.  
  35.    private TypelessValue comparison(ExpressionLexer var1) throws ExpressionException {
  36.       TypelessValue var2 = this.additive(var1);
  37.  
  38.       while(true) {
  39.          int var3 = var1.lookAhead().getType();
  40.          switch (var3) {
  41.             case 1:
  42.             case 2:
  43.             case 3:
  44.             case 4:
  45.             case 5:
  46.             case 6:
  47.                var1.read();
  48.                TypelessValue var5 = this.additive(var1);
  49.  
  50.                int var4;
  51.                try {
  52.                   var4 = var2.compareTo(var5);
  53.                } catch (TypeConversionException var6) {
  54.                   throw new ExpressionException(105, "Illegal attempt to compare the values '" + var2.asString() + "' and '" + var5.asString() + "' (their types are incompatible).");
  55.                }
  56.  
  57.                boolean var7;
  58.                switch (var3) {
  59.                   case 1:
  60.                      var7 = var4 < 0;
  61.                      break;
  62.                   case 2:
  63.                      var7 = var4 <= 0;
  64.                      break;
  65.                   case 3:
  66.                      var7 = var4 > 0;
  67.                      break;
  68.                   case 4:
  69.                      var7 = var4 >= 0;
  70.                      break;
  71.                   case 5:
  72.                      var7 = var4 == 0;
  73.                      break;
  74.                   case 6:
  75.                      var7 = var4 != 0;
  76.                      break;
  77.                   default:
  78.                      var7 = false;
  79.                }
  80.  
  81.                var2 = new TypelessValue(var7);
  82.                break;
  83.             default:
  84.                return var2;
  85.          }
  86.       }
  87.    }
  88.  
  89.    private void arglist(String var1, ExpressionLexer var2, Vector var3) throws ExpressionException {
  90.       for(int var4 = var2.lookAhead().getType(); var4 != 41 && var4 != -1; var4 = var2.lookAhead().getType()) {
  91.          var3.addElement(this.expression(var2));
  92.          if (var2.lookAhead().getType() != 41) {
  93.             if (var2.lookAhead().getType() != 44) {
  94.                throw new ExpressionException(103, "Expected comma (,) was not found in call" + " to function '" + var1 + "'.");
  95.             }
  96.  
  97.             var2.read();
  98.          }
  99.       }
  100.  
  101.    }
  102.  
  103.    private TypelessValue logicalNOT(ExpressionLexer var1) throws ExpressionException {
  104.       boolean var2 = false;
  105.  
  106.       while(var1.lookAhead().getType() == 9) {
  107.          var2 = !var2;
  108.          var1.read();
  109.       }
  110.  
  111.       TypelessValue var3 = this.comparison(var1);
  112.       if (var2) {
  113.          double var4 = this.convertToNumber(var3);
  114.          boolean var6 = TypelessValue.numberToBoolean(var4);
  115.          var3 = new TypelessValue(!var6);
  116.       }
  117.  
  118.       return var3;
  119.    }
  120.  
  121.    private TypelessValue logicalAND(ExpressionLexer var1) throws ExpressionException {
  122.       TypelessValue var2;
  123.       boolean var4;
  124.       for(var2 = this.logicalNOT(var1); var1.lookAhead().getType() == 7; var2 = new TypelessValue(var4)) {
  125.          var1.read();
  126.          TypelessValue var3 = this.logicalNOT(var1);
  127.  
  128.          try {
  129.             var4 = var2.asBoolean() && var3.asBoolean();
  130.          } catch (TypeConversionException var5) {
  131.             throw new ExpressionException(105, "Illegal attempt to convert the values '" + var2.asString() + "' and '" + var3.asString() + "' to boolean. One of " + "these values is not a valid boolean.");
  132.          }
  133.       }
  134.  
  135.       return var2;
  136.    }
  137.  
  138.    protected TypelessValue callFunction(String var1, Vector var2) throws ExpressionException {
  139.       Enumeration var3 = this.m_functionLibs.elements();
  140.  
  141.       while(var3.hasMoreElements()) {
  142.          FunctionLibrary var4 = (FunctionLibrary)var3.nextElement();
  143.          Function var5 = var4.lookupFunction(var1);
  144.          if (var5 != null) {
  145.             return var5.call(this.m_runtimeContext, var2);
  146.          }
  147.       }
  148.  
  149.       throw new ExpressionException(101, "The function named '" + var1 + "' was not found.");
  150.    }
  151.  
  152.    public void removeFunctionLibrary(String var1) {
  153.       this.m_functionLibs.remove(var1.toUpperCase());
  154.    }
  155.  
  156.    private TypelessValue expression(ExpressionLexer var1) throws ExpressionException {
  157.       TypelessValue var2;
  158.       String var3;
  159.       for(var2 = this.logicalOR(var1); var1.lookAhead().getType() == 38; var2 = new TypelessValue(var3)) {
  160.          var1.read();
  161.          var3 = var2.asString().concat(this.logicalOR(var1).asString());
  162.       }
  163.  
  164.       return var2;
  165.    }
  166.  
  167.    public ExpressionParser(TemplateRuntimeContext var1) {
  168.       this.m_runtimeContext = var1;
  169.       this.addFunctionLibrary(m_libRuntime);
  170.       this.addFunctionLibrary(m_libString);
  171.    }
  172.  
  173.    private double convertToNumber(TypelessValue var1) throws ExpressionException {
  174.       try {
  175.          return var1.asReal();
  176.       } catch (TypeConversionException var2) {
  177.          throw new ExpressionException(105, "Error attempting to convert the value '" + var1.asString() + "' to a number");
  178.       }
  179.    }
  180.  
  181.    public void addFunctionLibrary(FunctionLibrary var1) {
  182.       this.m_functionLibs.put(var1.getName().toUpperCase(), var1);
  183.    }
  184.  
  185.    private TypelessValue primary(ExpressionLexer var1) throws ExpressionException {
  186.       Token var2 = var1.lookAhead();
  187.       switch (var2.getType()) {
  188.          case -1:
  189.             throw new ExpressionException(102, "Expression is incomplete (check for unmatched parentheses).");
  190.          case 10:
  191.             TypelessValue var3 = var1.read().getValue();
  192.             if (var1.lookAhead().getType() == 40) {
  193.                var1.read();
  194.                Vector var9 = new Vector();
  195.                this.arglist(var3.asString(), var1, var9);
  196.                if (var1.lookAhead().getType() != 41) {
  197.                   throw new ExpressionException(102, "Expected end parentheses ')' was not found for " + "function '" + var3.asString() + "'.");
  198.                }
  199.  
  200.                var1.read();
  201.                return this.callFunction(var3.asString(), var9);
  202.             } else {
  203.                try {
  204.                   return new TypelessValue(this.m_runtimeContext.getSymbolTable().getStringRequired(var3.asString()));
  205.                } catch (SymbolTableException var7) {
  206.                   throw new ExpressionException(((TemplateException)var7).getErrorNumber(), (String)((TemplateException)var7).getDiagnostics().firstElement());
  207.                }
  208.             }
  209.          case 11:
  210.             StringBuffer var8 = new StringBuffer();
  211.             var8.append(var1.read().getValue().asString());
  212.  
  213.             while(var1.lookAhead().getType() == 11) {
  214.                Token var5 = var1.read();
  215.                var8.append(var5.getQuoteChar());
  216.                var8.append(var5.getValue().asString());
  217.             }
  218.  
  219.             return new TypelessValue(new String(var8));
  220.          case 12:
  221.             return var1.read().getValue();
  222.          case 40:
  223.             var1.read();
  224.             TypelessValue var4 = this.expression(var1);
  225.             if (var1.lookAhead().getType() != 41) {
  226.                throw new ExpressionException(102, "Expected end parentheses ')' was not found.");
  227.             }
  228.  
  229.             var1.read();
  230.             return var4;
  231.          case 43:
  232.             var1.read();
  233.             return new TypelessValue(this.convertToNumber(this.primary(var1)));
  234.          case 45:
  235.             var1.read();
  236.             return new TypelessValue(-this.convertToNumber(this.primary(var1)));
  237.          default:
  238.             String var10 = String.valueOf((char)var2.getType());
  239.             throw new ExpressionException(100, "Unexpected token '" + var10 + "' found while parsing expression.");
  240.       }
  241.    }
  242.  
  243.    private TypelessValue logicalOR(ExpressionLexer var1) throws ExpressionException {
  244.       TypelessValue var2;
  245.       boolean var4;
  246.       for(var2 = this.logicalAND(var1); var1.lookAhead().getType() == 8; var2 = new TypelessValue(var4)) {
  247.          var1.read();
  248.          TypelessValue var3 = this.logicalAND(var1);
  249.  
  250.          try {
  251.             var4 = var2.asBoolean() || var3.asBoolean();
  252.          } catch (TypeConversionException var5) {
  253.             throw new ExpressionException(105, "Illegal attempt to convert the values '" + var2.asString() + "' and '" + var3.asString() + "' to boolean. One of " + "these values is not a valid boolean.");
  254.          }
  255.       }
  256.  
  257.       return var2;
  258.    }
  259.  
  260.    private TypelessValue multiplicative(ExpressionLexer var1) throws ExpressionException {
  261.       TypelessValue var2 = this.primary(var1);
  262.  
  263.       while(true) {
  264.          switch (var1.lookAhead().getType()) {
  265.             case 42:
  266.                var1.read();
  267.                double var7 = this.convertToNumber(var2) * this.convertToNumber(this.primary(var1));
  268.                var2 = new TypelessValue(var7);
  269.                break;
  270.             case 43:
  271.             case 44:
  272.             case 45:
  273.             case 46:
  274.             default:
  275.                return var2;
  276.             case 47:
  277.                var1.read();
  278.                double var3 = this.convertToNumber(this.primary(var1));
  279.                if (var3 == (double)0.0F) {
  280.                   throw new ExpressionException(104, "Attempted to divide '" + var2.asString() + "' by zero.");
  281.                }
  282.  
  283.                double var5 = this.convertToNumber(var2) / var3;
  284.                var2 = new TypelessValue(var5);
  285.          }
  286.       }
  287.    }
  288.  
  289.    private TypelessValue additive(ExpressionLexer var1) throws ExpressionException {
  290.       TypelessValue var2 = this.multiplicative(var1);
  291.  
  292.       while(true) {
  293.          switch (var1.lookAhead().getType()) {
  294.             case 43:
  295.                var1.read();
  296.                double var5 = this.convertToNumber(var2) + this.convertToNumber(this.multiplicative(var1));
  297.                var2 = new TypelessValue(var5);
  298.                break;
  299.             case 44:
  300.             default:
  301.                return var2;
  302.             case 45:
  303.                var1.read();
  304.                double var3 = this.convertToNumber(var2) - this.convertToNumber(this.multiplicative(var1));
  305.                var2 = new TypelessValue(var3);
  306.          }
  307.       }
  308.    }
  309. }
  310.