Using Multiple Tokens As Operators

I wrote a domain specific language for my rule engine to ensure that non programmers can write validation rules for business models.

Here are some examples:

if x is greater than 5 then error ""
if x is equal to 7 then error ""

The standard way to define operators used in Silverfly can only handle one token operators. This problem can be solved in two ways. Either create your own matcher to lex those keywords in the specific order as single token or you can create a parselet that can handle multiple tokens as operator. In this sample I will write my own matcher that produces a combined token.

public class MultipleTokenOperatorMatcher : IMatcher
{
    public static readonly string[] Operators = ["is less than", "is greather than", "is equal to"];

    public bool Match(Lexer lexer, char c)
    {
        return Operators.Any(op => lexer.IsMatch(op));
    }

    public Token Build(Lexer lexer, ref int index, ref int column, ref int line)
    {
        var oldColumn = column;
        var oldIndex = index;

        string type = null;
        foreach (var op in Operators)
        {
            if (lexer.AdvanceIfMatch(op))
            {
                type = op;
                break;
            }
        }

        return new(op, lexer.Document.Source[oldIndex..index], line, oldColumn, lexer.Document);
    }
}

You can register those tokens as own operators:

protected override void InitParser(ParserDefinition def)
{
   def.InfixLeft("is less than", DefaultPrecedenceLevels.Sum);
   def.InfixLeft("is greater than", DefaultPrecedenceLevels.Sum);
   def.InfixLeft("is equal to", DefaultPrecedenceLevels.Sum);
}

Last updated