uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Project: Parsing and Evaluating Complex Boolean Logic
Product:
Class:
A step-by-step guide to building a rule engine that can parse and evaluate complex boolean logic using uCalc's built-in operators and custom DSLs.
Remarks
🧠 Project: Parsing and Evaluating Complex Boolean Logic
This project demonstrates how to use uCalc to build a powerful engine for parsing and evaluating complex boolean logic expressions. This is a common requirement for applications like business rule engines, access control systems, search query parsers, and data validation frameworks.
The Goal: A Dynamic Rule Engine
We want to evaluate logical statements provided as strings at runtime, using a context of variables. Our engine should correctly handle:
- Comparison Operators:
==,>,<,>=,<=,<> - Logical Operators:
AND,OR,NOT - Grouping: Parentheses
()to control the order of operations.
A typical expression might look like this:"(status == 'Active' AND login_attempts < 3) OR is_admin == true"
Why uCalc is the Perfect Tool
Building a boolean logic parser from scratch is a significant undertaking. You would need to implement a lexer, a parser that understands operator precedence (e.g., AND before OR), and an evaluation engine.
uCalc provides all of this functionality out of the box:
- Built-in Operators: It already understands all standard comparison and logical operators.
- Precedence & Associativity: The engine correctly handles the order of operations.
- Dynamic Context: You can easily define variables at runtime to provide the data against which the rules are evaluated.
- Extensibility: As shown in the practical example, you can use the ExpressionTransformer to create a more natural, domain-specific language (DSL) on top of the core logic.
Step 1: The Basic Approach (Using Built-in Logic)
The simplest way to evaluate a boolean expression is to define your variables and then pass the expression string directly to EvalStr(). uCalc's default grammar will handle the rest.
The "Succinct" example below demonstrates this direct approach.
Step 2: The Advanced Approach (Creating a Custom DSL)
For a more user-friendly or domain-specific syntax, you can use the ExpressionTransformer to transpile custom keywords into standard uCalc expressions before they are evaluated.
Let's say we want to support a more natural language syntax:
ISinstead of==IS NOTinstead of<>CONTAINSfor string searching
We can define simple FromTo rules to map this custom syntax to uCalc's built-in operators and functions. This creates a powerful abstraction layer, making the rules easier for non-programmers to write and understand.
The "Practical" example demonstrates this technique.
Step 3: Providing the Data Context
In either approach, the boolean expression is evaluated against a set of variables. These variables represent the "facts" or the current state of the system. You define them using DefineVariable() before evaluating the expression.
// Define the data context for our rule engineuc.DefineVariable("status = 'Active'");uc.DefineVariable("login_attempts = 2");uc.DefineVariable("is_admin = false");When the expression is evaluated, uCalc will look up these variable names and use their current values in the calculation.
Let's see the complete implementations.
Examples
Succinct: Evaluates a complex boolean expression using uCalc's built-in operators.
using uCalcSoftware;
var uc = new uCalc();
uc.DefineVariable("status = 'Active'");
uc.DefineVariable("login_attempts = 2");
uc.DefineVariable("is_admin = false");
var rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true";
Console.WriteLine($"Evaluating rule: {rule}");
Console.Write("Result: ");
Console.WriteLine(uc.EvalStr(rule));
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true using uCalcSoftware; var uc = new uCalc(); uc.DefineVariable("status = 'Active'"); uc.DefineVariable("login_attempts = 2"); uc.DefineVariable("is_admin = false"); var rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"; Console.WriteLine($"Evaluating rule: {rule}"); Console.Write("Result: "); Console.WriteLine(uc.EvalStr(rule));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineVariable("status = 'Active'");
uc.DefineVariable("login_attempts = 2");
uc.DefineVariable("is_admin = false");
auto rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true";
cout << "Evaluating rule: " << rule << endl;
cout << "Result: ";
cout << uc.EvalStr(rule) << endl;
}
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineVariable("status = 'Active'"); uc.DefineVariable("login_attempts = 2"); uc.DefineVariable("is_admin = false"); auto rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"; cout << "Evaluating rule: " << rule << endl; cout << "Result: "; cout << uc.EvalStr(rule) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("status = 'Active'")
uc.DefineVariable("login_attempts = 2")
uc.DefineVariable("is_admin = false")
Dim rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true"
Console.WriteLine($"Evaluating rule: {rule}")
Console.Write("Result: ")
Console.WriteLine(uc.EvalStr(rule))
End Sub
End Module
Evaluating rule: (status == 'Active' AND login_attempts < 3) OR is_admin == true
Result: true Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("status = 'Active'") uc.DefineVariable("login_attempts = 2") uc.DefineVariable("is_admin = false") Dim rule = "(status == 'Active' AND login_attempts < 3) OR is_admin == true" Console.WriteLine($"Evaluating rule: {rule}") Console.Write("Result: ") Console.WriteLine(uc.EvalStr(rule)) End Sub End Module