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%20Doewould be incorrectly parsed. - Parameters without values: A flag like
&betawould break thesplit('=')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:
- 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. - Pattern Rules: We'll define patterns to match different types of parameters:
- A rule for standard
key=valuepairs. - A rule for "flag" parameters that have no value.
- A rule for standard
- Custom Function: We'll create a native callback function,
URLDecode, to handle URL-encoded characters like%20. {@Eval}Integration: Our replacement logic will use{@Eval}to call theURLDecodefunction 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 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")); }
#include
#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 #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; } }
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 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
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' 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); }
#include
#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' #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; } }
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' 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