Skip to content

Commit

Permalink
fix bug in operator
Browse files Browse the repository at this point in the history
  • Loading branch information
lfkdsk committed Sep 12, 2017
1 parent b347cfa commit fcd9f6e
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 40 deletions.
203 changes: 196 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,216 @@
# Just-Evaluator
## Just-Evaluator

JVM 平台的高性能、轻量级的表达式求值引擎,提供解释执行和编译执行等多种求值方式。
**JVM platform, high-performance, lightweight** expression evaluation engine, to provide interpretation and implementation of the implementation of a variety of evaluation methods.

## Dependency
### How to use?

* with gradle:

```groovy
// Step 1. Add the JitPack repository to your build file
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
// Step 2. Add the dependency
dependencies {
compile 'com.github.User:Repo:Tag'
}
```

* with maven:

## Capacity
**Step 1.** Add the JitPack repository to your build file

``` xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
```

**Step 2.** Add the dependency

```xml
<dependency>
<groupId>com.github.lfkdsk</groupId>
<artifactId>Just-Evaluator</artifactId>
<version>v1.0</version>
</dependency>
```

### Usage

#### 1.Eval Simple Expr:

``` java
JustEL.runEval("i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99 ==i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99",
new JustMapContext() {{
put("i", 100);
put("pi", 3.14d);
put("d", -3.9);
put("b", (byte) 4);
put("bool", false);
}};
```

Then you can get the result from the return value.

#### 2.Eval Simple Expr With Expression:

``` java
Expression expr =
JustEL.runEval("i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99 ==i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99");
expr.eval(new JustMapContext() {{
put("i", 100);
put("pi", 3.14d);
put("d", -3.9);
put("b", (byte) 4);
put("bool", false);
});
```

In this way, you can build **AST of this expr** at once time, then eval by multi-contexts **many-times**.

#### 3. Compile Expr to Expression

``` java
Expression expr =
JustEL.runCompile("i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99 ==i * pi +(d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99", context);
expr.eval(context);
```

Your Expr String will be compile at **Runtime**, so you can calculate the result of the expr by **Java**. This way has better permance when you will evaluate the result **million times, or even hundreds of millions of times** with same or different context.

### High-Level Usage

#### 4.Build The Components of Evaluator By yourself

``` java
JustEL.builder()
.lexer(new JustLexerImpl())
.parser(new JustParserImpl())
.compiler(new JustCompilerImpl())
.generator(new JavaCodeGenerator())
.create()
.compile("1111 + lfkdsk + sss", context)
.eval(context)
```

You can change all **primary components** of the Evaluator , contains *lexer* , *parser*, *compiler*, *template generator* .

#### 5. Extend Function

``` java
public static class Add extends ExtendFunctionExpr {
@Override
public String funcName() {
return "add";
}

@Override
public Object call(Object... params) {
Integer left = (Integer) params[0];
Integer right = (Integer) params[1];

if (left != null && right != null) {
return left + right;
}

return this.call(params);
}
}
```

Create a new class **extend** ExtendFunctionExpr Class,Override funcName and call method,then you can put it into the context and use like this :

``` java
JustContext context = new JustContext();
context.putExtendFunc("add", new ExtendFunctionExpr());
JustEL.runEval("add(111, 222.0)",context);
JustEL.runCompile("add(111, 222.0)",context);
```

#### 6. Add Binary Operator Support

Just-Evaluator support **ast-level Binary-Operators** , Extent Operator will be supported as system-operators.

``` java
public static class NewOperator extends OperatorExpr {

public NewOperator(List<AstNode> children) {
super(children, 1000);
}


@Override
public Object eval(JustContext env) {
Object left = leftChild().eval(env);
Object right = rightChild().eval(env);

if (isNumber(left) && isNumber(right)) {
return NumberUtils.computePlusValue(
(Number) NumberUtils.computePlusValue((Number) left, ((Number) right)),
(Number) right);
}

return super.eval(env);
}

@Override
public String compile(JustContext env) {
StringBuilder builder = new StringBuilder();
String left = leftChild().compile(env);
String right = rightChild().compile(env);
builder.append("(")
.append(left)
.append("+")
.append(right)
.append("+")
.append(right)
.append(")");

return builder.toString();
}

@Override
public String funcName() {
return "**";
}
}

```

Create new class **extend** OperatorsExpr Class and override eval or compile method according to your need.

Then you have to set some *symbol support* :

``` java
// let lexer know ** is Operator-Symbol
lexer.insertSymbol("**");
// let parser know symbol, priority, combination and this class.
parser.insertOperators("**", 2, LEFT, NewOperator.class);
```

### Performance



## Feature
### Feature



## Feedback
### Feedback
Please send your feedback as long as there occurs any inconvenience or problem. You can contact me with:
* Email: lfk_dsk@hotmail.com
* Weibo: [@亦狂亦侠_亦温文](http://www.weibo.com/u/2443510260)
* Blog: [刘丰恺](http://lfkdsk.github.io)

## License
### License

Copyright 2017 [刘丰恺](http://lfkdsk.github.io/)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.lfkdsk.justel.ast.base.AstNode;
import com.lfkdsk.justel.context.JustContext;
import com.lfkdsk.justel.exception.EvalException;
import com.lfkdsk.justel.parser.BnfCom;
import com.lfkdsk.justel.token.Token;
import com.lfkdsk.justel.utils.GeneratedId;

Expand All @@ -35,8 +34,6 @@ public abstract class OperatorExpr extends AstList implements Function {

protected boolean isThisNodeSpited = false;

public static final BnfCom.Operators operators = new BnfCom.Operators();

public OperatorExpr(List<AstNode> children) {
super(children, Token.OPERATOR);
this.checkConstNode();
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/com/lfkdsk/justel/ast/tree/AstFuncExpr.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
import com.lfkdsk.justel.exception.UnSupportMethodException;
import com.lfkdsk.justel.utils.GeneratedId;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* function( expr , expr , expr)
Expand All @@ -27,8 +25,6 @@
*/
public class AstFuncExpr extends AstList {

public static final Map<String, ExtendFunctionExpr> extFunc = new HashMap<>();

public AstFuncExpr(List<AstNode> children) {
super(children, AstNode.FUNCTION_EXPR);
}
Expand All @@ -55,7 +51,7 @@ public AstFuncArguments funcArgs() {
@Override
public Object eval(JustContext env) {
String funcName = funcName().toString();
ExtendFunctionExpr expr = extFunc.get(funcName);
ExtendFunctionExpr expr = env.getExtendFunc(funcName);

if (expr != null) {
expr.bindToAstFunc(this);
Expand All @@ -71,7 +67,7 @@ public String compile(JustContext env) {
// generate code by one time

// get func obj
ExtendFunctionExpr extendFunc = extFunc.get(funcName().toString());
ExtendFunctionExpr extendFunc = env.getExtendFunc(funcName().toString());

if (extendFunc == null) {
throw new UnSupportMethodException("un support method funcName: " + funcName().toString());
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/lfkdsk/justel/context/JustContext.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.lfkdsk.justel.context;

import com.lfkdsk.justel.ast.function.ExtendFunctionExpr;

import java.util.Collection;
import java.util.List;

Expand All @@ -17,6 +19,10 @@ public interface JustContext {

Object put(String key, Object val);

ExtendFunctionExpr putExtendFunc(String name, ExtendFunctionExpr expr);

ExtendFunctionExpr getExtendFunc(String name);

/**
* Warning:!!!
* Add Code to Java Source Code Straightly
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/lfkdsk/justel/context/JustMapContext.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.lfkdsk.justel.context;

import com.lfkdsk.justel.ast.function.ExtendFunctionExpr;
import com.lfkdsk.justel.utils.ObjectHelper;

import java.util.*;
Expand All @@ -18,6 +19,8 @@ public class JustMapContext implements JustContext {

private List<String> globalList = new LinkedList<>();

private Map<String, ExtendFunctionExpr> extFunc = new HashMap<>();

@Override
public boolean contain(String name) {
return map.containsKey(name);
Expand All @@ -33,6 +36,16 @@ public Object put(String key, Object val) {
return map.put(key, val);
}

@Override
public ExtendFunctionExpr putExtendFunc(String name, ExtendFunctionExpr expr) {
return extFunc.put(name, expr);
}

@Override
public ExtendFunctionExpr getExtendFunc(String name) {
return extFunc.get(name);
}

@Override
public Object command(String command) {
ObjectHelper.requireNonNull(command, "command could not null");
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/lfkdsk/justel/parser/JustParserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.lfkdsk.justel.token.ReservedToken;
import org.jetbrains.annotations.NotNull;

import static com.lfkdsk.justel.ast.function.OperatorExpr.operators;
import static com.lfkdsk.justel.parser.BnfCom.Operators.LEFT;
import static com.lfkdsk.justel.parser.BnfCom.rule;
import static com.lfkdsk.justel.parser.ParserHelper.generateAst;
Expand All @@ -50,6 +49,12 @@
*/
public class JustParserImpl implements JustParser {

///////////////////////////////////////////////////////////////////////////
// Support Operators
///////////////////////////////////////////////////////////////////////////

private BnfCom.Operators operators = new BnfCom.Operators();

private BnfCom expr0 = rule();


Expand Down Expand Up @@ -124,6 +129,10 @@ public class JustParserImpl implements JustParser {

private BnfCom program = rule(AstProgram.class).ast(expr).sep(EOL);

///////////////////////////////////////////////////////////////////////////
// Support Expr Function
///////////////////////////////////////////////////////////////////////////

public JustParserImpl() {

// primary { postfix }
Expand Down
Loading

0 comments on commit fcd9f6e

Please sign in to comment.