/** * Constructs a new parser instance which uses a {@link DefaultNamespace} and the given type-checking setting. * * @param typeChecking if true, the parser performs strong type-checking on expressions */ public ParserImpl(boolean typeChecking) { this(new DefaultNamespace(), typeChecking); }
private void registerDefaultSymbols() { registerSymbol(SymbolFactory.createConstant("PI", Math.PI)); registerSymbol(SymbolFactory.createConstant("E", Math.E)); registerSymbol(SymbolFactory.createConstant("NaN", Double.NaN)); }
public DefaultNamespace(Namespace parent) { super(parent); registerDefaultSymbols(); registerDefaultFunctions(); }
private void initParser() { final String sourceName = getSelectedSourceName(); final Variable sourceVariable = SymbolFactory.createVariable(sourceName, 0.0); final DefaultNamespace namespace = new DefaultNamespace(); namespace.registerSymbol(sourceVariable); setParser(new ParserImpl(namespace, true)); }
boolean setExpression(String qualifiedSourceName, String expression) { final Symbol symbol = namespace.resolveSymbol(qualifiedSourceName); if (symbol == null) { return false; } if (isExpressionValid(expression, qualifiedSourceName)) { currentExpressionMap.put(qualifiedSourceName, expression); fireExpressionChanged(); return true; } return false; }
private void registerDefaultFunctions() { registerFunction(new AbstractFunction.D("sin", 1) { registerFunction(new AbstractFunction.D("cos", 1) { registerFunction(new AbstractFunction.D("tan", 1) { registerFunction(new AbstractFunction.D("asin", 1) { registerFunction(new AbstractFunction.D("acos", 1) { registerFunction(new AbstractFunction.D("atan", 1) { registerFunction(new AbstractFunction.D("atan2", 2) { registerFunction(new AbstractFunction.D("log", 1) { registerFunction(new AbstractFunction.D("log10", 1) { public double evalD(EvalEnv env, Term[] args) throws EvalException { return Math.log10(args[0].evalD(env)); registerFunction(new AbstractFunction.D("exp", 1) { registerFunction(new AbstractFunction.D("exp10", 1) { registerFunction(new AbstractFunction.D("sqr", 1) { registerFunction(new AbstractFunction.D("sqrt", 1) { registerFunction(new AbstractFunction.D("pow", 2) {
private boolean isExpressionValid(String expression, String qualifiedSorceName) { if (expression == null || expression.trim().isEmpty()) { return true; } if (expression.trim().equals(qualifiedSorceName.trim())) { return false; } try { final DefaultNamespace expressionValidationNamespace = new DefaultNamespace(); expressionValidationNamespace.registerSymbol(SymbolFactory.createVariable(qualifiedSorceName, 0.0)); final Term term = parser.parse(expression, expressionValidationNamespace); return term != null && term.isB(); } catch (ParseException ignored) { return false; } }
@Override public TimeSeries validate(TimeSeries timeSeries, String sourceName, TimeSeriesType type) throws ParseException { String qualifiedSourceName = createQualifiedSourcename(sourceName, type); final Symbol symbol = namespace.resolveSymbol(qualifiedSourceName); if (symbol == null) { throw new ParseException("No variable for identifier '" + qualifiedSourceName + "' registered."); } final String expression = getExpressionFor(qualifiedSourceName); if (expression == null || expression.trim().isEmpty()) { return timeSeries; } final Variable variable = (Variable) symbol; final Term term = parser.parse(expression, namespace); final int seriesCount = timeSeries.getItemCount(); final TimeSeries validatedSeries = new TimeSeries(timeSeries.getKey()); for (int i = 0; i < seriesCount; i++) { final TimeSeriesDataItem dataItem = timeSeries.getDataItem(i); final Number value = dataItem.getValue(); variable.assignD(null, value.doubleValue()); if (term.evalB(null)) { validatedSeries.add(dataItem); } } return validatedSeries; }
@Override public void adaptTo(Object timeSeriesKey, AxisMapping axisMapping) { if (timeSeriesExpressionsMap.containsKey(timeSeriesKey)) { currentExpressionMap = timeSeriesExpressionsMap.get(timeSeriesKey); } else { currentExpressionMap = new HashMap<String, String>(); timeSeriesExpressionsMap.put(timeSeriesKey, currentExpressionMap); } qualifiedSourceNames = extractQualifiedSourceNames(axisMapping); namespace = new DefaultNamespace(); for (String qualifiedSourceName : qualifiedSourceNames) { namespace.registerSymbol(SymbolFactory.createVariable(qualifiedSourceName, 0.0)); } if (qualifiedSourceNames.size() > 0 && hasUI) { expressionTextField.setEnabled(true); sourceNamesDropDown.setEnabled(true); sourceNamesDropDown.setModel(new DefaultComboBoxModel(getSourceNames())); final String expression = getExpressionFor(getSelectedSourceName()); expressionTextField.setText(expression == null ? "" : expression); } }
/** * Constructs a new parser instance which uses a {@link DefaultNamespace} and type-checking enabled. */ public ParserImpl() { this(new DefaultNamespace(), true); }
public void testThatPerformanceIsSufficient() throws ParseException, IOException { final Band flags = new Band("flags", ProductData.TYPE_INT8, 1, 1); final SingleFlagSymbol s1 = new SingleFlagSymbol("flags.WATER", flags, 0x01); final SingleFlagSymbol s2 = new SingleFlagSymbol("flags.LAND", flags, 0x02); final SingleFlagSymbol s3 = new SingleFlagSymbol("flags.CLOUD", flags, 0x04); final int[] dataElems = new int[]{-1}; s1.setData(dataElems); s2.setData(dataElems); s3.setData(dataElems); final DefaultNamespace namespace = new DefaultNamespace(); namespace.registerSymbol(s1); namespace.registerSymbol(s2); namespace.registerSymbol(s3); final String code = "(flags.WATER OR flags.LAND) AND NOT flags.CLOUD"; final Term term = new ParserImpl(namespace, true).parse(code); final RasterDataEvalEnv evalEnv = new RasterDataEvalEnv(0, 0, 1, 1); long t1 = System.currentTimeMillis(); for (int i = 0; i < MAX_NUM_TEST_LOOPS; i++) { } long t2 = System.currentTimeMillis(); for (int i = 0; i < MAX_NUM_TEST_LOOPS; i++) { term.evalI(evalEnv); } long t3 = System.currentTimeMillis(); long dt = (t3 - t2) - (t2 - t1); long numOps = Math.round(MAX_NUM_TEST_LOOPS * (1000.0 / dt)); // System.out.println("numOps = " + numOps); assertTrue(String.format("Low evaluation performance detected (%d ops/s for term \"%s\"): Term implementation change?", numOps, code), numOps > MIN_NUM_OPS_PER_SECOND); }
private ParserImpl createFallbackParser() { final Namespace fallbackNS = new DummyNamespace(); final DefaultNamespace defaultNS = new DefaultNamespace(fallbackNS); return new ParserImpl(defaultNS, false); }
private static final WritableNamespace DEFAULT_NAMESPACE = new DefaultNamespace();
@Test public void testPow() throws ParseException { NamespaceImpl namespace = new NamespaceImpl(new DefaultNamespace()); namespace.registerSymbol(new AbstractSymbol.I("ix") { @Override public int evalI(EvalEnv env) throws EvalException { return ix; } }); namespace.registerSymbol(new AbstractSymbol.D("dx") { @Override public double evalD(EvalEnv env) throws EvalException { return dx; } }); ParserImpl parser = new ParserImpl(namespace); ix = 1; dx = 1.0; assertEquals(10.0, parser.parse("pow(10, ix)").evalD(null), 1E-10); assertEquals(10.0, parser.parse("pow(10, ix)").evalD(null), 1E-10); assertEquals(10.0, parser.parse("pow(10, dx)").evalD(null), 1E-10); assertEquals(10.0, parser.parse("pow(10, dx)").evalD(null), 1E-10); ix = 2; dx = 2.0; assertEquals(100.0, parser.parse("pow(10.0, ix)").evalD(null), 1E-10); assertEquals(100.0, parser.parse("pow(10.0, ix)").evalD(null), 1E-10); assertEquals(100.0, parser.parse("pow(10.0, dx)").evalD(null), 1E-10); assertEquals(100.0, parser.parse("pow(10.0, dx)").evalD(null), 1E-10); }