uCalc API Version: 2.1.3-preview.2 Released: 6/16/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: Building a Custom Query String Parser

Product: 

Class: 

A step-by-step guide to building a robust parser for URL query strings using the uCalc Transformer.

Remarks

💡 Project: Building a Custom Query String Parser

This project demonstrates how to build a robust parser for URL query strings using the uCalc Transformer. You'll learn how to handle key-value pairs, separators, and even URL-encoded characters, creating a tool that is far more reliable than simple string splitting.

The Goal: From Raw String to Structured Data

Our objective is to parse a standard URL query string and extract its key-value pairs into a clean, readable format.

Input:product=uCalc%20SDK&version=2.1&beta

Desired Output:

- product: 'uCalc SDK'- version: '2.1'- Flag: 'beta'

⚖️ Why uCalc? (vs. Manual String Splitting)

A common approach to this problem is to split the string by & and then split each part by =. This is simple but brittle and fails on many real-world edge cases:

  • URL-encoded values: name=John%20Doe would be incorrectly parsed.
  • Parameters without values: A flag like &beta would break the split('=') logic.
  • Empty values: A key like version= would require special handling.

uCalc's token-aware, rule-based engine handles these cases gracefully, leading to a more robust and maintainable solution.


The Strategy: A Multi-Rule Transformer

We will build our parser using a Transformer with a few key components:

  1. Custom Tokenizer: We'll teach the tokenizer to recognize & as a statement separator. This allows the transformer to process each key-value pair as a separate unit.
  2. Pattern Rules: We'll define patterns to match different types of parameters:
    • A rule for standard key=value pairs.
    • A rule for "flag" parameters that have no value.
  3. Custom Function: We'll create a native callback function, URLDecode, to handle URL-encoded characters like %20.
  4. {@Eval} Integration: Our replacement logic will use {@Eval} to call the URLDecode function on captured values, cleaning the data as it's extracted.

Step-by-Step Implementation

The practical example below demonstrates the complete implementation, including the setup of the tokenizer, the definition of the rules, and the integration of a native callback for decoding.

Examples

A succinct example that extracts a single key-value pair from a query string.
				
					using uCalcSoftware;

var uc = new uCalc();
using (var t = new uCalc.Transformer()) {
   // Define a rule to find a key-value pair
   t.FromTo("{@Alphanumeric:key}={@Alphanumeric:val}", "Key: {key}, Value: {val}");

   // Process a simple query string
   Console.WriteLine(t.Transform("user=admin"));
}
				
			
Key: user, Value: admin
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   {
      uCalc::Transformer t;
      t.Owned(); // Causes t to be released when it goes out of scope
      // Define a rule to find a key-value pair
      t.FromTo("{@Alphanumeric:key}={@Alphanumeric:val}", "Key: {key}, Value: {val}");

      // Process a simple query string
      cout << t.Transform("user=admin") << endl;
   }
}
				
			
Key: user, Value: admin
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Using t As New uCalc.Transformer()
         '// Define a rule to find a key-value pair
         t.FromTo("{@Alphanumeric:key}={@Alphanumeric:val}", "Key: {key}, Value: {val}")
         
         '// Process a simple query string
         Console.WriteLine(t.Transform("user=admin"))
      End Using
   End Sub
End Module
				
			
Key: user, Value: admin
A practical, real-world parser that handles multiple key-value pairs and URL-encoded characters using a custom callback.
				
					using uCalcSoftware;

var uc = new uCalc();

static void URLDecode(uCalc.Callback cb) {
   // In a real application, this would be a full URL decoding implementation.
   // For this example, we'll just handle spaces (%20) and plus signs (+).
   uCalc.String s = cb.ArgStr(1);
   s.Replace("%20", " ").Replace("+", " ");
   cb.ReturnStr(s.Text);
}


// 1. Define the custom URLDecode function in the uCalc engine
uc.DefineFunction("URLDecode(s As String) As String", URLDecode);

// 2. Create the transformer and configure its tokenizer
using (var t = new uCalc.Transformer(uc)) {
   // Treat '&' as a statement separator to process each pair individually
   t.Tokens.Add("&", TokenType.StatementSep);

   // 3. Define the rule to capture key-value pairs and decode the value
   t.FromTo("{@Alphanumeric:key}={value}", "- {key}: '{@Eval: URLDecode(value)}'");

   // 4. Process a real-world query string
   var queryString = "name=John%20Doe&role=user+admin&id=123";

   // Use Filter() to get a clean, newline-separated list of the results
   Console.WriteLine(t.Transform(queryString).Matches);
}
				
			
- name: 'John Doe'
- role: 'user admin'
- id: '123'
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call URLDecode(uCalcBase::Callback cb) {
   // In a real application, this would be a full URL decoding implementation.
   // For this example, we'll just handle spaces (%20) and plus signs (+).
   uCalc::String s = cb.ArgStr(1);
   s.Replace("%20", " ").Replace("+", " ");
   cb.ReturnStr(s.Text());
}

int main() {
   uCalc uc;
   // 1. Define the custom URLDecode function in the uCalc engine
   uc.DefineFunction("URLDecode(s As String) As String", URLDecode);

   // 2. Create the transformer and configure its tokenizer
   {
      uCalc::Transformer t(uc);
      t.Owned(); // Causes t to be released when it goes out of scope
      // Treat '&' as a statement separator to process each pair individually
      t.Tokens().Add("&", TokenType::StatementSep);

      // 3. Define the rule to capture key-value pairs and decode the value
      t.FromTo("{@Alphanumeric:key}={value}", "- {key}: '{@Eval: URLDecode(value)}'");

      // 4. Process a real-world query string
      auto queryString = "name=John%20Doe&role=user+admin&id=123";

      // Use Filter() to get a clean, newline-separated list of the results
      cout << t.Transform(queryString).Matches() << endl;
   }
}
				
			
- name: 'John Doe'
- role: 'user admin'
- id: '123'
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub URLDecode(ByVal cb As uCalc.Callback)
      '// In a real application, this would be a full URL decoding implementation.
      '// For this example, we'll just handle spaces (%20) and plus signs (+).
      Dim s As uCalc.String = cb.ArgStr(1)
      s.Replace("%20", " ").Replace("+", " ")
      cb.ReturnStr(s.Text)
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      '// 1. Define the custom URLDecode function in the uCalc engine
      uc.DefineFunction("URLDecode(s As String) As String", AddressOf URLDecode)
      
      '// 2. Create the transformer and configure its tokenizer
      Using t As New uCalc.Transformer(uc)
         '// Treat '&' as a statement separator to process each pair individually
         t.Tokens.Add("&", TokenType.StatementSep)
         
         '// 3. Define the rule to capture key-value pairs and decode the value
         t.FromTo("{@Alphanumeric:key}={value}", "- {key}: '{@Eval: URLDecode(value)}'")
         
         '// 4. Process a real-world query string
         Dim queryString = "name=John%20Doe&role=user+admin&id=123"
         
         '// Use Filter() to get a clean, newline-separated list of the results
         Console.WriteLine(t.Transform(queryString).Matches)
      End Using
   End Sub
End Module
				
			
- name: 'John Doe'
- role: 'user admin'
- id: '123'