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.
Separator Override +
Product:
Class:
Remarks
Statement Boundary Override
Shortcut: +Associated Method: uCalc.Rule.StatementSeparatorAware(bool)
Description: A postfix modifier that allows a pattern variable to ignore statement separators (such as ; or structural newlines) and continue capturing text across command boundaries.
By default, uCalc is "Statement Separator Aware." This means that when a variable is capturing text, it treats statement separators as hard boundaries. This safety mechanism prevents a single variable from accidentally merging multiple distinct commands into one capture, which could break the logic of subsequent transformation rules.
The Statement Boundary Override (+) is used to bypass this structural limitation.
Default vs. Override Behavior
- Default (Statement Aware): If a variable
{v}is matched againstx=1; y=2, and the pattern looks for everything afterx=, it will stop capturing at the semicolon.{v}will contain only1. - Override (
{v+}): Appending the plus symbol tells the engine that statement separators are not boundaries for this specific variable. In the same example,{v+}would capture1; y=2.
The StatementSeparatorAware() Method
You can toggle this behavior globally using the StatementSeparatorAware() method on the uCalc object.
uc.StatementSeparatorAware(true): (Default) Variables stop matching at statement separators.uc.StatementSeparatorAware(false): All variables behave as if they have the+postfix, ignoring separators by default.
Examples
1. Succinct (Breaking the Statement Barrier)
Showing how a standard variable is terminated by a semicolon, while the override continues until the pattern's end.
New(uCalc::Transformer, t)// Default: Capture stops at the semicolont.FromTo("get {cmd}", "CMD:[{cmd}]")// Override: Capture ignores the semicolont.FromTo("all {cmd+}", "FULL:[{cmd}]")wl(t.Transform("get x=1; y=2")) // Output: CMD:[x=1]; y=2wl(t.Transform("all x=1; y=2")) // Output: FULL:[x=1; y=2]2. Practical (Capturing Multi-Line Blocks)
Useful when you need to wrap an entire sequence of instructions into a container, where those instructions are separated by semicolons or newlines.
New(uCalc::Transformer, t)// Use '+' to ensure 'block' captures every statement until the 'END' keywordt.FromTo("BEGIN {block+} END", "<div class='code'>{block}</div>")wl(t.Transform("BEGIN cmd1; cmd2; cmd3; END"))[Expected Output]<div class='code'>cmd1; cmd2; cmd3;</div>
3. Internal Test (Global Configuration)
Verifying that disabling global statement awareness allows all variables to span across separators.
// Disable statement awareness globallyuc.StatementSeparatorAware(false)New(uCalc::Transformer, t)// Now this matches across the semicolon even without the '+' postfixt.FromTo("capture {v}", "GOT:{v}")wl(t.Transform("capture a;b;c"))[Expected Output]GOT:a;b;c
Strategy & Critique
- Structural Intent: Statement separators are critical markers in most languages. Only override them when your goal is to manipulate a "block" of logic rather than an individual expression.
- Lexer Dependencies: The definition of a "statement separator" depends on the current lexer configuration.
+ensures that whatever the lexer considers a separator is ignored for that capture. - Naming: The method
StatementSeparatorAware()clearly identifies that the engine's default state is to protect the boundaries between statements. - See Also: Refer to Topic 781 for Nesting Overrides and Topic 786 for Quote Overrides.
Examples
IgnoreStatementSeparator +
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.FromTo("a {txt} c", "<{@Self}>");
t.FromTo("x {txt+} z", "<{@Self}>");
Console.WriteLine(t.Transform("a b c; :: x y z; :: a b; c :: x y; z"));
<a b c>; :: <x y z>; :: a b; c :: <x y; z> using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.FromTo("a {txt} c", "<{@Self}>"); t.FromTo("x {txt+} z", "<{@Self}>"); Console.WriteLine(t.Transform("a b c; :: x y z; :: a b; c :: x y; z"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.FromTo("a {txt} c", "<{@Self}>");
t.FromTo("x {txt+} z", "<{@Self}>");
cout << t.Transform("a b c; :: x y z; :: a b; c :: x y; z") << endl;
}
<a b c>; :: <x y z>; :: a b; c :: <x y; z> #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.FromTo("a {txt} c", "<{@Self}>"); t.FromTo("x {txt+} z", "<{@Self}>"); cout << t.Transform("a b c; :: x y z; :: a b; c :: x y; z") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.FromTo("a {txt} c", "<{@Self}>")
t.FromTo("x {txt+} z", "<{@Self}>")
Console.WriteLine(t.Transform("a b c; :: x y z; :: a b; c :: x y; z"))
End Sub
End Module
<a b c>; :: <x y z>; :: a b; c :: <x y; z> Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.FromTo("a {txt} c", "<{@Self}>") t.FromTo("x {txt+} z", "<{@Self}>") Console.WriteLine(t.Transform("a b c; :: x y z; :: a b; c :: x y; z")) End Sub End Module