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.
IndexOf
Method
Product:
Class:
Gets the zero-based index of a token definition, which determines its precedence in the matching order.
Syntax
Parameters
Return
int32
The zero-based index of the token definition in the collection, representing its precedence rank. Returns -1 if the token is not found.
Remarks
The IndexOf method finds the zero-based position of a specific token definition within the collection. This index is not just an arbitrary position; it directly corresponds to the token's precedence.
⚙️ Precedence: Higher Index Wins
uCalc's tokenizer evaluates token patterns in a Last-In, First-Out (LIFO) order. This means:
- The most recently added token has the highest index (
Count() - 1) and is checked first. - The first token added (or the oldest built-in token) has the lowest index (
0) and is checked last.
A higher index means higher precedence. This method is the primary tool for programmatically querying the precedence rank of any token.
🎯 Use Cases
- Debugging: Verify the order in which tokens are being evaluated to resolve matching conflicts.
- Dynamic Analysis: Write code that can inspect a
Tokenscollection and understand its precedence hierarchy at runtime. - Advanced Configuration: Programmatically insert tokens at specific indices (using other overloads of
AddorInsert) and then useIndexOfto confirm their final precedence.
If the specified token is not found in the collection, the method returns -1.
💡 Why uCalc? (Comparative Analysis)
vs. Static Lexers (ANTLR, Flex/Bison): In traditional parser generators, token precedence is often implicit, determined by the order of rules in a static grammar file. There is no simple, programmatic way to query a token's rank at runtime. uCalc's
IndexOfmakes precedence a first-class, inspectable property of its dynamic lexical model.vs. Standard
IndexOf: Unlike a typicalIndexOfmethod that just finds an element's position in a list, this method's return value has direct semantic meaning for the parser's behavior. This makes it a powerful introspection tool rather than a simple collection utility.
Examples
A succinct demonstration of how adding tokens affects their index and, therefore, their precedence.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
var tokens = t.Tokens;
tokens.Clear();
tokens.Add("."); // Add a fallback token at index 0
// The order of definition determines the index (precedence)
var tokenA = tokens.Add("A");
var tokenB = tokens.Add("B");
Console.WriteLine($"Index of A: {tokens.IndexOf(tokenA)}"); // Will have a lower index
Console.WriteLine($"Index of B: {tokens.IndexOf(tokenB)}"); // Will have a higher index, thus higher precedence
Index of A: 1
Index of B: 2 using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); var tokens = t.Tokens; tokens.Clear(); tokens.Add("."); // Add a fallback token at index 0 // The order of definition determines the index (precedence) var tokenA = tokens.Add("A"); var tokenB = tokens.Add("B"); Console.WriteLine($"Index of A: {tokens.IndexOf(tokenA)}"); // Will have a lower index Console.WriteLine($"Index of B: {tokens.IndexOf(tokenB)}"); // Will have a higher index, thus higher precedence
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
auto tokens = t.Tokens();
tokens.Clear();
tokens.Add("."); // Add a fallback token at index 0
// The order of definition determines the index (precedence)
auto tokenA = tokens.Add("A");
auto tokenB = tokens.Add("B");
cout << "Index of A: " << tokens.IndexOf(tokenA) << endl; // Will have a lower index
cout << "Index of B: " << tokens.IndexOf(tokenB) << endl; // Will have a higher index, thus higher precedence
}
Index of A: 1
Index of B: 2 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; auto tokens = t.Tokens(); tokens.Clear(); tokens.Add("."); // Add a fallback token at index 0 // The order of definition determines the index (precedence) auto tokenA = tokens.Add("A"); auto tokenB = tokens.Add("B"); cout << "Index of A: " << tokens.IndexOf(tokenA) << endl; // Will have a lower index cout << "Index of B: " << tokens.IndexOf(tokenB) << endl; // Will have a higher index, thus higher precedence }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
Dim tokens = t.Tokens
tokens.Clear()
tokens.Add(".") '// Add a fallback token at index 0
'// The order of definition determines the index (precedence)
Dim tokenA = tokens.Add("A")
Dim tokenB = tokens.Add("B")
Console.WriteLine($"Index of A: {tokens.IndexOf(tokenA)}") '// Will have a lower index
Console.WriteLine($"Index of B: {tokens.IndexOf(tokenB)}") '// Will have a higher index, thus higher precedence
End Sub
End Module
Index of A: 1
Index of B: 2 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() Dim tokens = t.Tokens tokens.Clear() tokens.Add(".") '// Add a fallback token at index 0 '// The order of definition determines the index (precedence) Dim tokenA = tokens.Add("A") Dim tokenB = tokens.Add("B") Console.WriteLine($"Index of A: {tokens.IndexOf(tokenA)}") '// Will have a lower index Console.WriteLine($"Index of B: {tokens.IndexOf(tokenB)}") '// Will have a higher index, thus higher precedence End Sub End Module
Internal Test: Verifies the LIFO precedence order and the return value for a token not present in the collection.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
var tokens = t.Tokens;
tokens.Clear();
tokens.Add("."); // Fallback
var tokenPlus = tokens.Add("[+]");
var tokenStar = tokens.Add("[*]");
var tokenCaret = tokens.Add("^");
// LIFO order means precedence is: '^' > '*' > '+'
Console.WriteLine("Precedence Check:");
Console.WriteLine($"Caret (^) > Star (*): {tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)}");
Console.WriteLine($"Star (*) > Plus (+): {tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)}");
// Test for a token not in this collection
var t2 = new uCalc.Transformer();
var unaddedToken = t2.Tokens.Add("unrelated");
Console.WriteLine($"Index of un-added token: {tokens.IndexOf(unaddedToken)}");
Precedence Check:
Caret (^) > Star (*): True
Star (*) > Plus (+): True
Index of un-added token: -1 using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); var tokens = t.Tokens; tokens.Clear(); tokens.Add("."); // Fallback var tokenPlus = tokens.Add("[+]"); var tokenStar = tokens.Add("[*]"); var tokenCaret = tokens.Add("^"); // LIFO order means precedence is: '^' > '*' > '+' Console.WriteLine("Precedence Check:"); Console.WriteLine($"Caret (^) > Star (*): {tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)}"); Console.WriteLine($"Star (*) > Plus (+): {tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)}"); // Test for a token not in this collection var t2 = new uCalc.Transformer(); var unaddedToken = t2.Tokens.Add("unrelated"); Console.WriteLine($"Index of un-added token: {tokens.IndexOf(unaddedToken)}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
#define tf(IsTrue) ((IsTrue) ? "True" : "False")
int main() {
uCalc uc;
uCalc::Transformer t;
auto tokens = t.Tokens();
tokens.Clear();
tokens.Add("."); // Fallback
auto tokenPlus = tokens.Add("[+]");
auto tokenStar = tokens.Add("[*]");
auto tokenCaret = tokens.Add("^");
// LIFO order means precedence is: '^' > '*' > '+'
cout << "Precedence Check:" << endl;
cout << "Caret (^) > Star (*): " << tf(tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)) << endl;
cout << "Star (*) > Plus (+): " << tf(tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)) << endl;
// Test for a token not in this collection
uCalc::Transformer t2;
auto unaddedToken = t2.Tokens().Add("unrelated");
cout << "Index of un-added token: " << tokens.IndexOf(unaddedToken) << endl;
}
Precedence Check:
Caret (^) > Star (*): True
Star (*) > Plus (+): True
Index of un-added token: -1 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; #define tf(IsTrue) ((IsTrue) ? "True" : "False") int main() { uCalc uc; uCalc::Transformer t; auto tokens = t.Tokens(); tokens.Clear(); tokens.Add("."); // Fallback auto tokenPlus = tokens.Add("[+]"); auto tokenStar = tokens.Add("[*]"); auto tokenCaret = tokens.Add("^"); // LIFO order means precedence is: '^' > '*' > '+' cout << "Precedence Check:" << endl; cout << "Caret (^) > Star (*): " << tf(tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)) << endl; cout << "Star (*) > Plus (+): " << tf(tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)) << endl; // Test for a token not in this collection uCalc::Transformer t2; auto unaddedToken = t2.Tokens().Add("unrelated"); cout << "Index of un-added token: " << tokens.IndexOf(unaddedToken) << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
Dim tokens = t.Tokens
tokens.Clear()
tokens.Add(".") '// Fallback
Dim tokenPlus = tokens.Add("[+]")
Dim tokenStar = tokens.Add("[*]")
Dim tokenCaret = tokens.Add("^")
'// LIFO order means precedence is: '^' > '*' > '+'
Console.WriteLine("Precedence Check:")
Console.WriteLine($"Caret (^) > Star (*): {tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)}")
Console.WriteLine($"Star (*) > Plus (+): {tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)}")
'// Test for a token not in this collection
Dim t2 As New uCalc.Transformer()
Dim unaddedToken = t2.Tokens.Add("unrelated")
Console.WriteLine($"Index of un-added token: {tokens.IndexOf(unaddedToken)}")
End Sub
End Module
Precedence Check:
Caret (^) > Star (*): True
Star (*) > Plus (+): True
Index of un-added token: -1 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() Dim tokens = t.Tokens tokens.Clear() tokens.Add(".") '// Fallback Dim tokenPlus = tokens.Add("[+]") Dim tokenStar = tokens.Add("[*]") Dim tokenCaret = tokens.Add("^") '// LIFO order means precedence is: '^' > '*' > '+' Console.WriteLine("Precedence Check:") Console.WriteLine($"Caret (^) > Star (*): {tokens.IndexOf(tokenCaret) > tokens.IndexOf(tokenStar)}") Console.WriteLine($"Star (*) > Plus (+): {tokens.IndexOf(tokenStar) > tokens.IndexOf(tokenPlus)}") '// Test for a token not in this collection Dim t2 As New uCalc.Transformer() Dim unaddedToken = t2.Tokens.Add("unrelated") Console.WriteLine($"Index of un-added token: {tokens.IndexOf(unaddedToken)}") End Sub End Module
Displays the complete list of default token definitions, showing their type, internal name, and regex pattern.
using uCalcSoftware;
var uc = new uCalc();
// Lists all tokens currently defined for the expression evaluator.
Console.WriteLine($"Token Count: {uc.ExpressionTokens.Count}");
Console.WriteLine("");
Console.WriteLine("Index Type Name: regex");
Console.WriteLine("========================");
var Tokens = uc.ExpressionTokens;
foreach(var token in Tokens) {
Console.Write(Tokens.IndexOf(token));
Console.WriteLine($" {token.Description} {token.Name}: {token.Regex}");
}
// Note that the expression evaluator token list has a few extra tokens,
// related to hex/bin/oct notation, string interpolation, and imaginary number
// notation, which are not found in the default Transformer token list.
Token Count: 30
Index Type Name: regex
========================
0 generic _token_line: .*
1 generic _token_catchall: .
2 generic _token_catchall_utf8_other: [\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]|[\xc0-\xdf][\x80-\xbf]
3 generic _token_punctuation: (--|\.{3}|\xE2\x80\xA6|[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]|\xE2\x80[\x90-\x95])
4 generic _token_quotechar: ("){3}|"|'
5 generic _token_quotechar_single: '
6 generic _token_quotechar_double: "
7 generic _token_quotechar_tripledouble: """
8 memberaccess _token_memberaccess: \.
9 generic _token_variableargs: \.\.\.
10 reducible _token_reducible2: [-:|+/*^&=%@!`\\<>?#$~]+
11 bracket _token_parenthesis: \(
12 bracketclose _token_parenthesis_close: \)
13 bracket _token_curlybrace: \{
14 bracketclose _token_curlybrace_close: \}
15 bracket _token_squarebracket: \[
16 bracketclose _token_squarebracket_close: \]
17 argseparator _token_argseparator: ,
18 statementseparator _token_newline: (?:\r?\n)|\r
19 statementseparator _token_semicolon: ;
20 literal _token_string_singlequoted: '([^']*(?:''[^']*)*)'
21 literal _token_string_doublequoted: "([^"]*(?:""[^"]*)*)"
22 literal _token_string_tripledoublequoted: """([\s\S]*?)"""
23 whitespace _token_whitespace: [\t\v ]+
24 reducible _token_reducible: [-:|+/*^&=%@!`\\<>?]+
25 literal _token_floatnumber: [0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?
26 alphanumeric _token_alphanumeric: [a-zA-Z_][a-zA-Z0-9_]*
27 literal _token_imaginaryunit: #i
28 tokentransform _token_binaryhexoctalnotation: #[bho][0-9A-F]+
29 tokentransform _token_stringinterpolationquote: \$['"] using uCalcSoftware; var uc = new uCalc(); // Lists all tokens currently defined for the expression evaluator. Console.WriteLine($"Token Count: {uc.ExpressionTokens.Count}"); Console.WriteLine(""); Console.WriteLine("Index Type Name: regex"); Console.WriteLine("========================"); var Tokens = uc.ExpressionTokens; foreach(var token in Tokens) { Console.Write(Tokens.IndexOf(token)); Console.WriteLine($" {token.Description} {token.Name}: {token.Regex}"); } // Note that the expression evaluator token list has a few extra tokens, // related to hex/bin/oct notation, string interpolation, and imaginary number // notation, which are not found in the default Transformer token list.
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// Lists all tokens currently defined for the expression evaluator.
cout << "Token Count: " << uc.ExpressionTokens().Count() << endl;
cout << "" << endl;
cout << "Index Type Name: regex" << endl;
cout << "========================" << endl;
auto Tokens = uc.ExpressionTokens();
for(auto token : Tokens) {
cout << Tokens.IndexOf(token);
cout << " " << token.Description() << " " << token.Name() << ": " << token.Regex() << endl;
}
// Note that the expression evaluator token list has a few extra tokens,
// related to hex/bin/oct notation, string interpolation, and imaginary number
// notation, which are not found in the default Transformer token list.
}
Token Count: 30
Index Type Name: regex
========================
0 generic _token_line: .*
1 generic _token_catchall: .
2 generic _token_catchall_utf8_other: [\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]|[\xc0-\xdf][\x80-\xbf]
3 generic _token_punctuation: (--|\.{3}|\xE2\x80\xA6|[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]|\xE2\x80[\x90-\x95])
4 generic _token_quotechar: ("){3}|"|'
5 generic _token_quotechar_single: '
6 generic _token_quotechar_double: "
7 generic _token_quotechar_tripledouble: """
8 memberaccess _token_memberaccess: \.
9 generic _token_variableargs: \.\.\.
10 reducible _token_reducible2: [-:|+/*^&=%@!`\\<>?#$~]+
11 bracket _token_parenthesis: \(
12 bracketclose _token_parenthesis_close: \)
13 bracket _token_curlybrace: \{
14 bracketclose _token_curlybrace_close: \}
15 bracket _token_squarebracket: \[
16 bracketclose _token_squarebracket_close: \]
17 argseparator _token_argseparator: ,
18 statementseparator _token_newline: (?:\r?\n)|\r
19 statementseparator _token_semicolon: ;
20 literal _token_string_singlequoted: '([^']*(?:''[^']*)*)'
21 literal _token_string_doublequoted: "([^"]*(?:""[^"]*)*)"
22 literal _token_string_tripledoublequoted: """([\s\S]*?)"""
23 whitespace _token_whitespace: [\t\v ]+
24 reducible _token_reducible: [-:|+/*^&=%@!`\\<>?]+
25 literal _token_floatnumber: [0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?
26 alphanumeric _token_alphanumeric: [a-zA-Z_][a-zA-Z0-9_]*
27 literal _token_imaginaryunit: #i
28 tokentransform _token_binaryhexoctalnotation: #[bho][0-9A-F]+
29 tokentransform _token_stringinterpolationquote: \$['"] #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // Lists all tokens currently defined for the expression evaluator. cout << "Token Count: " << uc.ExpressionTokens().Count() << endl; cout << "" << endl; cout << "Index Type Name: regex" << endl; cout << "========================" << endl; auto Tokens = uc.ExpressionTokens(); for(auto token : Tokens) { cout << Tokens.IndexOf(token); cout << " " << token.Description() << " " << token.Name() << ": " << token.Regex() << endl; } // Note that the expression evaluator token list has a few extra tokens, // related to hex/bin/oct notation, string interpolation, and imaginary number // notation, which are not found in the default Transformer token list. }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// Lists all tokens currently defined for the expression evaluator.
Console.WriteLine($"Token Count: {uc.ExpressionTokens.Count}")
Console.WriteLine("")
Console.WriteLine("Index Type Name: regex")
Console.WriteLine("========================")
Dim Tokens = uc.ExpressionTokens
For Each token In Tokens
Console.Write(Tokens.IndexOf(token))
Console.WriteLine($" {token.Description} {token.Name}: {token.Regex}")
Next
'// Note that the expression evaluator token list has a few extra tokens,
'// related to hex/bin/oct notation, string interpolation, and imaginary number
'// notation, which are not found in the default Transformer token list.
End Sub
End Module
Token Count: 30
Index Type Name: regex
========================
0 generic _token_line: .*
1 generic _token_catchall: .
2 generic _token_catchall_utf8_other: [\xf0-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]|[\xc0-\xdf][\x80-\xbf]
3 generic _token_punctuation: (--|\.{3}|\xE2\x80\xA6|[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]|\xE2\x80[\x90-\x95])
4 generic _token_quotechar: ("){3}|"|'
5 generic _token_quotechar_single: '
6 generic _token_quotechar_double: "
7 generic _token_quotechar_tripledouble: """
8 memberaccess _token_memberaccess: \.
9 generic _token_variableargs: \.\.\.
10 reducible _token_reducible2: [-:|+/*^&=%@!`\\<>?#$~]+
11 bracket _token_parenthesis: \(
12 bracketclose _token_parenthesis_close: \)
13 bracket _token_curlybrace: \{
14 bracketclose _token_curlybrace_close: \}
15 bracket _token_squarebracket: \[
16 bracketclose _token_squarebracket_close: \]
17 argseparator _token_argseparator: ,
18 statementseparator _token_newline: (?:\r?\n)|\r
19 statementseparator _token_semicolon: ;
20 literal _token_string_singlequoted: '([^']*(?:''[^']*)*)'
21 literal _token_string_doublequoted: "([^"]*(?:""[^"]*)*)"
22 literal _token_string_tripledoublequoted: """([\s\S]*?)"""
23 whitespace _token_whitespace: [\t\v ]+
24 reducible _token_reducible: [-:|+/*^&=%@!`\\<>?]+
25 literal _token_floatnumber: [0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?
26 alphanumeric _token_alphanumeric: [a-zA-Z_][a-zA-Z0-9_]*
27 literal _token_imaginaryunit: #i
28 tokentransform _token_binaryhexoctalnotation: #[bho][0-9A-F]+
29 tokentransform _token_stringinterpolationquote: \$['"] Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// Lists all tokens currently defined for the expression evaluator. Console.WriteLine($"Token Count: {uc.ExpressionTokens.Count}") Console.WriteLine("") Console.WriteLine("Index Type Name: regex") Console.WriteLine("========================") Dim Tokens = uc.ExpressionTokens For Each token In Tokens Console.Write(Tokens.IndexOf(token)) Console.WriteLine($" {token.Description} {token.Name}: {token.Regex}") Next '// Note that the expression evaluator token list has a few extra tokens, '// related to hex/bin/oct notation, string interpolation, and imaginary number '// notation, which are not found in the default Transformer token list. End Sub End Module