I write simple math tokenizer and try to use new C# pattern matching
feature.
Tokenizer is quite simple:
public IEnumerable<IToken> Tokenize(string input)
{
const char decimalSeparator = '.';
string inputWithoutSpaces = input.Replace(" ", string.Empty);
var numberBuffer = new StringBuilder();
var letterBuffer = new StringBuilder();
foreach (char c in inputWithoutSpaces)
{
switch (c)
{
case var _ when IsTerm(c, letterBuffer):
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
yield return new Operator('*');
}
letterBuffer.Append(c);
break;
case decimalSeparator:
case var _ when IsDigit(c):
numberBuffer.Append(c);
break;
case var _ when IsOperator(c):
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
}
if (letterBuffer.Length > 0)
{
yield return EmptyLetterBufferAsTerm(letterBuffer);
}
yield return new Operator(c);
break;
}
}
if (numberBuffer.Length > 0)
{
yield return EmptyNumberBufferAsLiteral(numberBuffer);
}
if (letterBuffer.Length > 0)
{
yield return EmptyLetterBufferAsTerm(letterBuffer);
}
}
I'm using case var _
because I want to match by condition without using if-else if
chain, but I'm unable to write case when
without specifying var variableName
.
Is there any fancy way to perform such operation? Or it is recommended way to do these things?
There is a "fancy" way to do pattern matching like this, using what are commonly called active patterns. C# doesn't (yet) support active patterns though, but see this answer for an example of what they might look like if/when implemented.
So using active patterns, your code would end up looking something like:
switch (c)
{
case Term(letterBuffer):
...
break;
case decimalSeparator:
case Digit():
...
break;
case Operator():
...
break;
}
If you'd like to see this feature in a future version of C#, please upvote it on the csharplang github repo.
In the meantime, then you are limited choosing between sticking with if
statements as others have said, or using when guards as you are. Which you go for really is just a matter of preferred style.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With