Skip to content

Commit

Permalink
Merge pull request #22 from bytedance/feat/support_single_feature_parse
Browse files Browse the repository at this point in the history
Feat/support single feature parse
  • Loading branch information
AoranAllen authored Jul 25, 2024
2 parents 1ad8cca + 0aae0f4 commit 16962c5
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
4 changes: 2 additions & 2 deletions arishem/arishem_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestBuildCondition(t *testing.T) {
expr, err := condGroup.Build()
assert.Nil(t, err)
assert.NotEmpty(t, expr)
assert.Equal(t, `{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1}},"Rhs":{"Const":{"NumConst":9223372036854775807}}}]}`, expr)
assert.Equal(t, `{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1.0}},"Rhs":{"Const":{"NumConst":9223372036854775807}}}]}`, expr)

cond2 := NewCondition(ListIn, NOT)
var varPath VarExpr = "user.user_list#2.name"
Expand All @@ -48,7 +48,7 @@ func TestBuildCondition(t *testing.T) {
expr, err = condGroup.Build()
assert.Nil(t, err)
assert.NotEmpty(t, expr)
assert.Equal(t, `{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1}},"Rhs":{"Const":{"NumConst":9223372036854775807}}},{"Operator":"!LIST_IN","Lhs":{"VarExpr":"user.user_list#2.name"},"Rhs":{"ConstList":[{"StrConst":"Jack"},{"StrConst":"Jane"},{"StrConst":"John"},{"StrConst":"Ezreal"}]}}]}`, expr)
assert.Equal(t, `{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1.0}},"Rhs":{"Const":{"NumConst":9223372036854775807}}},{"Operator":"!LIST_IN","Lhs":{"VarExpr":"user.user_list#2.name"},"Rhs":{"ConstList":[{"StrConst":"Jack"},{"StrConst":"Jane"},{"StrConst":"John"},{"StrConst":"Ezreal"}]}}]}`, expr)

pass, err := JudgeConditionWithFactMeta(context.Background(), expr, `{"user":{"user_list":[{"name":"Aatrox"},{"name":"Ahri"},{"name":"Ezreal"},{"name":"MalPhite"}]}}`)
assert.Nil(t, err)
Expand Down
15 changes: 15 additions & 0 deletions arishem/arishem_lw_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"errors"
"github.com/antlr/antlr4/runtime/Go/antlr/v4"
"github.com/bytedance/arishem/internal/core"
"github.com/bytedance/arishem/internal/parser"
"github.com/bytedance/arishem/tools"
"github.com/bytedance/arishem/typedef"
"strings"
Expand Down Expand Up @@ -109,6 +110,20 @@ func ParseRuleTree(expr string, exprType ExprType) (exprTree *RuleTree, err erro
return
}

// ParseSingleFeature input a feature expression string and return the typedef.FeatureParam
func ParseSingleFeature(featureExpr string) (typedef.FeatureParam, error) {
fppl := core.NewFeaturePreParseListener()
err := parser.ParseSingleExpr(featureExpr, fppl)
if err != nil {
return nil, err
}
featureParams := fppl.Data()
if len(featureParams) <= 0 {
return nil, errors.New("parse failed: empty feature params")
}
return featureParams[0], nil
}

// WalkAim will try to parse the aimExpr into the antlr parse tree and visit it to get the result, err will not be null when parse aim expression failed.
func WalkAim(aimExpr string, dc typedef.DataCtx, opts ...ExecuteOption) (aim typedef.Aim, err error) {
var tree *RuleTree
Expand Down
52 changes: 52 additions & 0 deletions arishem/arishem_lw_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,55 @@ func TestWalkAim(t *testing.T) {
testCase.check(WalkAim(testCase.aimExpr, dc))
}
}

func TestParseFeature(t *testing.T) {
testCases := []*struct {
featExpr string
check func(fp typedef.FeatureParam, err error)
}{
{
`{"FeatureExpr":{"FeaturePath":"Hit_Knowledge_Count","BuiltinParam":{"Knowledge_id":{"ConstList":[{"NumConst":7348866865063544851},{"NumConst":7348866865063790611}]},"Start_time":{"Const":{"StrConst":"2024-01-01"}}}}}`,
func(fp typedef.FeatureParam, err error) {
assert.Nil(t, fp)
assert.NotNil(t, err)
fmt.Printf("%v\n", err)
},
},
{
`{"FeatureExpr":{"FeaturePath":"Hit_Knowledge_Count.xxxx","BuiltinParam":{"Knowledge_id":{"ConstList":[{"NumConst":7348866865063544851},{"NumConst":7348866865063790611}]},"Start_time":{"Const":{"StrConst":"2024-01-01"}}}}}`,
func(fp typedef.FeatureParam, err error) {
assert.Nil(t, err)
assert.NotNil(t, fp)
assert.NotNil(t, fp.BuiltinParam())
assert.Equal(t, fp.FeatureName(), "Hit_Knowledge_Count")
idList := fp.BuiltinParam()["Knowledge_id"]
assert.NotEmpty(t, idList)
for _, i := range idList.([]interface{}) {
fmt.Printf("%v\n", i)
}

},
},
{
`{"FeatureExpr":{"FeaturePath":"user_center.user_personality"}}`,
func(fp typedef.FeatureParam, err error) {
assert.Nil(t, err)
assert.NotNil(t, fp)
assert.Nil(t, fp.BuiltinParam())
assert.Equal(t, fp.FeatureName(), "user_center")
},
},
{
`{"MathExpr":{"OpMath":">","ParamList":[{"Const":{"NumConst":100}},{"Const":{"NumConst":20}}]}}`,
func(fp typedef.FeatureParam, err error) {
assert.Nil(t, fp)
assert.NotNil(t, err)
fmt.Printf("%v\n", err)
},
},
}
for _, testCase := range testCases {
featParam, err := ParseSingleFeature(testCase.featExpr)
testCase.check(featParam, err)
}
}
27 changes: 26 additions & 1 deletion internal/parser/arishem_ctx_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,32 @@ import (
"strings"
)

//ParseArishemCondition parse condition group context from expression string, return an error if syntax is not valid.
func ParseSingleExpr(expr string, pos typedef.ParseObserver) error {
if pos == nil {
return errors.New("feature parse observer is nil")
}
// parse listener
cl := NewCachedListener()
ruleParser, err := parseArishemRuleFromStr(expr, cl.tokenCEL)
if err != nil {
return err
}
if !cl.CheckSyntaxValid() {
return cl.GenerateError()
}
// remove error default listeners
ruleParser.RemoveErrorListeners()
// add parse listener
ruleParser.AddErrorListener(cl.parseCEL)

cl.AddListenerProxy(pos)
ruleParser.AddParseListener(cl)

_ = ruleParser.Expr()
return nil
}

// ParseArishemCondition parse condition group context from expression string, return an error if syntax is not valid.
func ParseArishemCondition(expr string, pos ...typedef.ParseObserver) (ICondEntityContext, error) {
// parse listener
cl := NewCachedListener()
Expand Down

0 comments on commit 16962c5

Please sign in to comment.