Fast Math Parser and Innovative token-aware text parser/transformer
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.
Hierarchical Parsing (LocalTransformer)
Product:
Class:
Explains how to use LocalTransformer to create nested, multi-level parsing logic for structured data formats like HTML or XML.
Remarks
🌳 Hierarchical Parsing with LocalTransformer
Standard find-and-replace operations are typically "flat"—they scan an entire document from start to finish. However, real-world data is often hierarchical, with nested structures like HTML tags, JSON objects, or code blocks. The LocalTransformer is uCalc's elegant solution for this, enabling you to build powerful, multi-level parsers that understand scope and nesting.
It allows you to say: "First, find this outer block. Then, and only within that block, find these inner elements."
The Problem: Lack of Scope
Imagine you want to extract all the links (<a> tags) from a navigation menu in an HTML document, but ignore all other links in the main content. A global search for <a> tags is too broad and will incorrectly include links from the entire page.
<nav> <a href="/home">Home</a> <a href="/about">About</a></nav><main> <p>Some text with another <a href="/link">link</a>.</p></main>
A simple, flat pattern would find all three links. To solve this with traditional tools like regex, you would need a complex, multi-step process: first find the <nav> block, extract its content into a new string, run a second regex on that substring, and then manually map the results' coordinates back to the original document. This is inefficient and error-prone.
The Solution: The LocalTransformer
The LocalTransformer property on a Rule object provides a clean, integrated solution. It creates a nested Transformer whose scope is limited exclusively to the text captured by its parent rule.
The Two-Step Workflow:
Define the Parent Rule: Create a rule that finds and captures the outer container. The content to be searched is captured into a variable (e.g., {body}).
var parentRule = t.Pattern("<nav>{body}</nav>");
2. **Define Child Rules on the Local Transformer**: Get the local transformer from the parent rule and define rules on it. These rules will *only* run on the text captured by `{body}`. ```csharp var local_t = parentRule.LocalTransformer; local_t.Pattern("<a {etc}>...</a>");
When the main Transformer runs, the engine handles the entire hierarchical process automatically. This creates a parent-child relationship between matches, which you can inspect using the IsChildRule property and filter using MatchesOption flags like RootLevelOnly and InnermostOnly.
LocalTransformer vs. Tokens.ContextSwitch
Both features handle nested syntax, but they operate at different stages and solve different problems.
Feature
LocalTransformer (This Topic)
Tokens.ContextSwitch
Stage
Syntactic (Parser)
Lexical (Tokenizer)
What it Does
Applies a new set of grammar rules to a block of already-tokenized text.
Swaps the entire set of token definitions. Changes how text is broken into tokens.
Nesting
Yes. Local transformers can be nested to any depth.
No. Switches are not nestable by default.
Use Case
Parsing nested structures within the same language (e.g., finding <img> tags only within a specific <div>).
Parsing completely different, embedded languages (e.g., <script> in HTML, SQL in a string literal).
Conclusion: Use LocalTransformer for hierarchical parsing within a consistent syntax. Use ContextSwitch when you encounter a block of text that follows entirely different lexical rules.
Examples
A simple demonstration of finding a word but only inside a specific parenthetical block.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// 1. Parent rule finds content inside parentheses.
var parentRule = t.FromTo("({body})", "({body})");
// 2. Get the local transformer for the parent.
var local_t = parentRule.LocalTransformer;
// 3. Child rule runs only inside the parentheses.
local_t.FromTo("this", "THIS");
var text = "do not find this, but (find this) and not this";
Console.WriteLine(t.Transform(text));
do not find this, but (find THIS) and not this
using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // 1. Parent rule finds content inside parentheses. var parentRule = t.FromTo("({body})", "({body})"); // 2. Get the local transformer for the parent. var local_t = parentRule.LocalTransformer; // 3. Child rule runs only inside the parentheses. local_t.FromTo("this", "THIS"); var text = "do not find this, but (find this) and not this"; Console.WriteLine(t.Transform(text));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// 1. Parent rule finds content inside parentheses.
auto parentRule = t.FromTo("({body})", "({body})");
// 2. Get the local transformer for the parent.
auto local_t = parentRule.LocalTransformer();
// 3. Child rule runs only inside the parentheses.
local_t.FromTo("this", "THIS");
auto text = "do not find this, but (find this) and not this";
cout << t.Transform(text) << endl;
}
do not find this, but (find THIS) and not this
#include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // 1. Parent rule finds content inside parentheses. auto parentRule = t.FromTo("({body})", "({body})"); // 2. Get the local transformer for the parent. auto local_t = parentRule.LocalTransformer(); // 3. Child rule runs only inside the parentheses. local_t.FromTo("this", "THIS"); auto text = "do not find this, but (find this) and not this"; cout << t.Transform(text) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// 1. Parent rule finds content inside parentheses.
Dim parentRule = t.FromTo("({body})", "({body})")
'// 2. Get the local transformer for the parent.
Dim local_t = parentRule.LocalTransformer
'// 3. Child rule runs only inside the parentheses.
local_t.FromTo("this", "THIS")
Dim text = "do not find this, but (find this) and not this"
Console.WriteLine(t.Transform(text))
End Sub
End Module
do not find this, but (find THIS) and not this
Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// 1. Parent rule finds content inside parentheses. Dim parentRule = t.FromTo("({body})", "({body})") '// 2. Get the local transformer for the parent. Dim local_t = parentRule.LocalTransformer '// 3. Child rule runs only inside the parentheses. local_t.FromTo("this", "THIS") Dim text = "do not find this, but (find this) and not this" Console.WriteLine(t.Transform(text)) End Sub End Module
A practical example that extracts all `<a>` tags, but only from within a specific `<nav>` section of an HTML document.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
// Ignore multi-line formatting
t.DefaultRuleSet.StatementSensitive = false;
// 1. Parent rule captures the content of the
using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); // Ignore multi-line formatting t.DefaultRuleSet.StatementSensitive = false; // 1. Parent rule captures the content of the <nav> block. var navRule = t.Pattern("<nav>{content}</nav>"); // 2. Get the local transformer for the nav block. var local_t = navRule.LocalTransformer; // 3. This rule will only find `<a>` tags inside the <nav> block. local_t.Pattern("<a href={url}>{text}</a>"); var html = """ <nav> <a href="/home">Home</a> <a href="/about">About</a> </nav> <main> <p>Some text with another <a href="/other">other link</a>.</p> </main> """; t.Text = html; t.Find(); Console.WriteLine("--- Found Links (Innermost Matches Only) ---"); // Use InnermostOnly to see only the results from the local transformer. Console.WriteLine(t.GetMatches(MatchesOption.InnermostOnly).Text);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
// Ignore multi-line formatting
t.DefaultRuleSet().StatementSensitive(false);
// 1. Parent rule captures the content of the block.
auto navRule = t.Pattern("{content}");
// 2. Get the local transformer for the nav block.
auto local_t = navRule.LocalTransformer();
// 3. This rule will only find `` tags inside the block.
local_t.Pattern("{text}");
auto html = R"(
HomeAbout
)";
t.Text(html);
t.Find();
cout << "--- Found Links (Innermost Matches Only) ---" << endl;
// Use InnermostOnly to see only the results from the local transformer.
cout << t.GetMatches(MatchesOption::InnermostOnly).Text() << endl;
}
#include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; // Ignore multi-line formatting t.DefaultRuleSet().StatementSensitive(false); // 1. Parent rule captures the content of the <nav> block. auto navRule = t.Pattern("<nav>{content}</nav>"); // 2. Get the local transformer for the nav block. auto local_t = navRule.LocalTransformer(); // 3. This rule will only find `<a>` tags inside the <nav> block. local_t.Pattern("<a href={url}>{text}</a>"); auto html = R"( <nav> <a href="/home">Home</a> <a href="/about">About</a> </nav> <main> <p>Some text with another <a href="/other">other link</a>.</p> </main> )"; t.Text(html); t.Find(); cout << "--- Found Links (Innermost Matches Only) ---" << endl; // Use InnermostOnly to see only the results from the local transformer. cout << t.GetMatches(MatchesOption::InnermostOnly).Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
'// Ignore multi-line formatting
t.DefaultRuleSet.StatementSensitive = false
'// 1. Parent rule captures the content of the block.
Dim navRule = t.Pattern("{content}")
'// 2. Get the local transformer for the nav block.
Dim local_t = navRule.LocalTransformer
'// 3. This rule will only find `` tags inside the block.
local_t.Pattern("{text}")
Dim html = "
HomeAbout
"
t.Text = html
t.Find()
Console.WriteLine("--- Found Links (Innermost Matches Only) ---")
'// Use InnermostOnly to see only the results from the local transformer.
Console.WriteLine(t.GetMatches(MatchesOption.InnermostOnly).Text)
End Sub
End Module
Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() '// Ignore multi-line formatting t.DefaultRuleSet.StatementSensitive = false '// 1. Parent rule captures the content of the <nav> block. Dim navRule = t.Pattern("<nav>{content}</nav>") '// 2. Get the local transformer for the nav block. Dim local_t = navRule.LocalTransformer '// 3. This rule will only find `<a>` tags inside the <nav> block. local_t.Pattern("<a href={url}>{text}</a>") Dim html = " <nav> <a href=""/home"">Home</a> <a href=""/about"">About</a> </nav> <main> <p>Some text with another <a href=""/other"">other link</a>.</p> </main> " t.Text = html t.Find() Console.WriteLine("--- Found Links (Innermost Matches Only) ---") '// Use InnermostOnly to see only the results from the local transformer. Console.WriteLine(t.GetMatches(MatchesOption.InnermostOnly).Text) End Sub End Module