Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for default Field #12

Merged
merged 2 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading