uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026

Warning

uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.

Tag = [int]

Property

Product: 

Class: 

Gets or sets a user-defined integer value, allowing for fast, programmatic identification and categorization of rules at runtime.

Remarks

🏷️ Tagging Rules for Programmatic Identification

The Tag property allows you to associate a custom integer identifier with any Rule. This is a powerful mechanism for categorizing rules and identifying which pattern generated a specific Match at runtime, without relying on slower string comparisons.

⚙️ Getter and Setter Behavior

This property functions as both a getter and a setter, following the standard property syntax:

  • Getter: var myTag = myRule.Tag;Retrieves the integer tag associated with the rule. If no tag has been set, it defaults to 0.

  • Setter: myRule.Tag = 123;Assigns an integer tag to the rule. The setter SetTag() function supports a fluent interface, returning the Rule object itself to allow for method chaining.

🎯 Primary Use Cases

Tag is the preferred method for programmatically identifying rules because comparing integers is significantly faster than comparing strings from Name() or Description().

  • Syntax Highlighting: In a code editor, you can create rules for keywords, strings, and comments, each with a unique tag (e.g., 1 for keyword, 2 for string). When processing matches, you can check the Match.Rule().Tag() to determine which color or style to apply.

  • Building an Abstract Syntax Tree (AST): When building a custom parser, you can use tags to represent token types or node types in your grammar (e.g., TAG_IDENTIFIER, TAG_OPERATOR).

  • State Machines: In a multi-stage transformation, tags can represent different states, allowing you to easily identify which rule corresponds to which state transition.

💡 Why uCalc? (Comparative Analysis)

In a standard Regex-based system, there is no built-in way to attach metadata like a numeric tag to a pattern. A developer would need to manage this association externally, which is cumbersome and less efficient.

Without uCalc:

// Manual, external mappingvar ruleMappings = new Dictionary<Regex, int>{    { new Regex(@"\b(if|else|for)\b"), 1 }, // Tag 1 for keywords    { new Regex(@"""[^\"]*""""), 2 }        // Tag 2 for strings};// ... must then manually find which Regex produced a match ...

With uCalc:csharp
// Integrated, declarative approach
var keywordRule = t.Pattern("{if|else|for}").SetTag(1);
var stringRule = t.Pattern("{@String}").SetTag(2);
// ... later, simply check match.Rule().Tag() ...

uCalc's integrated Tag property provides a cleaner, more declarative, and higher-performance solution by keeping the identifying metadata tightly coupled with the rule itself.

Examples

How to set and get tags for different rules.

ID: 994

				
					using uCalcSoftware;

var uc = new uCalc();
var t = new uCalc.Transformer();
var ruleA = t.Pattern("A").SetTag(10);
var ruleB = t.Pattern("B").SetTag(20);

Console.WriteLine($"Tag for Rule A: {ruleA.Tag}");
Console.WriteLine($"Tag for Rule B: {ruleB.Tag}");
				
			
Tag for Rule A: 10
Tag for Rule B: 20
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc::Transformer t;
   auto ruleA = t.Pattern("A").SetTag(10);
   auto ruleB = t.Pattern("B").SetTag(20);

   cout << "Tag for Rule A: " << ruleA.Tag() << endl;
   cout << "Tag for Rule B: " << ruleB.Tag() << endl;
}
				
			
Tag for Rule A: 10
Tag for Rule B: 20
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t As New uCalc.Transformer()
      Dim ruleA = t.Pattern("A").SetTag(10)
      Dim ruleB = t.Pattern("B").SetTag(20)
      
      Console.WriteLine($"Tag for Rule A: {ruleA.Tag}")
      Console.WriteLine($"Tag for Rule B: {ruleB.Tag}")
   End Sub
End Module
				
			
Tag for Rule A: 10
Tag for Rule B: 20
A practical example using tags to build a simple syntax highlighter that categorizes matches.

ID: 995

				
					using uCalcSoftware;

var uc = new uCalc();
// Practical: Basic Syntax Highlighter
var t = new uCalc.Transformer();

// Define categories with integer tags
var TAG_KEYWORD = 1;
var TAG_STRING = 2;
var TAG_COMMENT = 3;

// Define rules and tag them
t.Pattern("{ if | else | for | while }").SetTag(TAG_KEYWORD);
t.Pattern("{@String}").SetTag(TAG_STRING);
t.Pattern("// {text}").SetTag(TAG_COMMENT);

t.Text = """
for (i=0; i<10; i++) { s = "hello"; // comment }
""";
t.Find();

foreach(var match in t.Matches) {
   var tag = match.Rule.Tag;
   if (tag == TAG_KEYWORD) {
      Console.WriteLine($"TAG_KEYWORD: {match.Text}");
   } else if (tag == TAG_STRING) {
      Console.WriteLine($"TAG_STRING: {match.Text}");
   } else if (tag == TAG_COMMENT) {
      Console.WriteLine($"TAG_COMMENT: {match.Text}");
   }
}
				
			
TAG_KEYWORD: for
TAG_STRING: "hello"
TAG_COMMENT: // comment 
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // Practical: Basic Syntax Highlighter
   uCalc::Transformer t;

   // Define categories with integer tags
   auto TAG_KEYWORD = 1;
   auto TAG_STRING = 2;
   auto TAG_COMMENT = 3;

   // Define rules and tag them
   t.Pattern("{ if | else | for | while }").SetTag(TAG_KEYWORD);
   t.Pattern("{@String}").SetTag(TAG_STRING);
   t.Pattern("// {text}").SetTag(TAG_COMMENT);

   t.Text(R"(for (i=0; i<10; i++) { s = "hello"; // comment })");
   t.Find();

   for(auto match : t.Matches()) {
      auto tag = match.Rule().Tag();
      if (tag == TAG_KEYWORD) {
         cout << "TAG_KEYWORD: " << match.Text() << endl;
      } else if (tag == TAG_STRING) {
         cout << "TAG_STRING: " << match.Text() << endl;
      } else if (tag == TAG_COMMENT) {
         cout << "TAG_COMMENT: " << match.Text() << endl;
      }
   }
}
				
			
TAG_KEYWORD: for
TAG_STRING: "hello"
TAG_COMMENT: // comment 
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// Practical: Basic Syntax Highlighter
      Dim t As New uCalc.Transformer()
      
      '// Define categories with integer tags
      Dim TAG_KEYWORD = 1
      Dim TAG_STRING = 2
      Dim TAG_COMMENT = 3
      
      '// Define rules and tag them
      t.Pattern("{ if | else | for | while }").SetTag(TAG_KEYWORD)
      t.Pattern("{@String}").SetTag(TAG_STRING)
      t.Pattern("// {text}").SetTag(TAG_COMMENT)
      
      t.Text = "for (i=0; i<10; i++) { s = ""hello""; // comment }"
      t.Find()
      
      For Each match In t.Matches
         Dim tag = match.Rule.Tag
         If tag = TAG_KEYWORD Then
            Console.WriteLine($"TAG_KEYWORD: {match.Text}")
            ElseIf tag = TAG_STRING Then
            Console.WriteLine($"TAG_STRING: {match.Text}")
            ElseIf tag = TAG_COMMENT Then
            Console.WriteLine($"TAG_COMMENT: {match.Text}")
         End If
      Next
   End Sub
End Module
				
			
TAG_KEYWORD: for
TAG_STRING: "hello"
TAG_COMMENT: // comment 
Internal Test: Verifies rule precedence and tag retrieval by traversing the overload chain with NextOverload.

ID: 996

				
					using uCalcSoftware;

var uc = new uCalc();
// Internal Test: Verifies precedence and tag retrieval via NextOverload
var t = new uCalc.Transformer();
t.Text = "Testing (a b c) Testing x y z! Testing 1 2 3.";

// Rules defined last have higher precedence for the same anchor ("Testing")
var p1 = t.Pattern("Testing {etc}.").SetTag(111);
var p2 = t.Pattern("Testing {etc}!").SetTag(222);
var p3 = t.Pattern("Testing ({etc})").SetTag(333);

// Get the highest precedence rule via Pattern's return value
var highestPriorityRule = p3;
Console.WriteLine($"Highest priority rule tag: {highestPriorityRule.Tag}");

// Walk the overload chain
var midPriorityRule = highestPriorityRule.NextOverload();
Console.WriteLine($"Mid priority rule tag: {midPriorityRule.Tag}");

var lowPriorityRule = midPriorityRule.NextOverload();
Console.WriteLine($"Low priority rule tag: {lowPriorityRule.Tag}");

// The end of the chain should have a tag of 0 (default)
var endOfChain = lowPriorityRule.NextOverload();
Console.WriteLine($"End of chain tag: {endOfChain.Tag}");
				
			
Highest priority rule tag: 333
Mid priority rule tag: 222
Low priority rule tag: 111
End of chain tag: 0
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // Internal Test: Verifies precedence and tag retrieval via NextOverload
   uCalc::Transformer t;
   t.Text("Testing (a b c) Testing x y z! Testing 1 2 3.");

   // Rules defined last have higher precedence for the same anchor ("Testing")
   auto p1 = t.Pattern("Testing {etc}.").SetTag(111);
   auto p2 = t.Pattern("Testing {etc}!").SetTag(222);
   auto p3 = t.Pattern("Testing ({etc})").SetTag(333);

   // Get the highest precedence rule via Pattern's return value
   auto highestPriorityRule = p3;
   cout << "Highest priority rule tag: " << highestPriorityRule.Tag() << endl;

   // Walk the overload chain
   auto midPriorityRule = highestPriorityRule.NextOverload();
   cout << "Mid priority rule tag: " << midPriorityRule.Tag() << endl;

   auto lowPriorityRule = midPriorityRule.NextOverload();
   cout << "Low priority rule tag: " << lowPriorityRule.Tag() << endl;

   // The end of the chain should have a tag of 0 (default)
   auto endOfChain = lowPriorityRule.NextOverload();
   cout << "End of chain tag: " << endOfChain.Tag() << endl;
}
				
			
Highest priority rule tag: 333
Mid priority rule tag: 222
Low priority rule tag: 111
End of chain tag: 0
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// Internal Test: Verifies precedence and tag retrieval via NextOverload
      Dim t As New uCalc.Transformer()
      t.Text = "Testing (a b c) Testing x y z! Testing 1 2 3."
      
      '// Rules defined last have higher precedence for the same anchor ("Testing")
      Dim p1 = t.Pattern("Testing {etc}.").SetTag(111)
      Dim p2 = t.Pattern("Testing {etc}!").SetTag(222)
      Dim p3 = t.Pattern("Testing ({etc})").SetTag(333)
      
      '// Get the highest precedence rule via Pattern's return value
      Dim highestPriorityRule = p3
      Console.WriteLine($"Highest priority rule tag: {highestPriorityRule.Tag}")
      
      '// Walk the overload chain
      Dim midPriorityRule = highestPriorityRule.NextOverload()
      Console.WriteLine($"Mid priority rule tag: {midPriorityRule.Tag}")
      
      Dim lowPriorityRule = midPriorityRule.NextOverload()
      Console.WriteLine($"Low priority rule tag: {lowPriorityRule.Tag}")
      
      '// The end of the chain should have a tag of 0 (default)
      Dim endOfChain = lowPriorityRule.NextOverload()
      Console.WriteLine($"End of chain tag: {endOfChain.Tag}")
   End Sub
End Module
				
			
Highest priority rule tag: 333
Mid priority rule tag: 222
Low priority rule tag: 111
End of chain tag: 0
Rule NextOverload and Tag

ID: 131

				
					using uCalcSoftware;

var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "Testing (a b c) Testing x y z! Testing 1 2 3.";

var Pattern1 = t.Pattern("Testing {etc}.").SetTag(111);
var Pattern2 = t.Pattern("Testing {etc}!").SetTag(222);
var Pattern3 = t.Pattern("Testing ({etc})").SetTag(333);

t.Find();
Console.WriteLine("--- Matches ---");
Console.WriteLine(t.Matches.Text);
Console.WriteLine("--- Patterns ---");
Console.WriteLine(Pattern1.Pattern);
Console.WriteLine(Pattern2.Pattern);
Console.WriteLine(Pattern3.Pattern);
Console.WriteLine("---- Tags ----");
Console.WriteLine(Pattern1.Tag);
Console.WriteLine(Pattern2.Tag);
Console.WriteLine(Pattern3.Tag);
Console.WriteLine("-- Overload Tags --");
// Note that most recently defined patterns come first
Console.WriteLine(Pattern3.NextOverload().Tag);
Console.WriteLine(Pattern2.NextOverload().Tag);
Console.WriteLine(Pattern1.NextOverload().Tag);


				
			
--- Matches ---
Testing (a b c)
Testing x y z!
Testing 1 2 3.
--- Patterns ---
Testing {etc}.
Testing {etc}!
Testing ({etc})
---- Tags ----
111
222
333
-- Overload Tags --
222
111
0
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   auto t = uc.NewTransformer();
   t.Text("Testing (a b c) Testing x y z! Testing 1 2 3.");

   auto Pattern1 = t.Pattern("Testing {etc}.").SetTag(111);
   auto Pattern2 = t.Pattern("Testing {etc}!").SetTag(222);
   auto Pattern3 = t.Pattern("Testing ({etc})").SetTag(333);

   t.Find();
   cout << "--- Matches ---" << endl;
   cout << t.Matches().Text() << endl;
   cout << "--- Patterns ---" << endl;
   cout << Pattern1.Pattern() << endl;
   cout << Pattern2.Pattern() << endl;
   cout << Pattern3.Pattern() << endl;
   cout << "---- Tags ----" << endl;
   cout << Pattern1.Tag() << endl;
   cout << Pattern2.Tag() << endl;
   cout << Pattern3.Tag() << endl;
   cout << "-- Overload Tags --" << endl;
   // Note that most recently defined patterns come first
   cout << Pattern3.NextOverload().Tag() << endl;
   cout << Pattern2.NextOverload().Tag() << endl;
   cout << Pattern1.NextOverload().Tag() << endl;


}
				
			
--- Matches ---
Testing (a b c)
Testing x y z!
Testing 1 2 3.
--- Patterns ---
Testing {etc}.
Testing {etc}!
Testing ({etc})
---- Tags ----
111
222
333
-- Overload Tags --
222
111
0
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim t = uc.NewTransformer()
      t.Text = "Testing (a b c) Testing x y z! Testing 1 2 3."
      
      Dim Pattern1 = t.Pattern("Testing {etc}.").SetTag(111)
      Dim Pattern2 = t.Pattern("Testing {etc}!").SetTag(222)
      Dim Pattern3 = t.Pattern("Testing ({etc})").SetTag(333)
      
      t.Find()
      Console.WriteLine("--- Matches ---")
      Console.WriteLine(t.Matches.Text)
      Console.WriteLine("--- Patterns ---")
      Console.WriteLine(Pattern1.Pattern)
      Console.WriteLine(Pattern2.Pattern)
      Console.WriteLine(Pattern3.Pattern)
      Console.WriteLine("---- Tags ----")
      Console.WriteLine(Pattern1.Tag)
      Console.WriteLine(Pattern2.Tag)
      Console.WriteLine(Pattern3.Tag)
      Console.WriteLine("-- Overload Tags --")
      '// Note that most recently defined patterns come first
      Console.WriteLine(Pattern3.NextOverload().Tag)
      Console.WriteLine(Pattern2.NextOverload().Tag)
      Console.WriteLine(Pattern1.NextOverload().Tag)
      
      
   End Sub
End Module
				
			
--- Matches ---
Testing (a b c)
Testing x y z!
Testing 1 2 3.
--- Patterns ---
Testing {etc}.
Testing {etc}!
Testing ({etc})
---- Tags ----
111
222
333
-- Overload Tags --
222
111
0