Skip to content

Commit

Permalink
support default field
Browse files Browse the repository at this point in the history
  • Loading branch information
sidhant92 committed Nov 6, 2023
1 parent fb590a9 commit b921dac
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 16 deletions.
20 changes: 12 additions & 8 deletions internal/parser/antlr/antlr_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@ import (
)

type ANTLRParser struct {
UseCache bool
cache *lru.Cache[string, domain.Node]
UseCache bool
cache *lru.Cache[string, domain.Node]
}

func Default() *ANTLRParser {
return &ANTLRParser{
UseCache: false,
cache: nil,
UseCache: false,
cache: nil,
}
}

func Cached(size int) *ANTLRParser {
cache, _ := lru.New[string, domain.Node](size)
return &ANTLRParser{
UseCache: true,
cache: cache,
UseCache: true,
cache: cache,
}
}

func (p *ANTLRParser) Parse(input string) (res domain.Node, err error) {
func (p *ANTLRParser) Parse(input string, defaultField ...string) (res domain.Node, err error) {
defer func() {
if r := recover(); r != nil {
log.Println("panic occurred:", r)
Expand All @@ -56,7 +56,11 @@ func (p *ANTLRParser) Parse(input string) (res domain.Node, err error) {
lexer := lib.NewBooleanExpressionLexer(inputStream)
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
antlrParser := lib.NewBooleanExpressionParser(stream)
listener := New()
var df = ""
if len(defaultField) > 0 {
df = defaultField[0]
}
listener := New(df)
antlr.ParseTreeWalkerDefault.Walk(listener, antlrParser.Parse())
if p.UseCache {
p.cache.Add(input, listener.GetResult())
Expand Down
26 changes: 22 additions & 4 deletions internal/parser/antlr/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ type myListener struct {
Result domain.Node

OperatorService *service.OperatorService

DefaultField string
}

func New() *myListener {
func New(defaultField string) *myListener {
l := myListener{
Nodes: []domain.Node{},
LastToken: nil,
Result: nil,
OperatorService: service.NewOperatorService(),
DefaultField: defaultField,
}
return &l
}
Expand Down Expand Up @@ -132,7 +135,8 @@ func (l *myListener) ExitTypesExpression(c *lib.TypesExpressionContext) {
}

func (l *myListener) ExitInExpression(c *lib.InExpressionContext) {
field := c.GetField().GetText()
l.ValidateField(c.GetField(), c.GetText())
field := l.GetField(c.GetField().GetText())

typesContextFilter := func(tree antlr.Tree) bool { return reflect.TypeOf(tree) == reflect.TypeOf(&lib.TypesContext{}) }
var typesContextChildren = util.Filter(c.GetData().GetChildren(), typesContextFilter)
Expand All @@ -154,7 +158,8 @@ func (l *myListener) ExitInExpression(c *lib.InExpressionContext) {
}

func (l *myListener) ExitToExpression(c *lib.ToExpressionContext) {
field := c.GetField().GetText()
l.ValidateField(c.GetField(), c.GetText())
field := l.GetField(c.GetField().GetText())
lowerDataType := GetDataType(c.GetLower().GetStart())
lowerValue, _ := util.ConvertValue(c.GetLower().GetStart().GetText(), lowerDataType)
upperDataType := GetDataType(c.GetUpper().GetStart())
Expand Down Expand Up @@ -189,7 +194,7 @@ func (l *myListener) ExitNotExpression(c *lib.NotExpressionContext) {
}

func (l *myListener) ExitComparatorExpression(c *lib.ComparatorExpressionContext) {
field := c.GetLeft().GetText()
field := l.GetField(c.GetLeft().GetText())
dataType := GetDataType(c.GetRight().GetStart())
value, _ := util.ConvertValue(c.GetRight().GetText(), dataType)
operator := l.OperatorService.GetOperatorFromSymbol(c.GetOp().GetText())
Expand Down Expand Up @@ -249,3 +254,16 @@ func GetDataType(token antlr.Token) constant.DataType {
return constant.STRING
}
}

func (l myListener) ValidateField(token antlr.Token, text string) {
if token == nil || (len(token.GetText()) == 0 && len(text) == 0) {
panic("Invalid Expression, field and default value both are empty")
}
}

func (l myListener) GetField(field string) string {
if len(field) == 0 {
return l.DefaultField
}
return field
}
4 changes: 2 additions & 2 deletions pkg/application/boolean_expression_evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ type BooleanExpressionEvaluator struct {
OperatorService *service.OperatorService
}

func (b *BooleanExpressionEvaluator) Evaluate(expression string, data map[string]interface{}) (bool, error) {
node, err := b.Parser.Parse(expression)
func (b *BooleanExpressionEvaluator) Evaluate(expression string, data map[string]interface{}, defaultField ...string) (bool, error) {
node, err := b.Parser.Parse(expression, defaultField...)
if err != nil {
return false, err
}
Expand Down
18 changes: 18 additions & 0 deletions pkg/application/boolean_expression_evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,21 @@ func TestStringEqualityWithQuotes(t *testing.T) {
assert.Nil(t, err)
assert.True(t, res)
}

func TestDefaultFieldTrue(t *testing.T) {
data := map[string]interface{}{
"age": 19,
}
res, err := evaluator.Evaluate(">= 18 AND < 20", data, "age")
assert.Nil(t, err)
assert.True(t, res)
}

func TestDefaultFieldFalse(t *testing.T) {
data := map[string]interface{}{
"age": 17,
}
res, err := evaluator.Evaluate(">= 18 AND < 20", data, "age")
assert.Nil(t, err)
assert.False(t, res)
}
4 changes: 3 additions & 1 deletion pkg/error/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ var INVALID_DATA_TYPE = errors.New("invalid data type")

var INVALID_UNARY_OPERAND = errors.New("invalid unary operand")

var KEY_DATA_NOT_PRESENT = errors.New("key data not present")
var KEY_DATA_NOT_PRESENT = errors.New("key data not present")

var INVALID_EXPRESSION = errors.New("invalid expression")
2 changes: 1 addition & 1 deletion pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

type Parser interface {
Parse(input string) (domain.Node, error)
Parse(input string, defaultField ...string) (domain.Node, error)
}

func New() Parser {
Expand Down

0 comments on commit b921dac

Please sign in to comment.