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.

StatementSensitive = [bool]

Property

Product: 

Transformer Library

Class: 

Rule

Controls whether a pattern rule respects statement separators (like semicolons or newlines), preventing matches from crossing structural boundaries.

Remarks

🛡️ Structural Integrity: The StatementSensitive Property

The StatementSensitive property controls whether a pattern is aware of statement separators, preventing a variable capture from spanning across multiple distinct statements. When enabled (the default), it acts as a crucial safety feature, ensuring that a pattern like "start {body} end" doesn't accidentally consume an entire file if the "end" token is missing.

This property provides per-rule control, overriding the global setting inherited from the Transformer's DefaultRuleSet.

⚙️ How It Works

This property acts as a switch for an individual rule's parsing logic.

SettingBehavior
true (Default)Structurally Aware. The parser treats tokens categorized as TokenType::StatementSep (by default, newlines and semicolons) as hard boundaries for variable captures. A pattern like if {etc} will match only up to the end of the line or the next semicolon.
falseStructurally Unaware. Statement separators are treated like any other generic token. This is essential for parsing multi-line content such as HTML/XML blocks or free-form text where newlines are simply formatting.

By default, the uCalc expression engine defines the newline (_token_newline) and semicolon (_token_semicolon) tokens as statement separators. You can customize this by modifying the token definitions using the Transformer.Tokens property.

💡 Why uCalc? (Comparative Analysis)

In traditional regular expressions, handling multi-line text is notoriously tricky.

  • The dot . meta-character, by default, does not match newlines. To match across lines, you often have to enable a special "dotall" or "single-line" mode (e.g., the /s flag). This is a global switch for the entire regex.
  • Alternatively, you must use complex character classes like [\s\S] to match any character including newlines.

This is a blunt, all-or-nothing approach that lacks structural awareness.

uCalc's StatementSensitive property is more sophisticated because it is based on the semantic role of tokens, not just character types:

  1. Tokenizer Awareness: The tokenizer runs first and identifies tokens with the TokenType::StatementSep property.
  2. Safe Matching by Default: When StatementSensitive is true, the parser respects these separators as boundaries, preventing greedy variable captures from "leaking" across statements. This provides a much safer default behavior for parsing structured code or data.
  3. Granular Control: You can disable this safety feature on a per-rule basis, allowing you to have some rules that respect statement boundaries and others that don't, all within the same Transformer and running concurrently.

This gives you the flexibility to parse complex, mixed-content documents in a way that is far more robust and maintainable than with regex alone.

Examples

Succinct: Demonstrates the difference in variable capture behavior when StatementSensitive is enabled versus disabled.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
string txt = "start one; two end";

// Default behavior is StatementSensitive(true), so {body} stops at the semicolon
// and the 'end' anchor is never found. The transform fails.
var rule = t.FromTo("start {body} end", "[{body}]");
Console.WriteLine($"Sensitive (default): {t.Transform(txt)}");

rule.StatementSensitive = false;
// With StatementSensitive(false), {body} captures across the semicolon.
Console.WriteLine($"Insensitive: {t.Transform(txt)}");
				
			
Sensitive (default): start one; two end
Insensitive: [one; two]
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   string txt = "start one; two end";

   // Default behavior is StatementSensitive(true), so {body} stops at the semicolon
   // and the 'end' anchor is never found. The transform fails.
   auto rule = t.FromTo("start {body} end", "[{body}]");
   cout << "Sensitive (default): " << t.Transform(txt) << endl;

   rule.StatementSensitive(false);
   // With StatementSensitive(false), {body} captures across the semicolon.
   cout << "Insensitive: " << t.Transform(txt) << endl;
}
				
			
Sensitive (default): start one; two end
Insensitive: [one; two]
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      Dim txt As String = "start one; two end"
      
      '// Default behavior is StatementSensitive(true), so {body} stops at the semicolon
      '// and the 'end' anchor is never found. The transform fails.
      Dim rule = t.FromTo("start {body} end", "[{body}]")
      Console.WriteLine($"Sensitive (default): {t.Transform(txt)}")
      
      rule.StatementSensitive = false
      '// With StatementSensitive(false), {body} captures across the semicolon.
      Console.WriteLine($"Insensitive: {t.Transform(txt)}")
   End Sub
End Module
				
			
Sensitive (default): start one; two end
Insensitive: [one; two]
Practical: Shows how disabling statement sensitivity is essential for parsing multi-line HTML/XML blocks.
				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
var source = """
<data>
  content spans
  multiple lines
</data>
""";

// This rule must disable StatementSensitive to capture the multi-line body,
// otherwise the first newline would terminate the {body} variable.
var rule = t.FromTo("<data>{body}</data>", "Body: [{body}]");
rule.StatementSensitive = false;

Console.WriteLine(t.Transform(source));
				
			
Body: [
  content spans
  multiple lines
]
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   auto source = R"(<data>
  content spans
  multiple lines
</data>)";

   // This rule must disable StatementSensitive to capture the multi-line body,
   // otherwise the first newline would terminate the {body} variable.
   auto rule = t.FromTo("<data>{body}</data>", "Body: [{body}]");
   rule.StatementSensitive(false);

   cout << t.Transform(source) << endl;
}
				
			
Body: [
  content spans
  multiple lines
]
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      Dim source = "<data>
  content spans
  multiple lines
</data>"
      
      '// This rule must disable StatementSensitive to capture the multi-line body,
      '// otherwise the first newline would terminate the {body} variable.
      Dim rule = t.FromTo("<data>{body}</data>", "Body: [{body}]")
      rule.StatementSensitive = false
      
      Console.WriteLine(t.Transform(source))
   End Sub
End Module
				
			
Body: [
  content spans
  multiple lines
]
Using SkipOver() to ignore XML-style comments
				
					using uCalcSoftware;

var uc = new uCalc();
// StatementSensitive() is set to false so that ";" and newline are not treated as special

var t = uc.NewTransformer();
Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine("Setting StatementSensitive to False");

t.DefaultRuleSet.StatementSensitive = false; // so that newline does not behave as a statement separator

Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine("");

var Content =
"""

<nav aria-label="Main navigation">
  <ul>
    <li><a href="#intro">Intro</a></li>
    <li><a href="#examples">Examples</a></li>
    <!-- <li><a href="#contact">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label="Chapter navigation">
    <ul>
      <li><a href="#one">One</a></li>
      <li><a href="#two">Two</a></li>
      <li><a href="#three">Three</a></li>
    </ul>
</nav>

""";

t.Str(Content);
var Pattern = t.Pattern("<li>{item}</li>");
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

Console.WriteLine("<!-- Skip over commented lines -->");
Console.WriteLine("----------------------------------");
t.SkipOver("<!-- {comment} -->");
t.Find();
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

#define tf(IsTrue) ((IsTrue) ? "True" : "False")

int main() {
   uCalc uc;
   // StatementSensitive() is set to false so that ";" and newline are not treated as special

   auto t = uc.NewTransformer();
   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << "Setting StatementSensitive to False" << endl;

   t.DefaultRuleSet().StatementSensitive(false); // so that newline does not behave as a statement separator

   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << "" << endl;

   auto Content =
   R"(
<nav aria-label="Main navigation">
  <ul>
    <li><a href="#intro">Intro</a></li>
    <li><a href="#examples">Examples</a></li>
    <!-- <li><a href="#contact">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label="Chapter navigation">
    <ul>
      <li><a href="#one">One</a></li>
      <li><a href="#two">Two</a></li>
      <li><a href="#three">Three</a></li>
    </ul>
</nav>
)";

   t.Str(Content);
   auto Pattern = t.Pattern("<li>{item}</li>");
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

   cout << "<!-- Skip over commented lines -->" << endl;
   cout << "----------------------------------" << endl;
   t.SkipOver("<!-- {comment} -->");
   t.Find();
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

}
				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// StatementSensitive() is set to false so that ";" and newline are not treated as special
      
      Dim t = uc.NewTransformer()
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine("Setting StatementSensitive to False")
      
      t.DefaultRuleSet.StatementSensitive = false '// so that newline does not behave as a statement separator
      
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine("")
      
      Dim Content =
      "
<nav aria-label=""Main navigation"">
  <ul>
    <li><a href=""#intro"">Intro</a></li>
    <li><a href=""#examples"">Examples</a></li>
    <!-- <li><a href=""#contact"">Contact</a></li> -->
  </ul>
</nav>

<!-- 
<h2>Ingredients</h2>
<ul>
  <li>3 cups flour</li>
  <li>1.5 cups water</li>
  <li>1 tsp salt</li>
</ul>
-->

<nav aria-label=""Chapter navigation"">
    <ul>
      <li><a href=""#one"">One</a></li>
      <li><a href=""#two"">Two</a></li>
      <li><a href=""#three"">Three</a></li>
    </ul>
</nav>
"
      
      t.Str(Content)
      Dim Pattern = t.Pattern("<li>{item}</li>")
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
      Console.WriteLine("<!-- Skip over commented lines -->")
      Console.WriteLine("----------------------------------")
      t.SkipOver("<!-- {comment} -->")
      t.Find()
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
   End Sub
End Module
				
			
StatementSensitive: True
Setting StatementSensitive to False
StatementSensitive: False

<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#contact">Contact</a></li>
<li>3 cups flour</li>
<li>1.5 cups water</li>
<li>1 tsp salt</li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>

<!-- Skip over commented lines -->
----------------------------------
<li><a href="#intro">Intro</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
StatementSensitive()
				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2";
var p = t.Pattern("if {etc}");

Console.WriteLine($"Input: {t.Text}");
Console.WriteLine($"Pattern: {p.Pattern}");
Console.WriteLine("");

t.Find();
Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");

t.DefaultRuleSet.StatementSensitive = false;
t.Find();
Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}");
Console.WriteLine(t.Matches.Text);
				
			
Input: x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2
Pattern: if {etc}

StatementSensitive: True
if (true) func1(3+4)

StatementSensitive: False
if (true) func1(3+4); else func2(x*y); y = x + 2
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

#define tf(IsTrue) ((IsTrue) ? "True" : "False")

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   t.Text("x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2");
   auto p = t.Pattern("if {etc}");

   cout << "Input: " << t.Text() << endl;
   cout << "Pattern: " << p.Pattern() << endl;
   cout << "" << endl;

   t.Find();
   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << t.Matches().Text() << endl;
   cout << "" << endl;

   t.DefaultRuleSet().StatementSensitive(false);
   t.Find();
   cout << "StatementSensitive: " << tf(t.DefaultRuleSet().StatementSensitive()) << endl;
   cout << t.Matches().Text() << endl;
}
				
			
Input: x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2
Pattern: if {etc}

StatementSensitive: True
if (true) func1(3+4)

StatementSensitive: False
if (true) func1(3+4); else func2(x*y); y = x + 2
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      t.Text = "x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2"
      Dim p = t.Pattern("if {etc}")
      
      Console.WriteLine($"Input: {t.Text}")
      Console.WriteLine($"Pattern: {p.Pattern}")
      Console.WriteLine("")
      
      t.Find()
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("")
      
      t.DefaultRuleSet.StatementSensitive = false
      t.Find()
      Console.WriteLine($"StatementSensitive: {t.DefaultRuleSet.StatementSensitive}")
      Console.WriteLine(t.Matches.Text)
   End Sub
End Module
				
			
Input: x = 1; if (true) func1(3+4); else func2(x*y); y = x + 2
Pattern: if {etc}

StatementSensitive: True
if (true) func1(3+4)

StatementSensitive: False
if (true) func1(3+4); else func2(x*y); y = x + 2