日本語 | English
Java アプリケーションに組み込み可能な式評価エンジン(UDF スタイル)。
- ランタイムでの式評価
- 複数式の依存関係付き実行
- 6 つの実行バックエンド(JavaCode / AST / P4 系列)
- LSP / DAP サポート(VS Code 拡張)
ドキュメント: getting-started | language-guide | backends | architecture
IDE: tinyexpression-group/tinyexpression-ide — VS Code 拡張(LSP + DAP)
- Java 21+
- Maven 3.8+
テスト/ランタイムで反射アクセスを使うため add-opens が必要(pom.xml 設定済み)。
<dependency>
<groupId>org.unlaxer</groupId>
<artifactId>tinyExpression</artifactId>
<version>1.4.15</version>
</dependency>importorg.unlaxer.tinyexpression.CalculationContext;
importorg.unlaxer.tinyexpression.PreConstructedCalculator;
importorg.unlaxer.tinyexpression.Source;
importorg.unlaxer.tinyexpression.evaluator.javacode.JavaCodeCalculatorV3;
importorg.unlaxer.tinyexpression.evaluator.javacode.SpecifiedExpressionTypes;
importorg.unlaxer.tinyexpression.parser.ExpressionTypes;
publicclassQuickStart {
publicstaticvoidmain(String[] args) {
CalculationContextcontext = CalculationContext.newConcurrentContext();
context.set("gender", "male");
Stringformula = "if($gender=='male'){500}else{1000}";
PreConstructedCalculatorcalculator = newJavaCodeCalculatorV3(
newSource(formula),
"QuickStartCalculator",
newSpecifiedExpressionTypes(ExpressionTypes._float, ExpressionTypes._float),
Thread.currentThread().getContextClassLoader());
floatv1 = ((Number) calculator.apply(context)).floatValue();
context.set("gender", "female");
floatv2 = ((Number) calculator.apply(context)).floatValue();
System.out.println(v1); // 500.0System.out.println(v2); // 1000.0
}
}TinyExpressionsExecutor(複数形)で依存関係付き複数式を実行します。
<root>/
<tenant-id>/formulaInfo.txt
tags:NORMAL
description:基本スコア
siteId:69
calculatorName:baseScore
var:baseScore
resultType:float
formula:
if($age >= 20){100}else{0}
---END_OF_PART---
tags:NORMAL
description:ボーナス
siteId:69
calculatorName:bonusScore
dependsOn:baseScore
var:finalScore
backend:AST_EVALUATOR
resultType:float
formula:
$baseScore + 10
---END_OF_PART---
FormulaInfoAdditionalFieldsfields = newFormulaInfoAdditionalFields(
"siteId",
info -> info.calculatorName);
fields.setExecutionBackend(ExecutionBackend.JAVA_CODE);
FileBaseTinyExpressionInstancesCachecache = newFileBaseTinyExpressionInstancesCache(
Path.of("src", "main", "resources", "formula-root"),
fields);
CalculationContextctx = CalculationContext.newConcurrentContext();
ctx.set("age", 30);
TinyExpressionsExecutorexecutor = newTinyExpressionsExecutor();
List<CalculationResult> results = executor.execute(
TenantID.create(69),
ctx,
resultConsumer,
cache,
Comparator.comparingInt(Calculator::dependsOnByNestLevel).reversed(),
calculator -> true,
Thread.currentThread().getContextClassLoader());詳細は docs/getting-started.md 参照。
各ブロックは key:value + formula 本文で構成し、---END_OF_PART--- で区切ります。
| キー | 説明 |
|---|---|
calculatorName | 式 ID |
dependsOn | 依存式名(カンマ区切り) |
resultType | 戻り値型(string, boolean, float, double, FQCN 等) |
numberType | 数値演算の既定型 |
formula | 式本文 |
executionBackend / backend | バックエンド上書き |
var | CalculationContext への書き戻し変数名 |
field | ドメインオブジェクトフィールド名 |
checkKind | スコアマップ等の出力キー |
FormulaInfo の byteCode、hashByByteCode、javaCode は、過去の出力との互換性や
監査のために文書へ含まれることがあります。ただし、これらは式と同じ編集可能な文書に
保存されるため、署名の代わりにはなりません。ローダーは formula を必須とし、読込時は
現在の実行ポリシーで式から Calculator を再構築します。保存済み bytecode は実行しません。
再構築にはコンパイルコストが掛かるため、評価ごとに FormulaInfo を読み直さず、生成した Calculator を再利用してください。Java コードブロックを含む式には、引き続き以下の明示的な opt-in が必要です。
警告: Java コードブロックは JVM 上で任意コードを実行します。信頼できないユーザーが式を投稿できる環境では 使用しないでください。
formula フィールドに Java クラスを直接埋め込めます。
formula:
```java:sample.v1.CheckDigits
package sample.v1;
import org.unlaxer.tinyexpression.CalculationContext;
public class CheckDigits {
public boolean check(CalculationContext context, String target) {
return target.matches("\\d+");
}
}
```
import sample.v1.CheckDigits#check as checkDigits;
if(external returning as boolean checkDigits($input)){1}else{0}
詳細は docs/language-guide.md#java-コードブロック 参照。
解決順序:
- グローバル既定値:
FormulaInfoAdditionalFields.setExecutionBackend(...)(初期値:JAVA_CODE) - 式ごとの上書き:
executionBackend/backendキー - 実装割り当て:
CalculatorCreatorRegistry.forBackend(...)
| バックエンド名 | 説明 |
|---|---|
JAVA_CODE | 現行プロダクション JavaCode(推奨) |
JAVA_CODE_LEGACY_ASTCREATOR | リファクタ前ベースライン(凍結) |
AST_EVALUATOR | AST 走査実行 |
DSL_JAVA_CODE | DSL JavaCode シーム(ハイブリッド) |
P4_AST_EVALUATOR | UBNF 生成パーサー + AST 評価(PRIMARY) |
P4_DSL_JAVA_CODE | UBNF 生成パーサー + DSL JavaCode |
DAP/ランタイムエイリアス: token, ast, dsl-javacode, p4-ast, p4-dsl-javacode
詳細は docs/backends.md 参照。
# 変数
$age $name $isMember
# 算術
1 + 2 * 3 (1 + 2) / 3
# 比較・論理
10 >= 3 10 == 3 10 != 3
true | false true & false not(false)
# 条件
if($age >= 20){100}else{0}
# match
match{
$code == 'JP' -> 1,
default -> 0
}
# 文字列
toUpperCase($name) $msg.startsWith('hello') $msg[0:3]
# 変数宣言
variable $gender as string set if not exists 'male' description='性別';
# 外部メソッド
import sample.v1.Checker#check as check;
if(external returning as boolean check($input)){1}else{0}
完全仕様は docs/language-guide.md 参照。
VS Code 拡張 tinyexpression-p4-lsp-vscode が提供:
- シンタックスハイライト・セマンティックトークン
- リッチ診断(TE001〜TE025、カタログ連携、Quick Fix、構造化
ULX-PARSE-001) - 宣言・import・method・
.tecatalogを使う補完とホバー - DAP デバッグ(6 バックエンドのパリティ比較)
DAP 0.2.33 は生成AST上の停止・ブレークポイント・実ランタイム評価に加え、
人向けの期待値付き構文診断と、LLM/editor向けの構造化診断dataに対応します。
launch.json の variables は CalculationContext に型付きで注入され、選択バックエンド、
6バックエンド比較、Debug Consoleで共通利用されます。停止中はVariablesビューから値を変更し、
同じコンテキストで再評価できます。詳細は
VS Code拡張README を参照してください。
formulaInfo.txtも自動認識し、calculatorNameで対象式を選択できます。既定の
runtimeMode: metadataは各ブロックのexecutionBackendに従い、依存式を先に実行して
Variablesビューへ式ごとの結果を表示します。埋め込みJavaは編集・色付けできますが、実行は
安全のため既定で無効です。
外部リポジトリ: tinyexpression-group/tinyexpression-ide
mvn -q testCI は test-baseline.txt で既知の失敗を管理し、新規失敗で落とす。運用と更新手順は docs/test-baseline.md 参照。
ドキュメント一覧: docs/INDEX.ja.md