1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-02 09:21:54 +02:00

Added support of using keywords in namespaces (#481)

* Added support of using keywords in namespaces

* Added true and false

* Removed unnecessary string case
This commit is contained in:
Tim Voronov 2020-04-28 17:30:47 -04:00 committed by GitHub
parent 7d7253325e
commit 7b2ed4c662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1076 additions and 740 deletions

3
.gitignore vendored
View File

@ -133,4 +133,5 @@ dist
coverage.txt
# sometimes antlr generates stub
**/.antlr
**/.antlr
gen

View File

@ -2,6 +2,7 @@ package compiler_test
import (
"context"
"fmt"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
@ -78,4 +79,74 @@ func TestFunctionNSCall(t *testing.T) {
So(err, ShouldNotBeNil)
})
Convey("Should use keywords", t, func() {
c := compiler.New()
keywords := []string{
"And",
"Or",
"For",
"Return",
"Distinct",
"Filter",
"Sort",
"Limit",
"Let",
"Collect",
"Desc",
"Asc",
"None",
"Null",
"True",
"False",
"Use",
"Into",
"Keep",
"With",
"Count",
"All",
"Any",
"Aggregate",
"Like",
"Not",
"In",
}
for _, kw := range keywords {
segment := kw
err := c.Namespace("T").Namespace(segment).RegisterFunction("TEST", func(ctx context.Context, args ...core.Value) (core.Value, error) {
return values.True, nil
})
So(err, ShouldBeNil)
err = c.Namespace("T").Namespace(segment).RegisterFunction(segment, func(ctx context.Context, args ...core.Value) (core.Value, error) {
return values.True, nil
})
So(err, ShouldBeNil)
p, err := c.Compile(fmt.Sprintf(`
RETURN T::%s::TEST()
`, segment))
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
p, err = c.Compile(fmt.Sprintf(`
RETURN T::%s::%s()
`, segment, segment))
So(err, ShouldBeNil)
out = p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
}
})
}

View File

@ -1171,7 +1171,7 @@ func (v *visitor) doVisitFunctionCallExpression(context *fql.FunctionCallExpress
name += funcNS.GetText()
}
name += context.Identifier().GetText()
name += context.FunctionIdentifier().GetText()
fun, exists := v.funcs.Get(name)

View File

@ -44,22 +44,23 @@ SortDirection=43
None=44
Null=45
BooleanLiteral=46
Into=47
Keep=48
With=49
Count=50
All=51
Any=52
Aggregate=53
Like=54
Not=55
In=56
Param=57
Identifier=58
StringLiteral=59
IntegerLiteral=60
FloatLiteral=61
NamespaceSegment=62
Use=47
Into=48
Keep=49
With=50
Count=51
All=52
Any=53
Aggregate=54
Like=55
Not=56
In=57
Param=58
Identifier=59
StringLiteral=60
IntegerLiteral=61
FloatLiteral=62
NamespaceSegment=63
':'=5
';'=6
'.'=7
@ -97,13 +98,14 @@ NamespaceSegment=62
'COLLECT'=42
'NONE'=44
'NULL'=45
'INTO'=47
'KEEP'=48
'WITH'=49
'COUNT'=50
'ALL'=51
'ANY'=52
'AGGREGATE'=53
'LIKE'=54
'IN'=56
'@'=57
'USE'=47
'INTO'=48
'KEEP'=49
'WITH'=50
'COUNT'=51
'ALL'=52
'ANY'=53
'AGGREGATE'=54
'LIKE'=55
'IN'=57
'@'=58

View File

@ -223,8 +223,37 @@ namespace
: (NamespaceSegment)*
;
functionIdentifier
: Identifier
| And
| Or
| For
| Return
| Distinct
| Filter
| Sort
| Limit
| Let
| Collect
| SortDirection
| None
| Null
| BooleanLiteral
| Use
| Into
| Keep
| With
| Count
| All
| Any
| Aggregate
| Like
| Not
| In
;
functionCallExpression
: namespace Identifier arguments
: namespace functionIdentifier arguments
;
member

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -304,6 +304,12 @@ func (s *BaseFqlParserListener) EnterNamespace(ctx *NamespaceContext) {}
// ExitNamespace is called when production namespace is exited.
func (s *BaseFqlParserListener) ExitNamespace(ctx *NamespaceContext) {}
// EnterFunctionIdentifier is called when production functionIdentifier is entered.
func (s *BaseFqlParserListener) EnterFunctionIdentifier(ctx *FunctionIdentifierContext) {}
// ExitFunctionIdentifier is called when production functionIdentifier is exited.
func (s *BaseFqlParserListener) ExitFunctionIdentifier(ctx *FunctionIdentifierContext) {}
// EnterFunctionCallExpression is called when production functionCallExpression is entered.
func (s *BaseFqlParserListener) EnterFunctionCallExpression(ctx *FunctionCallExpressionContext) {}

View File

@ -195,6 +195,10 @@ func (v *BaseFqlParserVisitor) VisitNamespace(ctx *NamespaceContext) interface{}
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFunctionIdentifier(ctx *FunctionIdentifierContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFunctionCallExpression(ctx *FunctionCallExpressionContext) interface{} {
return v.VisitChildren(ctx)
}

View File

@ -148,6 +148,9 @@ type FqlParserListener interface {
// EnterNamespace is called when entering the namespace production.
EnterNamespace(c *NamespaceContext)
// EnterFunctionIdentifier is called when entering the functionIdentifier production.
EnterFunctionIdentifier(c *FunctionIdentifierContext)
// EnterFunctionCallExpression is called when entering the functionCallExpression production.
EnterFunctionCallExpression(c *FunctionCallExpressionContext)
@ -337,6 +340,9 @@ type FqlParserListener interface {
// ExitNamespace is called when exiting the namespace production.
ExitNamespace(c *NamespaceContext)
// ExitFunctionIdentifier is called when exiting the functionIdentifier production.
ExitFunctionIdentifier(c *FunctionIdentifierContext)
// ExitFunctionCallExpression is called when exiting the functionCallExpression production.
ExitFunctionCallExpression(c *FunctionCallExpressionContext)

View File

@ -148,6 +148,9 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#namespace.
VisitNamespace(ctx *NamespaceContext) interface{}
// Visit a parse tree produced by FqlParser#functionIdentifier.
VisitFunctionIdentifier(ctx *FunctionIdentifierContext) interface{}
// Visit a parse tree produced by FqlParser#functionCallExpression.
VisitFunctionCallExpression(ctx *FunctionCallExpressionContext) interface{}