1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-01-20 03:29:51 +02:00

Feature/#263 waitfor event (#590)

* Added new WAITFOR syntax

* Added support of event options

* Added support of options

* Added support of using WAITFOR EVENT in variable assignment
This commit is contained in:
Tim Voronov 2021-07-13 21:34:22 -04:00 committed by GitHub
parent e6c18ebb84
commit 742bdae0ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 6156 additions and 4786 deletions

View File

@ -6,6 +6,7 @@ import IframePage from './pages/iframes/index.js';
import MediaPage from './pages/media/index.js';
import PaginationPage from './pages/pagination/index.js';
import ListsPage from './pages/lists/index.js';
import NavigationPage from './pages/navigation/index.js';
const e = React.createElement;
const Router = ReactRouter.Router;
@ -66,6 +67,10 @@ export default React.memo(function AppComponent(params = {}) {
path: '/lists',
component: ListsPage
}),
e(Route, {
path: '/navigation',
component: NavigationPage
}),
]),
redirectTo
])

View File

@ -0,0 +1,44 @@
const e = React.createElement;
export default class NavigationPage extends React.Component {
constructor(props) {
super(props);
this.state = {
url: "",
};
this.handleTextInput = (evt) => {
evt.preventDefault();
this.setState({
url: evt.target.value
});
};
this.handleClick = () => {
window.location.href = this.state.url;
};
}
render() {
return e("div", { id: "navigation" }, [
e("div", { className: "form-group" }, [
e("label", null, "Url"),
e("input", {
id: "url",
type: "text",
className: "form-control",
onChange: this.handleTextInput
}),
e("input", {
id: "submit",
type: "button",
value: "Go",
className: "form-control",
onClick: this.handleClick
}),
])
])
}
}

View File

@ -0,0 +1,12 @@
LET url = @lab.cdn.dynamic + "?redirect=/iframe&src=/iframe"
LET page = DOCUMENT(url, { driver: 'cdp' })
LET original = FIRST(FRAMES(page, "name", "nested"))
INPUT(original, "#url_input", "https://getbootstrap.com/")
CLICK(original, "#submit")
WAITFOR EVENT "navigation" IN page OPTIONS { frame: original }
LET current = FIRST(FRAMES(page, "name", "nested"))
RETURN T::EQ(current.URL, "https://getbootstrap.com/")

View File

@ -0,0 +1,9 @@
LET url = @lab.cdn.dynamic + "/#/navigation"
LET page = DOCUMENT(url, { driver: 'cdp' })
INPUT(page, "#url", "https://getbootstrap.com/")
CLICK(page, "#submit")
WAITFOR EVENT "navigation" IN page
RETURN T::EQ(page.URL, "https://getbootstrap.com/")

View File

@ -55,7 +55,7 @@ func (c *Compiler) Compile(query string) (program *runtime.Program, err error) {
}()
p := parser.New(query)
p.AddErrorListener(&errorListener{})
p.AddErrorListener(newErrorListener())
l := newVisitor(query, c.funcs)

View File

@ -248,4 +248,18 @@ func TestLet(t *testing.T) {
So(err, ShouldNotBeNil)
})
Convey("Should use value returned from WAITFOR EVENT", t, func() {
out, err := newCompilerWithObservable().MustCompile(`
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event", "data", 100)
LET res = (WAITFOR EVENT "event" IN obj)
RETURN res
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, `"data"`)
})
}

View File

@ -106,7 +106,7 @@ func TestLikeOperator(t *testing.T) {
c := compiler.New()
out1, err := c.MustCompile(`
RETURN true ? false : ("foo" NOT LIKE "b*")s
RETURN true ? false : ("foo" NOT LIKE "b*")
`).Run(context.Background())
So(err, ShouldBeNil)

View File

@ -272,26 +272,56 @@ func TestMember(t *testing.T) {
Convey("Deep computed path", func() {
c := compiler.New()
p, err := c.Compile(`
LET obj = {
first: {
second: {
third: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
}
p := c.MustCompile(`
LET o1 = {
first: {
second: {
["third"]: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
}
RETURN obj["first"]["second"]["third"]["fourth"]["fifth"].bottom
LET o2 = { prop: "third" }
RETURN o1["first"]["second"][o2.prop]["fourth"]["fifth"].bottom
`)
out, err := p.Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, `true`)
})
Convey("Deep computed path 2", func() {
c := compiler.New()
p := c.MustCompile(`
LET o1 = {
first: {
second: {
third: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
}
LET o2 = { prop: "third" }
RETURN o1.first["second"][o2.prop].fourth["fifth"]["bottom"]
`)
out, err := p.Run(context.Background())
So(err, ShouldBeNil)

View File

@ -232,4 +232,18 @@ func TestReturn(t *testing.T) {
So(err, ShouldBeNil)
So(string(out), ShouldEqual, "{\"a\":\"foo\"}")
})
Convey("Should compile RETURN (WAITFOR EVENT \"event\" IN obj)", t, func() {
c := newCompilerWithObservable()
out, err := c.MustCompile(`
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event", "data", 100)
RETURN (WAITFOR EVENT "event" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out), ShouldEqual, `"data"`)
})
}

View File

@ -13,7 +13,7 @@ func TestTernaryOperator(t *testing.T) {
c := compiler.New()
p, err := c.Compile(`
FOR i IN [1, 2, 3, 4, 5, 6]
RETURN i < 3 ? i * 3 : i * 2;
RETURN i < 3 ? i * 3 : i * 2
`)
So(err, ShouldBeNil)

View File

@ -0,0 +1,110 @@
package compiler_test
import (
"context"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestWaitforEventWithinTernaryExpression(t *testing.T) {
Convey("RETURN foo ? TRUE : (WAITFOR EVENT \"event\" IN obj)", t, func() {
c := newCompilerWithObservable()
out1, err := c.MustCompile(`
LET foo = FALSE
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event", "data", 100)
RETURN foo ? TRUE : (WAITFOR EVENT "event" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out1), ShouldEqual, `"data"`)
out2, err := c.MustCompile(`
LET foo = TRUE
LET obj = X::CREATE()
RETURN foo ? TRUE : (WAITFOR EVENT "event" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out2), ShouldEqual, `true`)
})
Convey("RETURN foo ? (WAITFOR EVENT \"event1\" IN obj) : (WAITFOR EVENT \"event2\" IN obj)", t, func() {
c := newCompilerWithObservable()
out1, err := c.MustCompile(`
LET foo = FALSE
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event2", "data2", 100)
RETURN foo ? (WAITFOR EVENT "event1" IN obj) : (WAITFOR EVENT "event2" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out1), ShouldEqual, `"data2"`)
out2, err := c.MustCompile(`
LET foo = TRUE
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event1", "data1", 100)
RETURN foo ? (WAITFOR EVENT "event1" IN obj) : (WAITFOR EVENT "event2" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out2), ShouldEqual, `"data1"`)
})
Convey("RETURN foo ? (FOR i IN 1..3 RETURN i*2) : (WAITFOR EVENT \"event2\" IN obj)", t, func() {
c := newCompilerWithObservable()
out1, err := c.MustCompile(`
LET foo = FALSE
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event", "data", 100)
RETURN foo ? (FOR i IN 1..3 RETURN i*2) : (WAITFOR EVENT "event" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out1), ShouldEqual, `"data"`)
out2, err := c.MustCompile(`
LET foo = TRUE
LET obj = X::CREATE()
RETURN foo ? (FOR i IN 1..3 RETURN i*2) : (WAITFOR EVENT "event" IN obj)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out2), ShouldEqual, `[2,4,6]`)
})
Convey("RETURN foo ? (WAITFOR EVENT \"event\" IN obj) : (FOR i IN 1..3 RETURN i*2) ", t, func() {
c := newCompilerWithObservable()
out1, err := c.MustCompile(`
LET foo = FALSE
LET obj = X::CREATE()
RETURN foo ? (WAITFOR EVENT "event" IN obj) : (FOR i IN 1..3 RETURN i*2)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out1), ShouldEqual, `[2,4,6]`)
out2, err := c.MustCompile(`
LET foo = TRUE
LET obj = X::CREATE()
X::EMIT_WITH(obj, "event", "data", 100)
RETURN foo ? (WAITFOR EVENT "event" IN obj) : (FOR i IN 1..3 RETURN i*2)
`).Run(context.Background())
So(err, ShouldBeNil)
So(string(out2), ShouldEqual, `"data"`)
})
}

View File

@ -0,0 +1,231 @@
package compiler_test
import (
"context"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/events"
"github.com/MontFerret/ferret/pkg/runtime/values"
. "github.com/smartystreets/goconvey/convey"
"testing"
"time"
)
type MockedObservable struct {
*values.Object
subscribers map[string]chan events.Event
Args map[string][]*values.Object
}
func NewMockedObservable() *MockedObservable {
return &MockedObservable{
Object: values.NewObject(),
subscribers: map[string]chan events.Event{},
Args: map[string][]*values.Object{},
}
}
func (m *MockedObservable) Emit(eventName string, args core.Value, err error, timeout int64) {
ch := make(chan events.Event)
m.subscribers[eventName] = ch
go func() {
<-time.After(time.Millisecond * time.Duration(timeout))
ch <- events.Event{
Data: args,
Err: err,
}
}()
}
func (m *MockedObservable) Subscribe(_ context.Context, eventName string, opts *values.Object) <-chan events.Event {
calls, found := m.Args[eventName]
if !found {
calls = make([]*values.Object, 0, 10)
m.Args[eventName] = calls
}
m.Args[eventName] = append(calls, opts)
return m.subscribers[eventName]
}
func newCompilerWithObservable() *compiler.Compiler {
c := compiler.New()
err := c.Namespace("X").
RegisterFunctions(core.NewFunctionsFromMap(
map[string]core.Function{
"CREATE": func(ctx context.Context, args ...core.Value) (core.Value, error) {
return NewMockedObservable(), nil
},
"EMIT": func(ctx context.Context, args ...core.Value) (core.Value, error) {
if err := core.ValidateArgs(args, 2, 3); err != nil {
return values.None, err
}
observable := args[0].(*MockedObservable)
eventName := values.ToString(args[1])
timeout := values.NewInt(100)
if len(args) > 2 {
timeout = values.ToInt(args[2])
}
observable.Emit(eventName.String(), values.None, nil, int64(timeout))
return values.None, nil
},
"EMIT_WITH": func(ctx context.Context, args ...core.Value) (core.Value, error) {
if err := core.ValidateArgs(args, 3, 4); err != nil {
return values.None, err
}
observable := args[0].(*MockedObservable)
eventName := values.ToString(args[1])
timeout := values.NewInt(100)
if len(args) > 3 {
timeout = values.ToInt(args[3])
}
observable.Emit(eventName.String(), args[2], nil, int64(timeout))
return values.None, nil
},
"EVENT": func(ctx context.Context, args ...core.Value) (core.Value, error) {
return values.NewString("test"), nil
},
},
))
So(err, ShouldBeNil)
return c
}
func TestWaitforEventExpression(t *testing.T) {
Convey("WAITFOR EVENT X IN Y", t, func() {
Convey("Should wait for a given event", func() {
c := newCompilerWithObservable()
prog := c.MustCompile(`
LET obj = X::CREATE()
X::EMIT(obj, "test", 100)
WAITFOR EVENT "test" IN obj
RETURN NONE
`)
_, err := prog.Run(context.Background())
So(err, ShouldBeNil)
})
Convey("Should wait for a given event using variable", func() {
c := newCompilerWithObservable()
prog := c.MustCompile(`
LET obj = X::CREATE()
LET eventName = "test"
X::EMIT(obj, eventName, 100)
WAITFOR EVENT eventName IN obj
RETURN NONE
`)
_, err := prog.Run(context.Background())
So(err, ShouldBeNil)
})
Convey("Should wait for a given event using object", func() {
c := newCompilerWithObservable()
prog := c.MustCompile(`
LET obj = X::CREATE()
LET evt = {
name: "test"
}
X::EMIT(obj, evt.name, 100)
WAITFOR EVENT evt.name IN obj
RETURN NONE
`)
_, err := prog.Run(context.Background())
So(err, ShouldBeNil)
})
Convey("Should wait for a given event using param", func() {
c := newCompilerWithObservable()
prog := c.MustCompile(`
LET obj = X::CREATE()
X::EMIT(obj, @evt, 100)
WAITFOR EVENT @evt IN obj
RETURN NONE
`)
_, err := prog.Run(context.Background(), runtime.WithParam("evt", "test"))
So(err, ShouldBeNil)
})
Convey("Should use options", func() {
observable := NewMockedObservable()
c := newCompilerWithObservable()
c.Namespace("X").RegisterFunction("SINGLETONE", func(ctx context.Context, args ...core.Value) (core.Value, error) {
return observable, nil
})
prog := c.MustCompile(`
LET obj = X::SINGLETONE()
X::EMIT(obj, "test", 1000)
WAITFOR EVENT "test" IN obj OPTIONS { value: "foo" }
RETURN NONE
`)
_, err := prog.Run(context.Background())
So(err, ShouldBeNil)
options := observable.Args["test"][0]
So(options, ShouldNotBeNil)
So(options.MustGet("value").String(), ShouldEqual, "foo")
})
Convey("Should timeout", func() {
c := newCompilerWithObservable()
prog := c.MustCompile(`
LET obj = X::CREATE()
X::EMIT(obj, @evt, 6000)
WAITFOR EVENT @evt IN obj
RETURN NONE
`)
_, err := prog.Run(context.Background(), runtime.WithParam("evt", "test"))
So(err, ShouldNotBeNil)
})
})
}

View File

@ -6,7 +6,19 @@ import (
)
type errorListener struct {
*antlr.DefaultErrorListener
*antlr.DiagnosticErrorListener
}
func newErrorListener() *errorListener {
return &errorListener{
antlr.NewDiagnosticErrorListener(false),
}
}
func (d *errorListener) ReportAttemptingFullContext(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ *antlr.BitSet, _ antlr.ATNConfigSet) {
}
func (d *errorListener) ReportContextSensitivity(_ antlr.Parser, _ *antlr.DFA, _, _, _ int, _ antlr.ATNConfigSet) {
}
func (d *errorListener) SyntaxError(_ antlr.Recognizer, _ interface{}, line, column int, msg string, _ antlr.RecognitionException) {

View File

@ -2,10 +2,6 @@ package compiler
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/MontFerret/ferret/pkg/parser/fql"
"github.com/MontFerret/ferret/pkg/runtime"
"github.com/MontFerret/ferret/pkg/runtime/collections"
@ -16,6 +12,9 @@ import (
"github.com/MontFerret/ferret/pkg/runtime/expressions/operators"
"github.com/antlr/antlr4/runtime/Go/antlr"
"github.com/pkg/errors"
"regexp"
"strconv"
"strings"
)
type (
@ -154,77 +153,52 @@ func (v *visitor) doVisitBody(ctx *fql.BodyContext, scope *scope) (core.Expressi
}
func (v *visitor) doVisitBodyStatement(ctx *fql.BodyStatementContext, scope *scope) (core.Expression, error) {
variable := ctx.VariableDeclaration()
if variable != nil {
if variable := ctx.VariableDeclaration(); variable != nil {
return v.doVisitVariableDeclaration(variable.(*fql.VariableDeclarationContext), scope)
}
funcCall := ctx.FunctionCallExpression()
if funcCall != nil {
if funcCall := ctx.FunctionCallExpression(); funcCall != nil {
return v.doVisitFunctionCallExpression(funcCall.(*fql.FunctionCallExpressionContext), scope)
}
if waitfor := ctx.WaitForExpression(); waitfor != nil {
return v.doVisitWaitForExpressionContext(waitfor.(*fql.WaitForExpressionContext), scope)
}
return nil, core.Error(ErrInvalidToken, ctx.GetText())
}
func (v *visitor) doVisitBodyExpression(ctx *fql.BodyExpressionContext, scope *scope) (core.Expression, error) {
forIn := ctx.ForExpression()
if forIn != nil {
return v.doVisitForExpression(forIn.(*fql.ForExpressionContext), scope)
if exp := ctx.ForExpression(); exp != nil {
return v.doVisitForExpression(exp.(*fql.ForExpressionContext), scope)
}
ret := ctx.ReturnExpression()
if ret != nil {
return v.doVisitReturnExpression(ret.(*fql.ReturnExpressionContext), scope)
if exp := ctx.ReturnExpression(); exp != nil {
return v.doVisitReturnExpression(exp.(*fql.ReturnExpressionContext), scope)
}
return nil, nil
return nil, core.Error(ErrInvalidToken, ctx.GetText())
}
func (v *visitor) doVisitReturnExpression(ctx *fql.ReturnExpressionContext, scope *scope) (core.Expression, error) {
var exp core.Expression
expCtx := ctx.Expression()
var out core.Expression
var err error
if expCtx != nil {
out, err := v.doVisitExpression(expCtx.(*fql.ExpressionContext), scope)
if err != nil {
return nil, err
}
exp = out
return expressions.NewReturnExpression(v.getSourceMap(ctx), exp)
if exp := ctx.ForExpression(); exp != nil {
out, err = v.doVisitForExpression(exp.(*fql.ForExpressionContext), scope.Fork())
} else if exp := ctx.WaitForExpression(); exp != nil {
out, err = v.doVisitWaitForExpressionContext(exp.(*fql.WaitForExpressionContext), scope)
} else if exp := ctx.Expression(); exp != nil {
out, err = v.doVisitExpression(exp.(*fql.ExpressionContext), scope)
} else {
return nil, core.Error(ErrInvalidToken, ctx.GetText())
}
forIn := ctx.ForExpression()
if forIn != nil {
out, err := v.doVisitForExpression(ctx.ForExpression().(*fql.ForExpressionContext), scope.Fork())
if err != nil {
return nil, err
}
exp = out
return expressions.NewReturnExpression(v.getSourceMap(ctx), exp)
if err != nil {
return nil, err
}
forInTernary := ctx.ForTernaryExpression()
if forInTernary != nil {
out, err := v.doVisitForTernaryExpression(forInTernary.(*fql.ForTernaryExpressionContext), scope)
if err != nil {
return nil, err
}
return expressions.NewReturnExpression(v.getSourceMap(ctx), out)
}
return nil, ErrNotImplemented
return expressions.NewReturnExpression(v.getSourceMap(ctx), out)
}
func (v *visitor) doVisitForExpression(ctx *fql.ForExpressionContext, scope *scope) (core.Expression, error) {
@ -233,13 +207,14 @@ func (v *visitor) doVisitForExpression(ctx *fql.ForExpressionContext, scope *sco
var keyVarName string
var ds collections.Iterable
valVar := ctx.ForExpressionValueVariable()
valVarName = valVar.GetText()
expVars := ctx.AllIdentifier()
keyVar := ctx.ForExpressionKeyVariable()
if len(expVars) > 0 {
valVarName = expVars[0].GetText()
}
if keyVar != nil {
keyVarName = keyVar.GetText()
if len(expVars) > 1 {
keyVarName = expVars[1].GetText()
}
isWhileLoop := ctx.In() == nil
@ -779,127 +754,186 @@ func (v *visitor) doVisitForExpressionStatement(ctx *fql.ForExpressionStatementC
return nil, v.unexpectedToken(ctx)
}
func (v *visitor) doVisitOptionsClause(ctx *fql.OptionsClauseContext, s *scope) (core.Expression, error) {
return v.doVisitObjectLiteral(ctx.ObjectLiteral().(*fql.ObjectLiteralContext), s)
}
func (v *visitor) doVisitWaitForEventNameContext(ctx *fql.WaitForEventNameContext, s *scope) (core.Expression, error) {
if str := ctx.StringLiteral(); str != nil {
return v.doVisitStringLiteral(str.(*fql.StringLiteralContext))
}
if variable := ctx.Variable(); variable != nil {
return v.doVisitVariable(variable.(*fql.VariableContext), s)
}
if param := ctx.Param(); param != nil {
return v.doVisitParamContext(param.(*fql.ParamContext), s)
}
if member := ctx.MemberExpression(); member != nil {
return v.doVisitMemberExpression(member.(*fql.MemberExpressionContext), s)
}
if fnCall := ctx.FunctionCallExpression(); fnCall != nil {
return v.doVisitFunctionCallExpression(fnCall.(*fql.FunctionCallExpressionContext), s)
}
return nil, ErrNotImplemented
}
func (v *visitor) doVisitWaitForEventSourceContext(ctx *fql.WaitForEventSourceContext, s *scope) (core.Expression, error) {
if variable := ctx.Variable(); variable != nil {
return v.doVisitVariable(variable.(*fql.VariableContext), s)
}
if member := ctx.MemberExpression(); member != nil {
return v.doVisitMemberExpression(member.(*fql.MemberExpressionContext), s)
}
if fnCall := ctx.FunctionCallExpression(); fnCall != nil {
return v.doVisitFunctionCallExpression(fnCall.(*fql.FunctionCallExpressionContext), s)
}
return nil, ErrNotImplemented
}
func (v *visitor) doVisitWaitForTimeoutValueContext(ctx *fql.WaitForTimeoutContext, s *scope) (core.Expression, error) {
if integer := ctx.IntegerLiteral(); integer != nil {
return v.doVisitIntegerLiteral(integer.(*fql.IntegerLiteralContext))
}
if variable := ctx.Variable(); variable != nil {
return v.doVisitVariable(variable.(*fql.VariableContext), s)
}
if member := ctx.MemberExpression(); member != nil {
return v.doVisitMemberExpression(member.(*fql.MemberExpressionContext), s)
}
if fnCall := ctx.FunctionCallExpression(); fnCall != nil {
return v.doVisitFunctionCallExpression(fnCall.(*fql.FunctionCallExpressionContext), s)
}
return nil, ErrNotImplemented
}
func (v *visitor) doVisitWaitForExpressionContext(ctx *fql.WaitForExpressionContext, s *scope) (core.Expression, error) {
var options core.Expression
if optionsCtx := ctx.OptionsClause(); optionsCtx != nil {
optionsExp, err := v.doVisitOptionsClause(optionsCtx.(*fql.OptionsClauseContext), s)
if err != nil {
return nil, errors.Wrap(err, "invalid options")
}
options = optionsExp
}
var timeout core.Expression
if timeoutCtx := ctx.WaitForTimeout(); timeoutCtx != nil {
timeoutExp, err := v.doVisitWaitForTimeoutValueContext(timeoutCtx.(*fql.WaitForTimeoutContext), s)
if err != nil {
return nil, errors.Wrap(err, "invalid timeout")
}
timeout = timeoutExp
}
if eventName := ctx.WaitForEventName(); eventName != nil {
eventName, err := v.doVisitWaitForEventNameContext(eventName.(*fql.WaitForEventNameContext), s)
if err != nil {
return nil, errors.Wrap(err, "invalid event name")
}
eventSource, err := v.doVisitWaitForEventSourceContext(ctx.WaitForEventSource().(*fql.WaitForEventSourceContext), s)
if err != nil {
return nil, errors.Wrap(err, "invalid event source")
}
return expressions.NewWaitForEventExpression(
v.getSourceMap(ctx),
eventName,
eventSource,
options,
timeout,
)
}
return nil, ErrInvalidToken
}
func (v *visitor) doVisitMemberExpression(ctx *fql.MemberExpressionContext, scope *scope) (core.Expression, error) {
member, err := v.doVisitMember(ctx.Member().(*fql.MemberContext), scope)
source, err := v.doVisitMemberExpressionSource(ctx.MemberExpressionSource().(*fql.MemberExpressionSourceContext), scope)
if err != nil {
return nil, err
}
children := ctx.MemberPath().GetChildren()
children := ctx.AllMemberExpressionPath()
path := make([]core.Expression, 0, len(children))
for _, child := range children {
_, ok := child.(antlr.TerminalNode)
if ok {
continue
}
for _, memberPath := range children {
var exp core.Expression
var err error
var parsed bool
prop, ok := child.(*fql.PropertyNameContext)
memberPath := memberPath.(*fql.MemberExpressionPathContext)
if ok {
exp, err = v.doVisitPropertyNameContext(prop, scope)
parsed = true
if prop := memberPath.PropertyName(); prop != nil {
exp, err = v.doVisitPropertyNameContext(prop.(*fql.PropertyNameContext), scope)
} else if prop := memberPath.ComputedPropertyName(); prop != nil {
exp, err = v.doVisitComputedPropertyNameContext(prop.(*fql.ComputedPropertyNameContext), scope)
} else {
computedProp, ok := child.(*fql.ComputedPropertyNameContext)
if ok {
exp, err = v.doVisitComputedPropertyNameContext(computedProp, scope)
parsed = true
}
return nil, v.unexpectedToken(memberPath)
}
if err != nil {
return nil, err
}
if !parsed {
// TODO: add more contextual information
return nil, ErrInvalidToken
}
path = append(path, exp)
}
exp, err := expressions.NewMemberExpression(
return expressions.NewMemberExpression(
v.getSourceMap(ctx),
member,
source,
path,
)
if err != nil {
return nil, err
}
return exp, nil
}
func (v *visitor) doVisitMember(ctx *fql.MemberContext, scope *scope) (core.Expression, error) {
identifier := ctx.Identifier()
if identifier != nil {
varName := ctx.Identifier().GetText()
func (v *visitor) doVisitMemberExpressionSource(ctx *fql.MemberExpressionSourceContext, scope *scope) (core.Expression, error) {
if variable := ctx.Variable(); variable != nil {
varName := variable.GetText()
if !scope.HasVariable(varName) {
return nil, core.Error(ErrVariableNotFound, varName)
}
exp, err := expressions.NewVariableExpression(v.getSourceMap(ctx), varName)
if err != nil {
return nil, err
}
return exp, nil
return expressions.NewVariableExpression(v.getSourceMap(ctx), varName)
}
fnCall := ctx.FunctionCallExpression()
if fnCall != nil {
exp, err := v.doVisitFunctionCallExpression(fnCall.(*fql.FunctionCallExpressionContext), scope)
if err != nil {
return nil, err
}
return exp, nil
if param := ctx.Param(); param != nil {
return v.doVisitParamContext(param.(*fql.ParamContext), scope)
}
param := ctx.Param()
if param != nil {
exp, err := v.doVisitParamContext(param.(*fql.ParamContext), scope)
if err != nil {
return nil, err
}
return exp, nil
if fnCall := ctx.FunctionCallExpression(); fnCall != nil {
return v.doVisitFunctionCallExpression(fnCall.(*fql.FunctionCallExpressionContext), scope)
}
objectLiteral := ctx.ObjectLiteral()
if objectLiteral != nil {
exp, err := v.doVisitObjectLiteral(objectLiteral.(*fql.ObjectLiteralContext), scope)
if err != nil {
return nil, err
}
return exp, nil
if objectLiteral := ctx.ObjectLiteral(); objectLiteral != nil {
return v.doVisitObjectLiteral(objectLiteral.(*fql.ObjectLiteralContext), scope)
}
arrayLiteral := ctx.ArrayLiteral()
if arrayLiteral != nil {
exp, err := v.doVisitArrayLiteral(arrayLiteral.(*fql.ArrayLiteralContext), scope)
if err != nil {
return nil, err
}
return exp, nil
if arrayLiteral := ctx.ArrayLiteral(); arrayLiteral != nil {
return v.doVisitArrayLiteral(arrayLiteral.(*fql.ArrayLiteralContext), scope)
}
return nil, core.ErrNotImplemented
return nil, v.unexpectedToken(ctx)
}
func (v *visitor) doVisitObjectLiteral(ctx *fql.ObjectLiteralContext, scope *scope) (core.Expression, error) {
@ -909,38 +943,37 @@ func (v *visitor) doVisitObjectLiteral(ctx *fql.ObjectLiteralContext, scope *sco
for _, assignment := range assignments {
var name core.Expression
var value core.Expression
var shortHand bool
var err error
assignment := assignment.(*fql.PropertyAssignmentContext)
pac := assignment.(*fql.PropertyAssignmentContext)
prop := assignment.PropertyName()
computedProp := assignment.ComputedPropertyName()
shortHand := assignment.ShorthandPropertyName()
switch {
case prop != nil:
if prop := pac.PropertyName(); prop != nil {
name, err = v.doVisitPropertyNameContext(prop.(*fql.PropertyNameContext), scope)
case computedProp != nil:
name, err = v.doVisitComputedPropertyNameContext(computedProp.(*fql.ComputedPropertyNameContext), scope)
default:
name, err = v.doVisitShorthandPropertyNameContext(shortHand.(*fql.ShorthandPropertyNameContext), scope)
}
if err != nil {
return nil, err
}
if shortHand == nil {
value, err = v.visit(assignment.Expression(), scope)
} else if comProp := pac.ComputedPropertyName(); comProp != nil {
name, err = v.doVisitComputedPropertyNameContext(comProp.(*fql.ComputedPropertyNameContext), scope)
} else if variable := pac.Variable(); variable != nil {
shortHand = true
name = literals.NewStringLiteral(variable.GetText())
value, err = v.doVisitVariable(variable.(*fql.VariableContext), scope)
} else {
value, err = v.doVisitVariable(shortHand.(*fql.ShorthandPropertyNameContext).Variable().(*fql.VariableContext), scope)
return nil, v.unexpectedToken(pac)
}
if err != nil {
return nil, err
}
if !shortHand {
value, err = v.visit(pac.Expression(), scope)
if err != nil {
return nil, err
}
}
pa, err := literals.NewObjectPropertyAssignment(name, value)
if err != nil {
return nil, err
}
@ -952,58 +985,34 @@ func (v *visitor) doVisitObjectLiteral(ctx *fql.ObjectLiteralContext, scope *sco
}
func (v *visitor) doVisitPropertyNameContext(ctx *fql.PropertyNameContext, scope *scope) (core.Expression, error) {
var name string
identifier := ctx.Identifier()
if identifier != nil {
name = identifier.GetText()
} else {
stringLiteral := ctx.StringLiteral()
if stringLiteral != nil {
runes := []rune(stringLiteral.GetText())
name = string(runes[1 : len(runes)-1])
} else {
param, err := v.doVisitParamContext(ctx.Param().(*fql.ParamContext), scope)
if err != nil {
return nil, err
}
return param, nil
}
if id := ctx.Identifier(); id != nil {
return literals.NewStringLiteral(id.GetText()), nil
}
if name == "" {
return nil, core.Error(core.ErrNotFound, "property name")
if stringLiteral := ctx.StringLiteral(); stringLiteral != nil {
runes := []rune(stringLiteral.GetText())
return literals.NewStringLiteral(string(runes[1 : len(runes)-1])), nil
}
return literals.NewStringLiteral(name), nil
if param := ctx.Param(); param != nil {
return v.doVisitParamContext(param.(*fql.ParamContext), scope)
}
return nil, v.unexpectedToken(ctx)
}
func (v *visitor) doVisitComputedPropertyNameContext(ctx *fql.ComputedPropertyNameContext, scope *scope) (core.Expression, error) {
return v.doVisitExpression(ctx.Expression().(*fql.ExpressionContext), scope)
}
func (v *visitor) doVisitShorthandPropertyNameContext(ctx *fql.ShorthandPropertyNameContext, scope *scope) (core.Expression, error) {
name := ctx.Variable().GetText()
if !scope.HasVariable(name) {
return nil, core.Error(ErrVariableNotFound, name)
}
return literals.NewStringLiteral(ctx.Variable().GetText()), nil
}
func (v *visitor) doVisitArrayLiteral(ctx *fql.ArrayLiteralContext, scope *scope) (core.Expression, error) {
listCtx := ctx.ArrayElementList()
exp := ctx.AllExpression()
if listCtx == nil {
if exp == nil {
return literals.NewArrayLiteral(0), nil
}
list := listCtx.(*fql.ArrayElementListContext)
exp := list.AllExpression()
elements := make([]core.Expression, 0, len(exp))
for _, e := range exp {
@ -1058,7 +1067,7 @@ func (v *visitor) doVisitNoneLiteral(_ *fql.NoneLiteralContext) (core.Expression
}
func (v *visitor) doVisitVariable(ctx *fql.VariableContext, scope *scope) (core.Expression, error) {
name := ctx.Identifier().GetText()
name := ctx.GetText()
// check whether the variable is defined
if !scope.HasVariable(name) {
@ -1079,26 +1088,12 @@ func (v *visitor) doVisitVariableDeclaration(ctx *fql.VariableDeclarationContext
return nil, err
}
exp := ctx.Expression()
if exp != nil {
if exp := ctx.Expression(); exp != nil {
init, err = v.doVisitExpression(ctx.Expression().(*fql.ExpressionContext), scope)
}
if init == nil && err == nil {
forIn := ctx.ForExpression()
if forIn != nil {
init, err = v.doVisitForExpression(forIn.(*fql.ForExpressionContext), scope)
}
}
if init == nil && err == nil {
forTer := ctx.ForTernaryExpression()
if forTer != nil {
init, err = v.doVisitForTernaryExpression(forTer.(*fql.ForTernaryExpressionContext), scope)
}
} else if exp := ctx.ForExpression(); exp != nil {
init, err = v.doVisitForExpression(exp.(*fql.ForExpressionContext), scope)
} else if exp := ctx.WaitForExpression(); exp != nil {
init, err = v.doVisitWaitForExpressionContext(exp.(*fql.WaitForExpressionContext), scope)
}
if err != nil {
@ -1452,6 +1447,10 @@ func (v *visitor) doVisitExpression(ctx *fql.ExpressionContext, scope *scope) (c
return v.doVisitRegexpOperator(ctx, exp.(*fql.RegexpOperatorContext), scope)
}
if exp := ctx.QuestionMark(); exp != nil {
return v.doVisitTernaryExpression(ctx, scope)
}
if exp := ctx.Variable(); exp != nil {
return v.doVisitVariable(exp.(*fql.VariableContext), scope)
}
@ -1548,6 +1547,8 @@ func (v *visitor) visit(node antlr.Tree, scope *scope) (core.Expression, error)
out, err = v.doVisitForExpression(ctx, scope)
case *fql.ReturnExpressionContext:
out, err = v.doVisitReturnExpression(ctx, scope)
case *fql.WaitForExpressionContext:
out, err = v.doVisitWaitForExpressionContext(ctx, scope)
case *fql.ArrayLiteralContext:
out, err = v.doVisitArrayLiteral(ctx, scope)
case *fql.ObjectLiteralContext:
@ -1577,8 +1578,9 @@ func (v *visitor) visit(node antlr.Tree, scope *scope) (core.Expression, error)
return out, err
}
func (v *visitor) doVisitForTernaryExpression(ctx *fql.ForTernaryExpressionContext, scope *scope) (*expressions.ConditionExpression, error) {
func (v *visitor) doVisitTernaryExpression(ctx *fql.ExpressionContext, scope *scope) (*expressions.ConditionExpression, error) {
exps, err := v.doVisitChildren(ctx, scope)
if err != nil {
return nil, err
}

View File

@ -165,6 +165,15 @@ func (doc *HTMLDocument) Copy() core.Value {
func (doc *HTMLDocument) Compare(other core.Value) int64 {
switch other.Type() {
case drivers.HTMLDocumentType:
cdpDoc, ok := other.(*HTMLDocument)
if ok {
thisID := values.NewString(string(doc.Frame().Frame.ID))
otherID := values.NewString(string(cdpDoc.Frame().Frame.ID))
return thisID.Compare(otherID)
}
other := other.(drivers.HTMLDocument)
return values.NewString(doc.frameTree.Frame.URL).Compare(other.GetURL())

View File

@ -20,21 +20,31 @@ import (
"github.com/MontFerret/ferret/pkg/drivers/cdp/templates"
"github.com/MontFerret/ferret/pkg/drivers/common"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/events"
"github.com/MontFerret/ferret/pkg/runtime/logging"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
type HTMLPage struct {
mu sync.Mutex
closed values.Boolean
logger *zerolog.Logger
conn *rpcc.Conn
client *cdp.Client
network *net.Manager
dom *dom.Manager
mouse *input.Mouse
keyboard *input.Keyboard
}
type (
HTMLPageEvent string
HTMLPage struct {
mu sync.Mutex
closed values.Boolean
logger *zerolog.Logger
conn *rpcc.Conn
client *cdp.Client
network *net.Manager
dom *dom.Manager
mouse *input.Mouse
keyboard *input.Keyboard
}
)
const (
HTMLPageEventNavigation HTMLPageEvent = "navigation"
)
func LoadHTMLPage(
ctx context.Context,
@ -591,6 +601,73 @@ func (p *HTMLPage) WaitForFrameNavigation(ctx context.Context, frame drivers.HTM
return p.reloadMainFrame(ctx)
}
func (p *HTMLPage) Subscribe(ctx context.Context, eventName string, options *values.Object) <-chan events.Event {
ch := make(chan events.Event)
go func() {
var err error
var data core.Value
if eventName == drivers.EventPageNavigation {
data, err = p.subscribeToNavigation(ctx, options)
} else {
err = core.Errorf(core.ErrInvalidOperation, "unknown event name: %s", eventName)
}
ch <- events.Event{
Data: data,
Err: err,
}
}()
return ch
}
func (p *HTMLPage) subscribeToNavigation(ctx context.Context, options *values.Object) (values.String, error) {
var frame drivers.HTMLDocument
var targetURL values.String
if options != nil {
if options.Has("frame") {
frameOpt, _ := options.Get("frame")
doc, ok := frameOpt.(drivers.HTMLDocument)
if ok {
frame = doc
} else {
return values.EmptyString, errors.Wrap(core.TypeError(frameOpt.Type(), drivers.HTMLDocumentType), "invalid frame")
}
}
if options.Has("target") {
targetURLOpt, _ := options.Get("target")
url, ok := targetURLOpt.(values.String)
if ok {
targetURL = url
} else {
return values.EmptyString, errors.Wrap(core.TypeError(targetURLOpt.Type(), types.String), "invalid target")
}
}
}
if frame == nil {
if err := p.WaitForNavigation(ctx, targetURL); err != nil {
return values.EmptyString, err
}
return p.GetURL(), nil
}
if err := p.WaitForFrameNavigation(ctx, frame, targetURL); err != nil {
return values.EmptyString, err
}
return frame.GetURL(), nil
}
func (p *HTMLPage) urlToRegexp(targetURL values.String) (*regexp.Regexp, error) {
if targetURL == "" {
return nil, nil

3
pkg/drivers/events.go Normal file
View File

@ -0,0 +1,3 @@
package drivers
const EventPageNavigation = "navigation"

View File

@ -50,6 +50,8 @@ RegexMatch: '=~';
// Common Keywords
For: 'FOR';
Return: 'RETURN';
Waitfor: 'WAITFOR';
Options: 'OPTIONS';
Distinct: 'DISTINCT';
Filter: 'FILTER';
Sort: 'SORT';
@ -71,6 +73,9 @@ All: 'ALL';
Any: 'ANY';
Aggregate: 'AGGREGATE';
// Wait operators
Event: 'EVENT';
// Unary operators
Like: 'LIKE';
Not: 'NOT' | '!';
@ -90,6 +95,8 @@ FloatLiteral
NamespaceSegment: Identifier NamespaceSeparator;
UnknownIdentifier: .;
// Fragments
fragment HexDigit
: [0-9a-fA-F]

View File

@ -34,35 +34,39 @@ RegexNotMatch=33
RegexMatch=34
For=35
Return=36
Distinct=37
Filter=38
Sort=39
Limit=40
Let=41
Collect=42
SortDirection=43
None=44
Null=45
BooleanLiteral=46
Use=47
Into=48
Keep=49
With=50
Count=51
All=52
Any=53
Aggregate=54
Like=55
Not=56
In=57
Do=58
While=59
Param=60
Identifier=61
StringLiteral=62
IntegerLiteral=63
FloatLiteral=64
NamespaceSegment=65
Waitfor=37
Options=38
Distinct=39
Filter=40
Sort=41
Limit=42
Let=43
Collect=44
SortDirection=45
None=46
Null=47
BooleanLiteral=48
Use=49
Into=50
Keep=51
With=52
Count=53
All=54
Any=55
Aggregate=56
Event=57
Like=58
Not=59
In=60
Do=61
While=62
Param=63
Identifier=64
StringLiteral=65
IntegerLiteral=66
FloatLiteral=67
NamespaceSegment=68
UnknownIdentifier=69
':'=5
';'=6
'.'=7
@ -92,24 +96,27 @@ NamespaceSegment=65
'=~'=34
'FOR'=35
'RETURN'=36
'DISTINCT'=37
'FILTER'=38
'SORT'=39
'LIMIT'=40
'LET'=41
'COLLECT'=42
'NONE'=44
'NULL'=45
'USE'=47
'INTO'=48
'KEEP'=49
'WITH'=50
'COUNT'=51
'ALL'=52
'ANY'=53
'AGGREGATE'=54
'LIKE'=55
'IN'=57
'DO'=58
'WHILE'=59
'@'=60
'WAITFOR'=37
'OPTIONS'=38
'DISTINCT'=39
'FILTER'=40
'SORT'=41
'LIMIT'=42
'LET'=43
'COLLECT'=44
'NONE'=46
'NULL'=47
'USE'=49
'INTO'=50
'KEEP'=51
'WITH'=52
'COUNT'=53
'ALL'=54
'ANY'=55
'AGGREGATE'=56
'EVENT'=57
'LIKE'=58
'IN'=60
'DO'=61
'WHILE'=62
'@'=63

View File

@ -5,7 +5,7 @@ parser grammar FqlParser;
options { tokenVocab=FqlLexer; }
program
: (head)* body
: head* body EOF
;
head
@ -20,13 +20,18 @@ use
: Use namespaceIdentifier
;
namespaceIdentifier
: namespace Identifier
;
body
: (bodyStatement)* bodyExpression
: bodyStatement* bodyExpression
;
bodyStatement
: functionCallExpression
| variableDeclaration
: variableDeclaration
| functionCallExpression
| waitForExpression
;
bodyExpression
@ -34,29 +39,25 @@ bodyExpression
| forExpression
;
variableDeclaration
: Let Identifier Assign OpenParen (forExpression | waitForExpression) CloseParen
| Let Identifier Assign expression
;
returnExpression
: Return (Distinct)? expression
| Return (Distinct)? OpenParen forExpression CloseParen
| Return forTernaryExpression
: Return Distinct? OpenParen (forExpression | waitForExpression) CloseParen
| Return Distinct? expression
;
forExpression
: For forExpressionValueVariable (Comma forExpressionKeyVariable)? In forExpressionSource
(forExpressionBody)*
: For Identifier (Comma Identifier)? In forExpressionSource
forExpressionBody*
forExpressionReturn
| For forExpressionValueVariable (Do)? While expression
(forExpressionBody)*
| For Identifier Do? While expression
forExpressionBody*
forExpressionReturn
;
forExpressionValueVariable
: Identifier
;
forExpressionKeyVariable
: Identifier
;
forExpressionSource
: functionCallExpression
| arrayLiteral
@ -144,18 +145,34 @@ collectCounter
: With Count Into Identifier
;
variableDeclaration
: Let Identifier Assign expression
| Let Identifier Assign OpenParen forExpression CloseParen
| Let Identifier Assign forTernaryExpression
optionsClause
: Options objectLiteral
| Options variable
;
param
: Param Identifier
waitForExpression
: Waitfor Event waitForEventName In waitForEventSource (optionsClause)? (waitForTimeout)?
;
variable
: Identifier
waitForTimeout
: integerLiteral
| variable
| functionCallExpression
| memberExpression
;
waitForEventName
: stringLiteral
| variable
| param
| functionCallExpression
| memberExpression
;
waitForEventSource
: functionCallExpression
| variable
| memberExpression
;
rangeOperator
@ -163,46 +180,17 @@ rangeOperator
;
arrayLiteral
: OpenBracket arrayElementList? CloseBracket
: OpenBracket (expression (Comma expression)* Comma?)? CloseBracket
;
objectLiteral
: OpenBrace (propertyAssignment (Comma propertyAssignment)*)? Comma? CloseBrace
;
booleanLiteral
: BooleanLiteral
;
stringLiteral
: StringLiteral
;
integerLiteral
: IntegerLiteral
;
floatLiteral
: FloatLiteral
;
noneLiteral
: Null
| None
;
arrayElementList
: expression (Comma + expression)*
: OpenBrace (propertyAssignment (Comma propertyAssignment)* Comma?)? CloseBrace
;
propertyAssignment
: propertyName Colon expression
| computedPropertyName Colon expression
| shorthandPropertyName
;
shorthandPropertyName
: variable
| variable
;
computedPropertyName
@ -215,16 +203,80 @@ propertyName
| param
;
booleanLiteral
: BooleanLiteral
;
stringLiteral
: StringLiteral
;
floatLiteral
: FloatLiteral
;
integerLiteral
: IntegerLiteral
;
noneLiteral
: Null
| None
;
expressionGroup
: OpenParen expression CloseParen
;
namespaceIdentifier
: namespace Identifier
expression
: unaryOperator expression
| expression multiplicativeOperator expression
| expression additiveOperator expression
| expression arrayOperator (inOperator | equalityOperator) expression
| expression inOperator expression
| expression likeOperator expression
| expression equalityOperator expression
| expression regexpOperator expression
| expression logicalAndOperator expression
| expression logicalOrOperator expression
| expression QuestionMark OpenParen (forExpression | waitForExpression) CloseParen Colon OpenParen (forExpression | waitForExpression) CloseParen
| expression QuestionMark expression Colon OpenParen (forExpression | waitForExpression) CloseParen
| expression QuestionMark OpenParen (forExpression | waitForExpression) CloseParen Colon expression
| expression QuestionMark expression? Colon expression
| rangeOperator
| stringLiteral
| floatLiteral
| integerLiteral
| booleanLiteral
| arrayLiteral
| objectLiteral
| memberExpression
| functionCallExpression
| param
| variable
| noneLiteral
| expressionGroup
;
namespace
: (NamespaceSegment)*
memberExpression
: memberExpressionSource memberExpressionPath+
;
memberExpressionSource
: variable
| param
| functionCallExpression
| arrayLiteral
| objectLiteral
;
memberExpressionPath
: Dot propertyName
| computedPropertyName
;
functionCallExpression
: namespace functionIdentifier arguments
;
functionIdentifier
@ -254,64 +306,16 @@ functionIdentifier
| Like
| Not
| In
| Waitfor
| Event
;
functionCallExpression
: namespace functionIdentifier arguments
;
member
: Identifier
| functionCallExpression
| param
| objectLiteral
| arrayLiteral
;
memberPath
: (Dot propertyName (computedPropertyName)*)+
| computedPropertyName (Dot propertyName (computedPropertyName)*)* (computedPropertyName (Dot propertyName)*)*
;
memberExpression
: member memberPath
namespace
: NamespaceSegment*
;
arguments
: OpenParen(expression (Comma expression)*)?CloseParen
;
expression
: unaryOperator expression
| expression multiplicativeOperator expression
| expression additiveOperator expression
| functionCallExpression
| expressionGroup
| expression arrayOperator (inOperator | equalityOperator) expression
| expression inOperator expression
| expression likeOperator expression
| expression equalityOperator expression
| expression regexpOperator expression
| expression logicalAndOperator expression
| expression logicalOrOperator expression
| expression QuestionMark expression? Colon expression
| rangeOperator
| stringLiteral
| integerLiteral
| floatLiteral
| booleanLiteral
| arrayLiteral
| objectLiteral
| variable
| memberExpression
| noneLiteral
| param
;
forTernaryExpression
: expression QuestionMark expression? Colon OpenParen forExpression CloseParen
| expression QuestionMark OpenParen forExpression CloseParen Colon expression
| expression QuestionMark OpenParen forExpression CloseParen Colon OpenParen forExpression CloseParen
: OpenParen (expression (Comma expression)*)? CloseParen
;
arrayOperator
@ -367,4 +371,12 @@ unaryOperator
: Not
| Plus
| Minus
;
param
: Param Identifier
;
variable
: Identifier
;

File diff suppressed because one or more lines are too long

View File

@ -34,35 +34,39 @@ RegexNotMatch=33
RegexMatch=34
For=35
Return=36
Distinct=37
Filter=38
Sort=39
Limit=40
Let=41
Collect=42
SortDirection=43
None=44
Null=45
BooleanLiteral=46
Use=47
Into=48
Keep=49
With=50
Count=51
All=52
Any=53
Aggregate=54
Like=55
Not=56
In=57
Do=58
While=59
Param=60
Identifier=61
StringLiteral=62
IntegerLiteral=63
FloatLiteral=64
NamespaceSegment=65
Waitfor=37
Options=38
Distinct=39
Filter=40
Sort=41
Limit=42
Let=43
Collect=44
SortDirection=45
None=46
Null=47
BooleanLiteral=48
Use=49
Into=50
Keep=51
With=52
Count=53
All=54
Any=55
Aggregate=56
Event=57
Like=58
Not=59
In=60
Do=61
While=62
Param=63
Identifier=64
StringLiteral=65
IntegerLiteral=66
FloatLiteral=67
NamespaceSegment=68
UnknownIdentifier=69
':'=5
';'=6
'.'=7
@ -92,24 +96,27 @@ NamespaceSegment=65
'=~'=34
'FOR'=35
'RETURN'=36
'DISTINCT'=37
'FILTER'=38
'SORT'=39
'LIMIT'=40
'LET'=41
'COLLECT'=42
'NONE'=44
'NULL'=45
'USE'=47
'INTO'=48
'KEEP'=49
'WITH'=50
'COUNT'=51
'ALL'=52
'ANY'=53
'AGGREGATE'=54
'LIKE'=55
'IN'=57
'DO'=58
'WHILE'=59
'@'=60
'WAITFOR'=37
'OPTIONS'=38
'DISTINCT'=39
'FILTER'=40
'SORT'=41
'LIMIT'=42
'LET'=43
'COLLECT'=44
'NONE'=46
'NULL'=47
'USE'=49
'INTO'=50
'KEEP'=51
'WITH'=52
'COUNT'=53
'ALL'=54
'ANY'=55
'AGGREGATE'=56
'EVENT'=57
'LIKE'=58
'IN'=60
'DO'=61
'WHILE'=62
'@'=63

File diff suppressed because one or more lines are too long

View File

@ -34,35 +34,39 @@ RegexNotMatch=33
RegexMatch=34
For=35
Return=36
Distinct=37
Filter=38
Sort=39
Limit=40
Let=41
Collect=42
SortDirection=43
None=44
Null=45
BooleanLiteral=46
Use=47
Into=48
Keep=49
With=50
Count=51
All=52
Any=53
Aggregate=54
Like=55
Not=56
In=57
Do=58
While=59
Param=60
Identifier=61
StringLiteral=62
IntegerLiteral=63
FloatLiteral=64
NamespaceSegment=65
Waitfor=37
Options=38
Distinct=39
Filter=40
Sort=41
Limit=42
Let=43
Collect=44
SortDirection=45
None=46
Null=47
BooleanLiteral=48
Use=49
Into=50
Keep=51
With=52
Count=53
All=54
Any=55
Aggregate=56
Event=57
Like=58
Not=59
In=60
Do=61
While=62
Param=63
Identifier=64
StringLiteral=65
IntegerLiteral=66
FloatLiteral=67
NamespaceSegment=68
UnknownIdentifier=69
':'=5
';'=6
'.'=7
@ -92,24 +96,27 @@ NamespaceSegment=65
'=~'=34
'FOR'=35
'RETURN'=36
'DISTINCT'=37
'FILTER'=38
'SORT'=39
'LIMIT'=40
'LET'=41
'COLLECT'=42
'NONE'=44
'NULL'=45
'USE'=47
'INTO'=48
'KEEP'=49
'WITH'=50
'COUNT'=51
'ALL'=52
'ANY'=53
'AGGREGATE'=54
'LIKE'=55
'IN'=57
'DO'=58
'WHILE'=59
'@'=60
'WAITFOR'=37
'OPTIONS'=38
'DISTINCT'=39
'FILTER'=40
'SORT'=41
'LIMIT'=42
'LET'=43
'COLLECT'=44
'NONE'=46
'NULL'=47
'USE'=49
'INTO'=50
'KEEP'=51
'WITH'=52
'COUNT'=53
'ALL'=54
'ANY'=55
'AGGREGATE'=56
'EVENT'=57
'LIKE'=58
'IN'=60
'DO'=61
'WHILE'=62
'@'=63

View File

@ -14,7 +14,7 @@ var _ = fmt.Printf
var _ = unicode.IsLetter
var serializedLexerAtn = []uint16{
3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 67, 563,
3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 71, 595,
8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7,
9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12,
4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4,
@ -29,243 +29,256 @@ var serializedLexerAtn = []uint16{
60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65,
9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9,
70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75,
4, 76, 9, 76, 4, 77, 9, 77, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 160, 10, 2, 12,
2, 14, 2, 163, 11, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3,
3, 7, 3, 174, 10, 3, 12, 3, 14, 3, 177, 11, 3, 3, 3, 3, 3, 3, 4, 6, 4,
182, 10, 4, 13, 4, 14, 4, 183, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6,
3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3,
12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17,
3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3,
21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25,
3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3,
29, 3, 29, 3, 29, 5, 29, 249, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 5, 30,
255, 10, 30, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3,
34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37,
3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3,
38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39,
3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3,
41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43,
3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 5, 44, 327,
10, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46,
3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3,
47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 5, 47, 357,
10, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49,
3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3,
52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54,
3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3,
55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57,
3, 57, 5, 57, 411, 10, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3,
60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 6, 62, 428,
10, 62, 13, 62, 14, 62, 429, 3, 62, 3, 62, 7, 62, 434, 10, 62, 12, 62,
14, 62, 437, 11, 62, 7, 62, 439, 10, 62, 12, 62, 14, 62, 442, 11, 62, 3,
62, 3, 62, 7, 62, 446, 10, 62, 12, 62, 14, 62, 449, 11, 62, 7, 62, 451,
10, 62, 12, 62, 14, 62, 454, 11, 62, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63,
460, 10, 63, 3, 64, 6, 64, 463, 10, 64, 13, 64, 14, 64, 464, 3, 65, 3,
65, 3, 65, 6, 65, 470, 10, 65, 13, 65, 14, 65, 471, 3, 65, 5, 65, 475,
10, 65, 3, 65, 3, 65, 5, 65, 479, 10, 65, 5, 65, 481, 10, 65, 3, 66, 3,
66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 7, 68, 491, 10, 68, 12, 68,
14, 68, 494, 11, 68, 5, 68, 496, 10, 68, 3, 69, 3, 69, 5, 69, 500, 10,
69, 3, 69, 6, 69, 503, 10, 69, 13, 69, 14, 69, 504, 3, 70, 3, 70, 3, 71,
3, 71, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 7, 73, 519,
10, 73, 12, 73, 14, 73, 522, 11, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74,
3, 74, 3, 74, 3, 74, 7, 74, 532, 10, 74, 12, 74, 14, 74, 535, 11, 74, 3,
74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 7, 75, 543, 10, 75, 12, 75, 14,
75, 546, 11, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 7, 76, 554,
10, 76, 12, 76, 14, 76, 557, 11, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77,
3, 161, 2, 78, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19,
4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4,
81, 9, 81, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 168, 10, 2, 12, 2, 14, 2, 171,
11, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 182,
10, 3, 12, 3, 14, 3, 185, 11, 3, 3, 3, 3, 3, 3, 4, 6, 4, 190, 10, 4, 13,
4, 14, 4, 191, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3,
7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3,
13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18,
3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3,
21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26,
3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3,
29, 5, 29, 257, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 5, 30, 263, 10, 30,
3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3,
35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37,
3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3,
38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40,
3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3,
41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43,
3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3,
45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46,
3, 46, 3, 46, 5, 46, 351, 10, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3,
48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49,
3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3,
49, 3, 49, 5, 49, 381, 10, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51,
3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3,
53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55,
3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3,
57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58,
3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 5,
60, 441, 10, 60, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63,
3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 6, 65, 458, 10, 65, 13,
65, 14, 65, 459, 3, 65, 3, 65, 7, 65, 464, 10, 65, 12, 65, 14, 65, 467,
11, 65, 7, 65, 469, 10, 65, 12, 65, 14, 65, 472, 11, 65, 3, 65, 3, 65,
7, 65, 476, 10, 65, 12, 65, 14, 65, 479, 11, 65, 7, 65, 481, 10, 65, 12,
65, 14, 65, 484, 11, 65, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 490, 10, 66,
3, 67, 6, 67, 493, 10, 67, 13, 67, 14, 67, 494, 3, 68, 3, 68, 3, 68, 6,
68, 500, 10, 68, 13, 68, 14, 68, 501, 3, 68, 5, 68, 505, 10, 68, 3, 68,
3, 68, 5, 68, 509, 10, 68, 5, 68, 511, 10, 68, 3, 69, 3, 69, 3, 69, 3,
70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 7, 72, 523, 10, 72, 12, 72,
14, 72, 526, 11, 72, 5, 72, 528, 10, 72, 3, 73, 3, 73, 5, 73, 532, 10,
73, 3, 73, 6, 73, 535, 10, 73, 13, 73, 14, 73, 536, 3, 74, 3, 74, 3, 75,
3, 75, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 77, 3, 77, 7, 77, 551,
10, 77, 12, 77, 14, 77, 554, 11, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78,
3, 78, 3, 78, 3, 78, 7, 78, 564, 10, 78, 12, 78, 14, 78, 567, 11, 78, 3,
78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 7, 79, 575, 10, 79, 12, 79, 14,
79, 578, 11, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 7, 80, 586,
10, 80, 12, 80, 14, 80, 589, 11, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81,
3, 169, 2, 82, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19,
11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37,
20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55,
29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73,
38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91,
47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55,
109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63,
125, 64, 127, 65, 129, 66, 131, 67, 133, 2, 135, 2, 137, 2, 139, 2, 141,
2, 143, 2, 145, 2, 147, 2, 149, 2, 151, 2, 153, 2, 3, 2, 14, 5, 2, 12,
12, 15, 15, 8234, 8235, 6, 2, 11, 11, 13, 14, 34, 34, 162, 162, 3, 2, 50,
59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 51, 59, 4, 2, 71, 71, 103, 103,
4, 2, 45, 45, 47, 47, 4, 2, 67, 92, 99, 124, 4, 2, 36, 36, 94, 94, 4, 2,
41, 41, 94, 94, 3, 2, 98, 98, 3, 2, 182, 182, 2, 588, 2, 3, 3, 2, 2, 2,
2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2,
2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2,
2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2,
2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3,
2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43,
3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2,
51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2,
2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2,
2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2,
2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3,
2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89,
3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2,
97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2,
2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111,
3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2,
2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3,
2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 3,
155, 3, 2, 2, 2, 5, 169, 3, 2, 2, 2, 7, 181, 3, 2, 2, 2, 9, 187, 3, 2,
2, 2, 11, 191, 3, 2, 2, 2, 13, 193, 3, 2, 2, 2, 15, 195, 3, 2, 2, 2, 17,
197, 3, 2, 2, 2, 19, 199, 3, 2, 2, 2, 21, 201, 3, 2, 2, 2, 23, 203, 3,
2, 2, 2, 25, 205, 3, 2, 2, 2, 27, 207, 3, 2, 2, 2, 29, 209, 3, 2, 2, 2,
31, 211, 3, 2, 2, 2, 33, 213, 3, 2, 2, 2, 35, 215, 3, 2, 2, 2, 37, 218,
3, 2, 2, 2, 39, 221, 3, 2, 2, 2, 41, 224, 3, 2, 2, 2, 43, 227, 3, 2, 2,
2, 45, 229, 3, 2, 2, 2, 47, 231, 3, 2, 2, 2, 49, 233, 3, 2, 2, 2, 51, 235,
3, 2, 2, 2, 53, 237, 3, 2, 2, 2, 55, 240, 3, 2, 2, 2, 57, 248, 3, 2, 2,
2, 59, 254, 3, 2, 2, 2, 61, 256, 3, 2, 2, 2, 63, 259, 3, 2, 2, 2, 65, 261,
3, 2, 2, 2, 67, 263, 3, 2, 2, 2, 69, 266, 3, 2, 2, 2, 71, 269, 3, 2, 2,
2, 73, 273, 3, 2, 2, 2, 75, 280, 3, 2, 2, 2, 77, 289, 3, 2, 2, 2, 79, 296,
3, 2, 2, 2, 81, 301, 3, 2, 2, 2, 83, 307, 3, 2, 2, 2, 85, 311, 3, 2, 2,
2, 87, 326, 3, 2, 2, 2, 89, 328, 3, 2, 2, 2, 91, 333, 3, 2, 2, 2, 93, 356,
3, 2, 2, 2, 95, 358, 3, 2, 2, 2, 97, 362, 3, 2, 2, 2, 99, 367, 3, 2, 2,
2, 101, 372, 3, 2, 2, 2, 103, 377, 3, 2, 2, 2, 105, 383, 3, 2, 2, 2, 107,
387, 3, 2, 2, 2, 109, 391, 3, 2, 2, 2, 111, 401, 3, 2, 2, 2, 113, 410,
3, 2, 2, 2, 115, 412, 3, 2, 2, 2, 117, 415, 3, 2, 2, 2, 119, 418, 3, 2,
2, 2, 121, 424, 3, 2, 2, 2, 123, 427, 3, 2, 2, 2, 125, 459, 3, 2, 2, 2,
127, 462, 3, 2, 2, 2, 129, 480, 3, 2, 2, 2, 131, 482, 3, 2, 2, 2, 133,
485, 3, 2, 2, 2, 135, 495, 3, 2, 2, 2, 137, 497, 3, 2, 2, 2, 139, 506,
3, 2, 2, 2, 141, 508, 3, 2, 2, 2, 143, 510, 3, 2, 2, 2, 145, 512, 3, 2,
2, 2, 147, 525, 3, 2, 2, 2, 149, 538, 3, 2, 2, 2, 151, 549, 3, 2, 2, 2,
153, 560, 3, 2, 2, 2, 155, 156, 7, 49, 2, 2, 156, 157, 7, 44, 2, 2, 157,
161, 3, 2, 2, 2, 158, 160, 11, 2, 2, 2, 159, 158, 3, 2, 2, 2, 160, 163,
3, 2, 2, 2, 161, 162, 3, 2, 2, 2, 161, 159, 3, 2, 2, 2, 162, 164, 3, 2,
2, 2, 163, 161, 3, 2, 2, 2, 164, 165, 7, 44, 2, 2, 165, 166, 7, 49, 2,
2, 166, 167, 3, 2, 2, 2, 167, 168, 8, 2, 2, 2, 168, 4, 3, 2, 2, 2, 169,
170, 7, 49, 2, 2, 170, 171, 7, 49, 2, 2, 171, 175, 3, 2, 2, 2, 172, 174,
10, 2, 2, 2, 173, 172, 3, 2, 2, 2, 174, 177, 3, 2, 2, 2, 175, 173, 3, 2,
2, 2, 175, 176, 3, 2, 2, 2, 176, 178, 3, 2, 2, 2, 177, 175, 3, 2, 2, 2,
178, 179, 8, 3, 2, 2, 179, 6, 3, 2, 2, 2, 180, 182, 9, 3, 2, 2, 181, 180,
3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 181, 3, 2, 2, 2, 183, 184, 3, 2,
2, 2, 184, 185, 3, 2, 2, 2, 185, 186, 8, 4, 2, 2, 186, 8, 3, 2, 2, 2, 187,
188, 9, 2, 2, 2, 188, 189, 3, 2, 2, 2, 189, 190, 8, 5, 2, 2, 190, 10, 3,
2, 2, 2, 191, 192, 7, 60, 2, 2, 192, 12, 3, 2, 2, 2, 193, 194, 7, 61, 2,
2, 194, 14, 3, 2, 2, 2, 195, 196, 7, 48, 2, 2, 196, 16, 3, 2, 2, 2, 197,
198, 7, 46, 2, 2, 198, 18, 3, 2, 2, 2, 199, 200, 7, 93, 2, 2, 200, 20,
3, 2, 2, 2, 201, 202, 7, 95, 2, 2, 202, 22, 3, 2, 2, 2, 203, 204, 7, 42,
2, 2, 204, 24, 3, 2, 2, 2, 205, 206, 7, 43, 2, 2, 206, 26, 3, 2, 2, 2,
207, 208, 7, 125, 2, 2, 208, 28, 3, 2, 2, 2, 209, 210, 7, 127, 2, 2, 210,
30, 3, 2, 2, 2, 211, 212, 7, 64, 2, 2, 212, 32, 3, 2, 2, 2, 213, 214, 7,
62, 2, 2, 214, 34, 3, 2, 2, 2, 215, 216, 7, 63, 2, 2, 216, 217, 7, 63,
2, 2, 217, 36, 3, 2, 2, 2, 218, 219, 7, 64, 2, 2, 219, 220, 7, 63, 2, 2,
220, 38, 3, 2, 2, 2, 221, 222, 7, 62, 2, 2, 222, 223, 7, 63, 2, 2, 223,
40, 3, 2, 2, 2, 224, 225, 7, 35, 2, 2, 225, 226, 7, 63, 2, 2, 226, 42,
3, 2, 2, 2, 227, 228, 7, 44, 2, 2, 228, 44, 3, 2, 2, 2, 229, 230, 7, 49,
2, 2, 230, 46, 3, 2, 2, 2, 231, 232, 7, 39, 2, 2, 232, 48, 3, 2, 2, 2,
233, 234, 7, 45, 2, 2, 234, 50, 3, 2, 2, 2, 235, 236, 7, 47, 2, 2, 236,
52, 3, 2, 2, 2, 237, 238, 7, 47, 2, 2, 238, 239, 7, 47, 2, 2, 239, 54,
3, 2, 2, 2, 240, 241, 7, 45, 2, 2, 241, 242, 7, 45, 2, 2, 242, 56, 3, 2,
2, 2, 243, 244, 7, 67, 2, 2, 244, 245, 7, 80, 2, 2, 245, 249, 7, 70, 2,
2, 246, 247, 7, 40, 2, 2, 247, 249, 7, 40, 2, 2, 248, 243, 3, 2, 2, 2,
248, 246, 3, 2, 2, 2, 249, 58, 3, 2, 2, 2, 250, 251, 7, 81, 2, 2, 251,
255, 7, 84, 2, 2, 252, 253, 7, 126, 2, 2, 253, 255, 7, 126, 2, 2, 254,
250, 3, 2, 2, 2, 254, 252, 3, 2, 2, 2, 255, 60, 3, 2, 2, 2, 256, 257, 5,
15, 8, 2, 257, 258, 5, 15, 8, 2, 258, 62, 3, 2, 2, 2, 259, 260, 7, 63,
2, 2, 260, 64, 3, 2, 2, 2, 261, 262, 7, 65, 2, 2, 262, 66, 3, 2, 2, 2,
263, 264, 7, 35, 2, 2, 264, 265, 7, 128, 2, 2, 265, 68, 3, 2, 2, 2, 266,
267, 7, 63, 2, 2, 267, 268, 7, 128, 2, 2, 268, 70, 3, 2, 2, 2, 269, 270,
7, 72, 2, 2, 270, 271, 7, 81, 2, 2, 271, 272, 7, 84, 2, 2, 272, 72, 3,
2, 2, 2, 273, 274, 7, 84, 2, 2, 274, 275, 7, 71, 2, 2, 275, 276, 7, 86,
2, 2, 276, 277, 7, 87, 2, 2, 277, 278, 7, 84, 2, 2, 278, 279, 7, 80, 2,
2, 279, 74, 3, 2, 2, 2, 280, 281, 7, 70, 2, 2, 281, 282, 7, 75, 2, 2, 282,
283, 7, 85, 2, 2, 283, 284, 7, 86, 2, 2, 284, 285, 7, 75, 2, 2, 285, 286,
7, 80, 2, 2, 286, 287, 7, 69, 2, 2, 287, 288, 7, 86, 2, 2, 288, 76, 3,
2, 2, 2, 289, 290, 7, 72, 2, 2, 290, 291, 7, 75, 2, 2, 291, 292, 7, 78,
2, 2, 292, 293, 7, 86, 2, 2, 293, 294, 7, 71, 2, 2, 294, 295, 7, 84, 2,
2, 295, 78, 3, 2, 2, 2, 296, 297, 7, 85, 2, 2, 297, 298, 7, 81, 2, 2, 298,
299, 7, 84, 2, 2, 299, 300, 7, 86, 2, 2, 300, 80, 3, 2, 2, 2, 301, 302,
7, 78, 2, 2, 302, 303, 7, 75, 2, 2, 303, 304, 7, 79, 2, 2, 304, 305, 7,
75, 2, 2, 305, 306, 7, 86, 2, 2, 306, 82, 3, 2, 2, 2, 307, 308, 7, 78,
2, 2, 308, 309, 7, 71, 2, 2, 309, 310, 7, 86, 2, 2, 310, 84, 3, 2, 2, 2,
311, 312, 7, 69, 2, 2, 312, 313, 7, 81, 2, 2, 313, 314, 7, 78, 2, 2, 314,
315, 7, 78, 2, 2, 315, 316, 7, 71, 2, 2, 316, 317, 7, 69, 2, 2, 317, 318,
7, 86, 2, 2, 318, 86, 3, 2, 2, 2, 319, 320, 7, 67, 2, 2, 320, 321, 7, 85,
2, 2, 321, 327, 7, 69, 2, 2, 322, 323, 7, 70, 2, 2, 323, 324, 7, 71, 2,
2, 324, 325, 7, 85, 2, 2, 325, 327, 7, 69, 2, 2, 326, 319, 3, 2, 2, 2,
326, 322, 3, 2, 2, 2, 327, 88, 3, 2, 2, 2, 328, 329, 7, 80, 2, 2, 329,
330, 7, 81, 2, 2, 330, 331, 7, 80, 2, 2, 331, 332, 7, 71, 2, 2, 332, 90,
3, 2, 2, 2, 333, 334, 7, 80, 2, 2, 334, 335, 7, 87, 2, 2, 335, 336, 7,
78, 2, 2, 336, 337, 7, 78, 2, 2, 337, 92, 3, 2, 2, 2, 338, 339, 7, 86,
2, 2, 339, 340, 7, 84, 2, 2, 340, 341, 7, 87, 2, 2, 341, 357, 7, 71, 2,
2, 342, 343, 7, 118, 2, 2, 343, 344, 7, 116, 2, 2, 344, 345, 7, 119, 2,
2, 345, 357, 7, 103, 2, 2, 346, 347, 7, 72, 2, 2, 347, 348, 7, 67, 2, 2,
348, 349, 7, 78, 2, 2, 349, 350, 7, 85, 2, 2, 350, 357, 7, 71, 2, 2, 351,
352, 7, 104, 2, 2, 352, 353, 7, 99, 2, 2, 353, 354, 7, 110, 2, 2, 354,
355, 7, 117, 2, 2, 355, 357, 7, 103, 2, 2, 356, 338, 3, 2, 2, 2, 356, 342,
3, 2, 2, 2, 356, 346, 3, 2, 2, 2, 356, 351, 3, 2, 2, 2, 357, 94, 3, 2,
2, 2, 358, 359, 7, 87, 2, 2, 359, 360, 7, 85, 2, 2, 360, 361, 7, 71, 2,
2, 361, 96, 3, 2, 2, 2, 362, 363, 7, 75, 2, 2, 363, 364, 7, 80, 2, 2, 364,
365, 7, 86, 2, 2, 365, 366, 7, 81, 2, 2, 366, 98, 3, 2, 2, 2, 367, 368,
7, 77, 2, 2, 368, 369, 7, 71, 2, 2, 369, 370, 7, 71, 2, 2, 370, 371, 7,
82, 2, 2, 371, 100, 3, 2, 2, 2, 372, 373, 7, 89, 2, 2, 373, 374, 7, 75,
2, 2, 374, 375, 7, 86, 2, 2, 375, 376, 7, 74, 2, 2, 376, 102, 3, 2, 2,
2, 377, 378, 7, 69, 2, 2, 378, 379, 7, 81, 2, 2, 379, 380, 7, 87, 2, 2,
380, 381, 7, 80, 2, 2, 381, 382, 7, 86, 2, 2, 382, 104, 3, 2, 2, 2, 383,
384, 7, 67, 2, 2, 384, 385, 7, 78, 2, 2, 385, 386, 7, 78, 2, 2, 386, 106,
3, 2, 2, 2, 387, 388, 7, 67, 2, 2, 388, 389, 7, 80, 2, 2, 389, 390, 7,
91, 2, 2, 390, 108, 3, 2, 2, 2, 391, 392, 7, 67, 2, 2, 392, 393, 7, 73,
2, 2, 393, 394, 7, 73, 2, 2, 394, 395, 7, 84, 2, 2, 395, 396, 7, 71, 2,
2, 396, 397, 7, 73, 2, 2, 397, 398, 7, 67, 2, 2, 398, 399, 7, 86, 2, 2,
399, 400, 7, 71, 2, 2, 400, 110, 3, 2, 2, 2, 401, 402, 7, 78, 2, 2, 402,
403, 7, 75, 2, 2, 403, 404, 7, 77, 2, 2, 404, 405, 7, 71, 2, 2, 405, 112,
3, 2, 2, 2, 406, 407, 7, 80, 2, 2, 407, 408, 7, 81, 2, 2, 408, 411, 7,
86, 2, 2, 409, 411, 7, 35, 2, 2, 410, 406, 3, 2, 2, 2, 410, 409, 3, 2,
2, 2, 411, 114, 3, 2, 2, 2, 412, 413, 7, 75, 2, 2, 413, 414, 7, 80, 2,
2, 414, 116, 3, 2, 2, 2, 415, 416, 7, 70, 2, 2, 416, 417, 7, 81, 2, 2,
417, 118, 3, 2, 2, 2, 418, 419, 7, 89, 2, 2, 419, 420, 7, 74, 2, 2, 420,
421, 7, 75, 2, 2, 421, 422, 7, 78, 2, 2, 422, 423, 7, 71, 2, 2, 423, 120,
3, 2, 2, 2, 424, 425, 7, 66, 2, 2, 425, 122, 3, 2, 2, 2, 426, 428, 5, 139,
70, 2, 427, 426, 3, 2, 2, 2, 428, 429, 3, 2, 2, 2, 429, 427, 3, 2, 2, 2,
429, 430, 3, 2, 2, 2, 430, 440, 3, 2, 2, 2, 431, 435, 5, 141, 71, 2, 432,
434, 5, 123, 62, 2, 433, 432, 3, 2, 2, 2, 434, 437, 3, 2, 2, 2, 435, 433,
3, 2, 2, 2, 435, 436, 3, 2, 2, 2, 436, 439, 3, 2, 2, 2, 437, 435, 3, 2,
2, 2, 438, 431, 3, 2, 2, 2, 439, 442, 3, 2, 2, 2, 440, 438, 3, 2, 2, 2,
440, 441, 3, 2, 2, 2, 441, 452, 3, 2, 2, 2, 442, 440, 3, 2, 2, 2, 443,
447, 5, 143, 72, 2, 444, 446, 5, 123, 62, 2, 445, 444, 3, 2, 2, 2, 446,
449, 3, 2, 2, 2, 447, 445, 3, 2, 2, 2, 447, 448, 3, 2, 2, 2, 448, 451,
3, 2, 2, 2, 449, 447, 3, 2, 2, 2, 450, 443, 3, 2, 2, 2, 451, 454, 3, 2,
2, 2, 452, 450, 3, 2, 2, 2, 452, 453, 3, 2, 2, 2, 453, 124, 3, 2, 2, 2,
454, 452, 3, 2, 2, 2, 455, 460, 5, 147, 74, 2, 456, 460, 5, 145, 73, 2,
457, 460, 5, 149, 75, 2, 458, 460, 5, 151, 76, 2, 459, 455, 3, 2, 2, 2,
459, 456, 3, 2, 2, 2, 459, 457, 3, 2, 2, 2, 459, 458, 3, 2, 2, 2, 460,
126, 3, 2, 2, 2, 461, 463, 9, 4, 2, 2, 462, 461, 3, 2, 2, 2, 463, 464,
3, 2, 2, 2, 464, 462, 3, 2, 2, 2, 464, 465, 3, 2, 2, 2, 465, 128, 3, 2,
2, 2, 466, 467, 5, 135, 68, 2, 467, 469, 5, 15, 8, 2, 468, 470, 9, 4, 2,
2, 469, 468, 3, 2, 2, 2, 470, 471, 3, 2, 2, 2, 471, 469, 3, 2, 2, 2, 471,
472, 3, 2, 2, 2, 472, 474, 3, 2, 2, 2, 473, 475, 5, 137, 69, 2, 474, 473,
3, 2, 2, 2, 474, 475, 3, 2, 2, 2, 475, 481, 3, 2, 2, 2, 476, 478, 5, 135,
68, 2, 477, 479, 5, 137, 69, 2, 478, 477, 3, 2, 2, 2, 478, 479, 3, 2, 2,
2, 479, 481, 3, 2, 2, 2, 480, 466, 3, 2, 2, 2, 480, 476, 3, 2, 2, 2, 481,
130, 3, 2, 2, 2, 482, 483, 5, 123, 62, 2, 483, 484, 5, 153, 77, 2, 484,
132, 3, 2, 2, 2, 485, 486, 9, 5, 2, 2, 486, 134, 3, 2, 2, 2, 487, 496,
7, 50, 2, 2, 488, 492, 9, 6, 2, 2, 489, 491, 9, 4, 2, 2, 490, 489, 3, 2,
2, 2, 491, 494, 3, 2, 2, 2, 492, 490, 3, 2, 2, 2, 492, 493, 3, 2, 2, 2,
493, 496, 3, 2, 2, 2, 494, 492, 3, 2, 2, 2, 495, 487, 3, 2, 2, 2, 495,
488, 3, 2, 2, 2, 496, 136, 3, 2, 2, 2, 497, 499, 9, 7, 2, 2, 498, 500,
9, 8, 2, 2, 499, 498, 3, 2, 2, 2, 499, 500, 3, 2, 2, 2, 500, 502, 3, 2,
2, 2, 501, 503, 9, 4, 2, 2, 502, 501, 3, 2, 2, 2, 503, 504, 3, 2, 2, 2,
504, 502, 3, 2, 2, 2, 504, 505, 3, 2, 2, 2, 505, 138, 3, 2, 2, 2, 506,
507, 9, 9, 2, 2, 507, 140, 3, 2, 2, 2, 508, 509, 7, 97, 2, 2, 509, 142,
3, 2, 2, 2, 510, 511, 4, 50, 59, 2, 511, 144, 3, 2, 2, 2, 512, 520, 7,
36, 2, 2, 513, 514, 7, 94, 2, 2, 514, 519, 11, 2, 2, 2, 515, 516, 7, 36,
2, 2, 516, 519, 7, 36, 2, 2, 517, 519, 10, 10, 2, 2, 518, 513, 3, 2, 2,
2, 518, 515, 3, 2, 2, 2, 518, 517, 3, 2, 2, 2, 519, 522, 3, 2, 2, 2, 520,
518, 3, 2, 2, 2, 520, 521, 3, 2, 2, 2, 521, 523, 3, 2, 2, 2, 522, 520,
3, 2, 2, 2, 523, 524, 7, 36, 2, 2, 524, 146, 3, 2, 2, 2, 525, 533, 7, 41,
2, 2, 526, 527, 7, 94, 2, 2, 527, 532, 11, 2, 2, 2, 528, 529, 7, 41, 2,
2, 529, 532, 7, 41, 2, 2, 530, 532, 10, 11, 2, 2, 531, 526, 3, 2, 2, 2,
531, 528, 3, 2, 2, 2, 531, 530, 3, 2, 2, 2, 532, 535, 3, 2, 2, 2, 533,
531, 3, 2, 2, 2, 533, 534, 3, 2, 2, 2, 534, 536, 3, 2, 2, 2, 535, 533,
3, 2, 2, 2, 536, 537, 7, 41, 2, 2, 537, 148, 3, 2, 2, 2, 538, 544, 7, 98,
2, 2, 539, 540, 7, 94, 2, 2, 540, 543, 7, 98, 2, 2, 541, 543, 10, 12, 2,
2, 542, 539, 3, 2, 2, 2, 542, 541, 3, 2, 2, 2, 543, 546, 3, 2, 2, 2, 544,
542, 3, 2, 2, 2, 544, 545, 3, 2, 2, 2, 545, 547, 3, 2, 2, 2, 546, 544,
3, 2, 2, 2, 547, 548, 7, 98, 2, 2, 548, 150, 3, 2, 2, 2, 549, 555, 7, 182,
2, 2, 550, 551, 7, 94, 2, 2, 551, 554, 7, 182, 2, 2, 552, 554, 10, 13,
2, 2, 553, 550, 3, 2, 2, 2, 553, 552, 3, 2, 2, 2, 554, 557, 3, 2, 2, 2,
555, 553, 3, 2, 2, 2, 555, 556, 3, 2, 2, 2, 556, 558, 3, 2, 2, 2, 557,
555, 3, 2, 2, 2, 558, 559, 7, 182, 2, 2, 559, 152, 3, 2, 2, 2, 560, 561,
7, 60, 2, 2, 561, 562, 7, 60, 2, 2, 562, 154, 3, 2, 2, 2, 34, 2, 161, 175,
183, 248, 254, 326, 356, 410, 429, 435, 440, 447, 452, 459, 464, 471, 474,
478, 480, 492, 495, 499, 504, 518, 520, 531, 533, 542, 544, 553, 555, 3,
2, 3, 2,
125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71,
141, 2, 143, 2, 145, 2, 147, 2, 149, 2, 151, 2, 153, 2, 155, 2, 157, 2,
159, 2, 161, 2, 3, 2, 14, 5, 2, 12, 12, 15, 15, 8234, 8235, 6, 2, 11, 11,
13, 14, 34, 34, 162, 162, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104,
3, 2, 51, 59, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 4, 2, 67, 92,
99, 124, 4, 2, 36, 36, 94, 94, 4, 2, 41, 41, 94, 94, 3, 2, 98, 98, 3, 2,
182, 182, 2, 620, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2,
2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2,
2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2,
2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3,
2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39,
3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2,
47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2,
2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2,
2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2,
2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3,
2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85,
3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2,
93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2,
2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3,
2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2,
115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2,
2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129,
3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2,
2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 3, 163, 3, 2, 2, 2, 5, 177, 3,
2, 2, 2, 7, 189, 3, 2, 2, 2, 9, 195, 3, 2, 2, 2, 11, 199, 3, 2, 2, 2, 13,
201, 3, 2, 2, 2, 15, 203, 3, 2, 2, 2, 17, 205, 3, 2, 2, 2, 19, 207, 3,
2, 2, 2, 21, 209, 3, 2, 2, 2, 23, 211, 3, 2, 2, 2, 25, 213, 3, 2, 2, 2,
27, 215, 3, 2, 2, 2, 29, 217, 3, 2, 2, 2, 31, 219, 3, 2, 2, 2, 33, 221,
3, 2, 2, 2, 35, 223, 3, 2, 2, 2, 37, 226, 3, 2, 2, 2, 39, 229, 3, 2, 2,
2, 41, 232, 3, 2, 2, 2, 43, 235, 3, 2, 2, 2, 45, 237, 3, 2, 2, 2, 47, 239,
3, 2, 2, 2, 49, 241, 3, 2, 2, 2, 51, 243, 3, 2, 2, 2, 53, 245, 3, 2, 2,
2, 55, 248, 3, 2, 2, 2, 57, 256, 3, 2, 2, 2, 59, 262, 3, 2, 2, 2, 61, 264,
3, 2, 2, 2, 63, 267, 3, 2, 2, 2, 65, 269, 3, 2, 2, 2, 67, 271, 3, 2, 2,
2, 69, 274, 3, 2, 2, 2, 71, 277, 3, 2, 2, 2, 73, 281, 3, 2, 2, 2, 75, 288,
3, 2, 2, 2, 77, 296, 3, 2, 2, 2, 79, 304, 3, 2, 2, 2, 81, 313, 3, 2, 2,
2, 83, 320, 3, 2, 2, 2, 85, 325, 3, 2, 2, 2, 87, 331, 3, 2, 2, 2, 89, 335,
3, 2, 2, 2, 91, 350, 3, 2, 2, 2, 93, 352, 3, 2, 2, 2, 95, 357, 3, 2, 2,
2, 97, 380, 3, 2, 2, 2, 99, 382, 3, 2, 2, 2, 101, 386, 3, 2, 2, 2, 103,
391, 3, 2, 2, 2, 105, 396, 3, 2, 2, 2, 107, 401, 3, 2, 2, 2, 109, 407,
3, 2, 2, 2, 111, 411, 3, 2, 2, 2, 113, 415, 3, 2, 2, 2, 115, 425, 3, 2,
2, 2, 117, 431, 3, 2, 2, 2, 119, 440, 3, 2, 2, 2, 121, 442, 3, 2, 2, 2,
123, 445, 3, 2, 2, 2, 125, 448, 3, 2, 2, 2, 127, 454, 3, 2, 2, 2, 129,
457, 3, 2, 2, 2, 131, 489, 3, 2, 2, 2, 133, 492, 3, 2, 2, 2, 135, 510,
3, 2, 2, 2, 137, 512, 3, 2, 2, 2, 139, 515, 3, 2, 2, 2, 141, 517, 3, 2,
2, 2, 143, 527, 3, 2, 2, 2, 145, 529, 3, 2, 2, 2, 147, 538, 3, 2, 2, 2,
149, 540, 3, 2, 2, 2, 151, 542, 3, 2, 2, 2, 153, 544, 3, 2, 2, 2, 155,
557, 3, 2, 2, 2, 157, 570, 3, 2, 2, 2, 159, 581, 3, 2, 2, 2, 161, 592,
3, 2, 2, 2, 163, 164, 7, 49, 2, 2, 164, 165, 7, 44, 2, 2, 165, 169, 3,
2, 2, 2, 166, 168, 11, 2, 2, 2, 167, 166, 3, 2, 2, 2, 168, 171, 3, 2, 2,
2, 169, 170, 3, 2, 2, 2, 169, 167, 3, 2, 2, 2, 170, 172, 3, 2, 2, 2, 171,
169, 3, 2, 2, 2, 172, 173, 7, 44, 2, 2, 173, 174, 7, 49, 2, 2, 174, 175,
3, 2, 2, 2, 175, 176, 8, 2, 2, 2, 176, 4, 3, 2, 2, 2, 177, 178, 7, 49,
2, 2, 178, 179, 7, 49, 2, 2, 179, 183, 3, 2, 2, 2, 180, 182, 10, 2, 2,
2, 181, 180, 3, 2, 2, 2, 182, 185, 3, 2, 2, 2, 183, 181, 3, 2, 2, 2, 183,
184, 3, 2, 2, 2, 184, 186, 3, 2, 2, 2, 185, 183, 3, 2, 2, 2, 186, 187,
8, 3, 2, 2, 187, 6, 3, 2, 2, 2, 188, 190, 9, 3, 2, 2, 189, 188, 3, 2, 2,
2, 190, 191, 3, 2, 2, 2, 191, 189, 3, 2, 2, 2, 191, 192, 3, 2, 2, 2, 192,
193, 3, 2, 2, 2, 193, 194, 8, 4, 2, 2, 194, 8, 3, 2, 2, 2, 195, 196, 9,
2, 2, 2, 196, 197, 3, 2, 2, 2, 197, 198, 8, 5, 2, 2, 198, 10, 3, 2, 2,
2, 199, 200, 7, 60, 2, 2, 200, 12, 3, 2, 2, 2, 201, 202, 7, 61, 2, 2, 202,
14, 3, 2, 2, 2, 203, 204, 7, 48, 2, 2, 204, 16, 3, 2, 2, 2, 205, 206, 7,
46, 2, 2, 206, 18, 3, 2, 2, 2, 207, 208, 7, 93, 2, 2, 208, 20, 3, 2, 2,
2, 209, 210, 7, 95, 2, 2, 210, 22, 3, 2, 2, 2, 211, 212, 7, 42, 2, 2, 212,
24, 3, 2, 2, 2, 213, 214, 7, 43, 2, 2, 214, 26, 3, 2, 2, 2, 215, 216, 7,
125, 2, 2, 216, 28, 3, 2, 2, 2, 217, 218, 7, 127, 2, 2, 218, 30, 3, 2,
2, 2, 219, 220, 7, 64, 2, 2, 220, 32, 3, 2, 2, 2, 221, 222, 7, 62, 2, 2,
222, 34, 3, 2, 2, 2, 223, 224, 7, 63, 2, 2, 224, 225, 7, 63, 2, 2, 225,
36, 3, 2, 2, 2, 226, 227, 7, 64, 2, 2, 227, 228, 7, 63, 2, 2, 228, 38,
3, 2, 2, 2, 229, 230, 7, 62, 2, 2, 230, 231, 7, 63, 2, 2, 231, 40, 3, 2,
2, 2, 232, 233, 7, 35, 2, 2, 233, 234, 7, 63, 2, 2, 234, 42, 3, 2, 2, 2,
235, 236, 7, 44, 2, 2, 236, 44, 3, 2, 2, 2, 237, 238, 7, 49, 2, 2, 238,
46, 3, 2, 2, 2, 239, 240, 7, 39, 2, 2, 240, 48, 3, 2, 2, 2, 241, 242, 7,
45, 2, 2, 242, 50, 3, 2, 2, 2, 243, 244, 7, 47, 2, 2, 244, 52, 3, 2, 2,
2, 245, 246, 7, 47, 2, 2, 246, 247, 7, 47, 2, 2, 247, 54, 3, 2, 2, 2, 248,
249, 7, 45, 2, 2, 249, 250, 7, 45, 2, 2, 250, 56, 3, 2, 2, 2, 251, 252,
7, 67, 2, 2, 252, 253, 7, 80, 2, 2, 253, 257, 7, 70, 2, 2, 254, 255, 7,
40, 2, 2, 255, 257, 7, 40, 2, 2, 256, 251, 3, 2, 2, 2, 256, 254, 3, 2,
2, 2, 257, 58, 3, 2, 2, 2, 258, 259, 7, 81, 2, 2, 259, 263, 7, 84, 2, 2,
260, 261, 7, 126, 2, 2, 261, 263, 7, 126, 2, 2, 262, 258, 3, 2, 2, 2, 262,
260, 3, 2, 2, 2, 263, 60, 3, 2, 2, 2, 264, 265, 5, 15, 8, 2, 265, 266,
5, 15, 8, 2, 266, 62, 3, 2, 2, 2, 267, 268, 7, 63, 2, 2, 268, 64, 3, 2,
2, 2, 269, 270, 7, 65, 2, 2, 270, 66, 3, 2, 2, 2, 271, 272, 7, 35, 2, 2,
272, 273, 7, 128, 2, 2, 273, 68, 3, 2, 2, 2, 274, 275, 7, 63, 2, 2, 275,
276, 7, 128, 2, 2, 276, 70, 3, 2, 2, 2, 277, 278, 7, 72, 2, 2, 278, 279,
7, 81, 2, 2, 279, 280, 7, 84, 2, 2, 280, 72, 3, 2, 2, 2, 281, 282, 7, 84,
2, 2, 282, 283, 7, 71, 2, 2, 283, 284, 7, 86, 2, 2, 284, 285, 7, 87, 2,
2, 285, 286, 7, 84, 2, 2, 286, 287, 7, 80, 2, 2, 287, 74, 3, 2, 2, 2, 288,
289, 7, 89, 2, 2, 289, 290, 7, 67, 2, 2, 290, 291, 7, 75, 2, 2, 291, 292,
7, 86, 2, 2, 292, 293, 7, 72, 2, 2, 293, 294, 7, 81, 2, 2, 294, 295, 7,
84, 2, 2, 295, 76, 3, 2, 2, 2, 296, 297, 7, 81, 2, 2, 297, 298, 7, 82,
2, 2, 298, 299, 7, 86, 2, 2, 299, 300, 7, 75, 2, 2, 300, 301, 7, 81, 2,
2, 301, 302, 7, 80, 2, 2, 302, 303, 7, 85, 2, 2, 303, 78, 3, 2, 2, 2, 304,
305, 7, 70, 2, 2, 305, 306, 7, 75, 2, 2, 306, 307, 7, 85, 2, 2, 307, 308,
7, 86, 2, 2, 308, 309, 7, 75, 2, 2, 309, 310, 7, 80, 2, 2, 310, 311, 7,
69, 2, 2, 311, 312, 7, 86, 2, 2, 312, 80, 3, 2, 2, 2, 313, 314, 7, 72,
2, 2, 314, 315, 7, 75, 2, 2, 315, 316, 7, 78, 2, 2, 316, 317, 7, 86, 2,
2, 317, 318, 7, 71, 2, 2, 318, 319, 7, 84, 2, 2, 319, 82, 3, 2, 2, 2, 320,
321, 7, 85, 2, 2, 321, 322, 7, 81, 2, 2, 322, 323, 7, 84, 2, 2, 323, 324,
7, 86, 2, 2, 324, 84, 3, 2, 2, 2, 325, 326, 7, 78, 2, 2, 326, 327, 7, 75,
2, 2, 327, 328, 7, 79, 2, 2, 328, 329, 7, 75, 2, 2, 329, 330, 7, 86, 2,
2, 330, 86, 3, 2, 2, 2, 331, 332, 7, 78, 2, 2, 332, 333, 7, 71, 2, 2, 333,
334, 7, 86, 2, 2, 334, 88, 3, 2, 2, 2, 335, 336, 7, 69, 2, 2, 336, 337,
7, 81, 2, 2, 337, 338, 7, 78, 2, 2, 338, 339, 7, 78, 2, 2, 339, 340, 7,
71, 2, 2, 340, 341, 7, 69, 2, 2, 341, 342, 7, 86, 2, 2, 342, 90, 3, 2,
2, 2, 343, 344, 7, 67, 2, 2, 344, 345, 7, 85, 2, 2, 345, 351, 7, 69, 2,
2, 346, 347, 7, 70, 2, 2, 347, 348, 7, 71, 2, 2, 348, 349, 7, 85, 2, 2,
349, 351, 7, 69, 2, 2, 350, 343, 3, 2, 2, 2, 350, 346, 3, 2, 2, 2, 351,
92, 3, 2, 2, 2, 352, 353, 7, 80, 2, 2, 353, 354, 7, 81, 2, 2, 354, 355,
7, 80, 2, 2, 355, 356, 7, 71, 2, 2, 356, 94, 3, 2, 2, 2, 357, 358, 7, 80,
2, 2, 358, 359, 7, 87, 2, 2, 359, 360, 7, 78, 2, 2, 360, 361, 7, 78, 2,
2, 361, 96, 3, 2, 2, 2, 362, 363, 7, 86, 2, 2, 363, 364, 7, 84, 2, 2, 364,
365, 7, 87, 2, 2, 365, 381, 7, 71, 2, 2, 366, 367, 7, 118, 2, 2, 367, 368,
7, 116, 2, 2, 368, 369, 7, 119, 2, 2, 369, 381, 7, 103, 2, 2, 370, 371,
7, 72, 2, 2, 371, 372, 7, 67, 2, 2, 372, 373, 7, 78, 2, 2, 373, 374, 7,
85, 2, 2, 374, 381, 7, 71, 2, 2, 375, 376, 7, 104, 2, 2, 376, 377, 7, 99,
2, 2, 377, 378, 7, 110, 2, 2, 378, 379, 7, 117, 2, 2, 379, 381, 7, 103,
2, 2, 380, 362, 3, 2, 2, 2, 380, 366, 3, 2, 2, 2, 380, 370, 3, 2, 2, 2,
380, 375, 3, 2, 2, 2, 381, 98, 3, 2, 2, 2, 382, 383, 7, 87, 2, 2, 383,
384, 7, 85, 2, 2, 384, 385, 7, 71, 2, 2, 385, 100, 3, 2, 2, 2, 386, 387,
7, 75, 2, 2, 387, 388, 7, 80, 2, 2, 388, 389, 7, 86, 2, 2, 389, 390, 7,
81, 2, 2, 390, 102, 3, 2, 2, 2, 391, 392, 7, 77, 2, 2, 392, 393, 7, 71,
2, 2, 393, 394, 7, 71, 2, 2, 394, 395, 7, 82, 2, 2, 395, 104, 3, 2, 2,
2, 396, 397, 7, 89, 2, 2, 397, 398, 7, 75, 2, 2, 398, 399, 7, 86, 2, 2,
399, 400, 7, 74, 2, 2, 400, 106, 3, 2, 2, 2, 401, 402, 7, 69, 2, 2, 402,
403, 7, 81, 2, 2, 403, 404, 7, 87, 2, 2, 404, 405, 7, 80, 2, 2, 405, 406,
7, 86, 2, 2, 406, 108, 3, 2, 2, 2, 407, 408, 7, 67, 2, 2, 408, 409, 7,
78, 2, 2, 409, 410, 7, 78, 2, 2, 410, 110, 3, 2, 2, 2, 411, 412, 7, 67,
2, 2, 412, 413, 7, 80, 2, 2, 413, 414, 7, 91, 2, 2, 414, 112, 3, 2, 2,
2, 415, 416, 7, 67, 2, 2, 416, 417, 7, 73, 2, 2, 417, 418, 7, 73, 2, 2,
418, 419, 7, 84, 2, 2, 419, 420, 7, 71, 2, 2, 420, 421, 7, 73, 2, 2, 421,
422, 7, 67, 2, 2, 422, 423, 7, 86, 2, 2, 423, 424, 7, 71, 2, 2, 424, 114,
3, 2, 2, 2, 425, 426, 7, 71, 2, 2, 426, 427, 7, 88, 2, 2, 427, 428, 7,
71, 2, 2, 428, 429, 7, 80, 2, 2, 429, 430, 7, 86, 2, 2, 430, 116, 3, 2,
2, 2, 431, 432, 7, 78, 2, 2, 432, 433, 7, 75, 2, 2, 433, 434, 7, 77, 2,
2, 434, 435, 7, 71, 2, 2, 435, 118, 3, 2, 2, 2, 436, 437, 7, 80, 2, 2,
437, 438, 7, 81, 2, 2, 438, 441, 7, 86, 2, 2, 439, 441, 7, 35, 2, 2, 440,
436, 3, 2, 2, 2, 440, 439, 3, 2, 2, 2, 441, 120, 3, 2, 2, 2, 442, 443,
7, 75, 2, 2, 443, 444, 7, 80, 2, 2, 444, 122, 3, 2, 2, 2, 445, 446, 7,
70, 2, 2, 446, 447, 7, 81, 2, 2, 447, 124, 3, 2, 2, 2, 448, 449, 7, 89,
2, 2, 449, 450, 7, 74, 2, 2, 450, 451, 7, 75, 2, 2, 451, 452, 7, 78, 2,
2, 452, 453, 7, 71, 2, 2, 453, 126, 3, 2, 2, 2, 454, 455, 7, 66, 2, 2,
455, 128, 3, 2, 2, 2, 456, 458, 5, 147, 74, 2, 457, 456, 3, 2, 2, 2, 458,
459, 3, 2, 2, 2, 459, 457, 3, 2, 2, 2, 459, 460, 3, 2, 2, 2, 460, 470,
3, 2, 2, 2, 461, 465, 5, 149, 75, 2, 462, 464, 5, 129, 65, 2, 463, 462,
3, 2, 2, 2, 464, 467, 3, 2, 2, 2, 465, 463, 3, 2, 2, 2, 465, 466, 3, 2,
2, 2, 466, 469, 3, 2, 2, 2, 467, 465, 3, 2, 2, 2, 468, 461, 3, 2, 2, 2,
469, 472, 3, 2, 2, 2, 470, 468, 3, 2, 2, 2, 470, 471, 3, 2, 2, 2, 471,
482, 3, 2, 2, 2, 472, 470, 3, 2, 2, 2, 473, 477, 5, 151, 76, 2, 474, 476,
5, 129, 65, 2, 475, 474, 3, 2, 2, 2, 476, 479, 3, 2, 2, 2, 477, 475, 3,
2, 2, 2, 477, 478, 3, 2, 2, 2, 478, 481, 3, 2, 2, 2, 479, 477, 3, 2, 2,
2, 480, 473, 3, 2, 2, 2, 481, 484, 3, 2, 2, 2, 482, 480, 3, 2, 2, 2, 482,
483, 3, 2, 2, 2, 483, 130, 3, 2, 2, 2, 484, 482, 3, 2, 2, 2, 485, 490,
5, 155, 78, 2, 486, 490, 5, 153, 77, 2, 487, 490, 5, 157, 79, 2, 488, 490,
5, 159, 80, 2, 489, 485, 3, 2, 2, 2, 489, 486, 3, 2, 2, 2, 489, 487, 3,
2, 2, 2, 489, 488, 3, 2, 2, 2, 490, 132, 3, 2, 2, 2, 491, 493, 9, 4, 2,
2, 492, 491, 3, 2, 2, 2, 493, 494, 3, 2, 2, 2, 494, 492, 3, 2, 2, 2, 494,
495, 3, 2, 2, 2, 495, 134, 3, 2, 2, 2, 496, 497, 5, 143, 72, 2, 497, 499,
5, 15, 8, 2, 498, 500, 9, 4, 2, 2, 499, 498, 3, 2, 2, 2, 500, 501, 3, 2,
2, 2, 501, 499, 3, 2, 2, 2, 501, 502, 3, 2, 2, 2, 502, 504, 3, 2, 2, 2,
503, 505, 5, 145, 73, 2, 504, 503, 3, 2, 2, 2, 504, 505, 3, 2, 2, 2, 505,
511, 3, 2, 2, 2, 506, 508, 5, 143, 72, 2, 507, 509, 5, 145, 73, 2, 508,
507, 3, 2, 2, 2, 508, 509, 3, 2, 2, 2, 509, 511, 3, 2, 2, 2, 510, 496,
3, 2, 2, 2, 510, 506, 3, 2, 2, 2, 511, 136, 3, 2, 2, 2, 512, 513, 5, 129,
65, 2, 513, 514, 5, 161, 81, 2, 514, 138, 3, 2, 2, 2, 515, 516, 11, 2,
2, 2, 516, 140, 3, 2, 2, 2, 517, 518, 9, 5, 2, 2, 518, 142, 3, 2, 2, 2,
519, 528, 7, 50, 2, 2, 520, 524, 9, 6, 2, 2, 521, 523, 9, 4, 2, 2, 522,
521, 3, 2, 2, 2, 523, 526, 3, 2, 2, 2, 524, 522, 3, 2, 2, 2, 524, 525,
3, 2, 2, 2, 525, 528, 3, 2, 2, 2, 526, 524, 3, 2, 2, 2, 527, 519, 3, 2,
2, 2, 527, 520, 3, 2, 2, 2, 528, 144, 3, 2, 2, 2, 529, 531, 9, 7, 2, 2,
530, 532, 9, 8, 2, 2, 531, 530, 3, 2, 2, 2, 531, 532, 3, 2, 2, 2, 532,
534, 3, 2, 2, 2, 533, 535, 9, 4, 2, 2, 534, 533, 3, 2, 2, 2, 535, 536,
3, 2, 2, 2, 536, 534, 3, 2, 2, 2, 536, 537, 3, 2, 2, 2, 537, 146, 3, 2,
2, 2, 538, 539, 9, 9, 2, 2, 539, 148, 3, 2, 2, 2, 540, 541, 7, 97, 2, 2,
541, 150, 3, 2, 2, 2, 542, 543, 4, 50, 59, 2, 543, 152, 3, 2, 2, 2, 544,
552, 7, 36, 2, 2, 545, 546, 7, 94, 2, 2, 546, 551, 11, 2, 2, 2, 547, 548,
7, 36, 2, 2, 548, 551, 7, 36, 2, 2, 549, 551, 10, 10, 2, 2, 550, 545, 3,
2, 2, 2, 550, 547, 3, 2, 2, 2, 550, 549, 3, 2, 2, 2, 551, 554, 3, 2, 2,
2, 552, 550, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 555, 3, 2, 2, 2, 554,
552, 3, 2, 2, 2, 555, 556, 7, 36, 2, 2, 556, 154, 3, 2, 2, 2, 557, 565,
7, 41, 2, 2, 558, 559, 7, 94, 2, 2, 559, 564, 11, 2, 2, 2, 560, 561, 7,
41, 2, 2, 561, 564, 7, 41, 2, 2, 562, 564, 10, 11, 2, 2, 563, 558, 3, 2,
2, 2, 563, 560, 3, 2, 2, 2, 563, 562, 3, 2, 2, 2, 564, 567, 3, 2, 2, 2,
565, 563, 3, 2, 2, 2, 565, 566, 3, 2, 2, 2, 566, 568, 3, 2, 2, 2, 567,
565, 3, 2, 2, 2, 568, 569, 7, 41, 2, 2, 569, 156, 3, 2, 2, 2, 570, 576,
7, 98, 2, 2, 571, 572, 7, 94, 2, 2, 572, 575, 7, 98, 2, 2, 573, 575, 10,
12, 2, 2, 574, 571, 3, 2, 2, 2, 574, 573, 3, 2, 2, 2, 575, 578, 3, 2, 2,
2, 576, 574, 3, 2, 2, 2, 576, 577, 3, 2, 2, 2, 577, 579, 3, 2, 2, 2, 578,
576, 3, 2, 2, 2, 579, 580, 7, 98, 2, 2, 580, 158, 3, 2, 2, 2, 581, 587,
7, 182, 2, 2, 582, 583, 7, 94, 2, 2, 583, 586, 7, 182, 2, 2, 584, 586,
10, 13, 2, 2, 585, 582, 3, 2, 2, 2, 585, 584, 3, 2, 2, 2, 586, 589, 3,
2, 2, 2, 587, 585, 3, 2, 2, 2, 587, 588, 3, 2, 2, 2, 588, 590, 3, 2, 2,
2, 589, 587, 3, 2, 2, 2, 590, 591, 7, 182, 2, 2, 591, 160, 3, 2, 2, 2,
592, 593, 7, 60, 2, 2, 593, 594, 7, 60, 2, 2, 594, 162, 3, 2, 2, 2, 34,
2, 169, 183, 191, 256, 262, 350, 380, 440, 459, 465, 470, 477, 482, 489,
494, 501, 504, 508, 510, 524, 527, 531, 536, 550, 552, 563, 565, 574, 576,
585, 587, 3, 2, 3, 2,
}
var lexerChannelNames = []string{
@ -280,10 +293,10 @@ var lexerLiteralNames = []string{
"", "", "", "", "", "':'", "';'", "'.'", "','", "'['", "']'", "'('", "')'",
"'{'", "'}'", "'>'", "'<'", "'=='", "'>='", "'<='", "'!='", "'*'", "'/'",
"'%'", "'+'", "'-'", "'--'", "'++'", "", "", "", "'='", "'?'", "'!~'",
"'=~'", "'FOR'", "'RETURN'", "'DISTINCT'", "'FILTER'", "'SORT'", "'LIMIT'",
"'LET'", "'COLLECT'", "", "'NONE'", "'NULL'", "", "'USE'", "'INTO'", "'KEEP'",
"'WITH'", "'COUNT'", "'ALL'", "'ANY'", "'AGGREGATE'", "'LIKE'", "", "'IN'",
"'DO'", "'WHILE'", "'@'",
"'=~'", "'FOR'", "'RETURN'", "'WAITFOR'", "'OPTIONS'", "'DISTINCT'", "'FILTER'",
"'SORT'", "'LIMIT'", "'LET'", "'COLLECT'", "", "'NONE'", "'NULL'", "",
"'USE'", "'INTO'", "'KEEP'", "'WITH'", "'COUNT'", "'ALL'", "'ANY'", "'AGGREGATE'",
"'EVENT'", "'LIKE'", "", "'IN'", "'DO'", "'WHILE'", "'@'",
}
var lexerSymbolicNames = []string{
@ -292,11 +305,11 @@ var lexerSymbolicNames = []string{
"CloseParen", "OpenBrace", "CloseBrace", "Gt", "Lt", "Eq", "Gte", "Lte",
"Neq", "Multi", "Div", "Mod", "Plus", "Minus", "MinusMinus", "PlusPlus",
"And", "Or", "Range", "Assign", "QuestionMark", "RegexNotMatch", "RegexMatch",
"For", "Return", "Distinct", "Filter", "Sort", "Limit", "Let", "Collect",
"SortDirection", "None", "Null", "BooleanLiteral", "Use", "Into", "Keep",
"With", "Count", "All", "Any", "Aggregate", "Like", "Not", "In", "Do",
"While", "Param", "Identifier", "StringLiteral", "IntegerLiteral", "FloatLiteral",
"NamespaceSegment",
"For", "Return", "Waitfor", "Options", "Distinct", "Filter", "Sort", "Limit",
"Let", "Collect", "SortDirection", "None", "Null", "BooleanLiteral", "Use",
"Into", "Keep", "With", "Count", "All", "Any", "Aggregate", "Event", "Like",
"Not", "In", "Do", "While", "Param", "Identifier", "StringLiteral", "IntegerLiteral",
"FloatLiteral", "NamespaceSegment", "UnknownIdentifier",
}
var lexerRuleNames = []string{
@ -305,12 +318,12 @@ var lexerRuleNames = []string{
"CloseParen", "OpenBrace", "CloseBrace", "Gt", "Lt", "Eq", "Gte", "Lte",
"Neq", "Multi", "Div", "Mod", "Plus", "Minus", "MinusMinus", "PlusPlus",
"And", "Or", "Range", "Assign", "QuestionMark", "RegexNotMatch", "RegexMatch",
"For", "Return", "Distinct", "Filter", "Sort", "Limit", "Let", "Collect",
"SortDirection", "None", "Null", "BooleanLiteral", "Use", "Into", "Keep",
"With", "Count", "All", "Any", "Aggregate", "Like", "Not", "In", "Do",
"While", "Param", "Identifier", "StringLiteral", "IntegerLiteral", "FloatLiteral",
"NamespaceSegment", "HexDigit", "DecimalIntegerLiteral", "ExponentPart",
"Letter", "Symbols", "Digit", "DQSring", "SQString", "BacktickString",
"For", "Return", "Waitfor", "Options", "Distinct", "Filter", "Sort", "Limit",
"Let", "Collect", "SortDirection", "None", "Null", "BooleanLiteral", "Use",
"Into", "Keep", "With", "Count", "All", "Any", "Aggregate", "Event", "Like",
"Not", "In", "Do", "While", "Param", "Identifier", "StringLiteral", "IntegerLiteral",
"FloatLiteral", "NamespaceSegment", "UnknownIdentifier", "HexDigit", "DecimalIntegerLiteral",
"ExponentPart", "Letter", "Symbols", "Digit", "DQSring", "SQString", "BacktickString",
"TickString", "NamespaceSeparator",
}
@ -387,33 +400,37 @@ const (
FqlLexerRegexMatch = 34
FqlLexerFor = 35
FqlLexerReturn = 36
FqlLexerDistinct = 37
FqlLexerFilter = 38
FqlLexerSort = 39
FqlLexerLimit = 40
FqlLexerLet = 41
FqlLexerCollect = 42
FqlLexerSortDirection = 43
FqlLexerNone = 44
FqlLexerNull = 45
FqlLexerBooleanLiteral = 46
FqlLexerUse = 47
FqlLexerInto = 48
FqlLexerKeep = 49
FqlLexerWith = 50
FqlLexerCount = 51
FqlLexerAll = 52
FqlLexerAny = 53
FqlLexerAggregate = 54
FqlLexerLike = 55
FqlLexerNot = 56
FqlLexerIn = 57
FqlLexerDo = 58
FqlLexerWhile = 59
FqlLexerParam = 60
FqlLexerIdentifier = 61
FqlLexerStringLiteral = 62
FqlLexerIntegerLiteral = 63
FqlLexerFloatLiteral = 64
FqlLexerNamespaceSegment = 65
FqlLexerWaitfor = 37
FqlLexerOptions = 38
FqlLexerDistinct = 39
FqlLexerFilter = 40
FqlLexerSort = 41
FqlLexerLimit = 42
FqlLexerLet = 43
FqlLexerCollect = 44
FqlLexerSortDirection = 45
FqlLexerNone = 46
FqlLexerNull = 47
FqlLexerBooleanLiteral = 48
FqlLexerUse = 49
FqlLexerInto = 50
FqlLexerKeep = 51
FqlLexerWith = 52
FqlLexerCount = 53
FqlLexerAll = 54
FqlLexerAny = 55
FqlLexerAggregate = 56
FqlLexerEvent = 57
FqlLexerLike = 58
FqlLexerNot = 59
FqlLexerIn = 60
FqlLexerDo = 61
FqlLexerWhile = 62
FqlLexerParam = 63
FqlLexerIdentifier = 64
FqlLexerStringLiteral = 65
FqlLexerIntegerLiteral = 66
FqlLexerFloatLiteral = 67
FqlLexerNamespaceSegment = 68
FqlLexerUnknownIdentifier = 69
)

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,12 @@ func (s *BaseFqlParserListener) EnterUse(ctx *UseContext) {}
// ExitUse is called when production use is exited.
func (s *BaseFqlParserListener) ExitUse(ctx *UseContext) {}
// EnterNamespaceIdentifier is called when production namespaceIdentifier is entered.
func (s *BaseFqlParserListener) EnterNamespaceIdentifier(ctx *NamespaceIdentifierContext) {}
// ExitNamespaceIdentifier is called when production namespaceIdentifier is exited.
func (s *BaseFqlParserListener) ExitNamespaceIdentifier(ctx *NamespaceIdentifierContext) {}
// EnterBody is called when production body is entered.
func (s *BaseFqlParserListener) EnterBody(ctx *BodyContext) {}
@ -62,6 +68,12 @@ func (s *BaseFqlParserListener) EnterBodyExpression(ctx *BodyExpressionContext)
// ExitBodyExpression is called when production bodyExpression is exited.
func (s *BaseFqlParserListener) ExitBodyExpression(ctx *BodyExpressionContext) {}
// EnterVariableDeclaration is called when production variableDeclaration is entered.
func (s *BaseFqlParserListener) EnterVariableDeclaration(ctx *VariableDeclarationContext) {}
// ExitVariableDeclaration is called when production variableDeclaration is exited.
func (s *BaseFqlParserListener) ExitVariableDeclaration(ctx *VariableDeclarationContext) {}
// EnterReturnExpression is called when production returnExpression is entered.
func (s *BaseFqlParserListener) EnterReturnExpression(ctx *ReturnExpressionContext) {}
@ -74,20 +86,6 @@ func (s *BaseFqlParserListener) EnterForExpression(ctx *ForExpressionContext) {}
// ExitForExpression is called when production forExpression is exited.
func (s *BaseFqlParserListener) ExitForExpression(ctx *ForExpressionContext) {}
// EnterForExpressionValueVariable is called when production forExpressionValueVariable is entered.
func (s *BaseFqlParserListener) EnterForExpressionValueVariable(ctx *ForExpressionValueVariableContext) {
}
// ExitForExpressionValueVariable is called when production forExpressionValueVariable is exited.
func (s *BaseFqlParserListener) ExitForExpressionValueVariable(ctx *ForExpressionValueVariableContext) {
}
// EnterForExpressionKeyVariable is called when production forExpressionKeyVariable is entered.
func (s *BaseFqlParserListener) EnterForExpressionKeyVariable(ctx *ForExpressionKeyVariableContext) {}
// ExitForExpressionKeyVariable is called when production forExpressionKeyVariable is exited.
func (s *BaseFqlParserListener) ExitForExpressionKeyVariable(ctx *ForExpressionKeyVariableContext) {}
// EnterForExpressionSource is called when production forExpressionSource is entered.
func (s *BaseFqlParserListener) EnterForExpressionSource(ctx *ForExpressionSourceContext) {}
@ -190,23 +188,35 @@ func (s *BaseFqlParserListener) EnterCollectCounter(ctx *CollectCounterContext)
// ExitCollectCounter is called when production collectCounter is exited.
func (s *BaseFqlParserListener) ExitCollectCounter(ctx *CollectCounterContext) {}
// EnterVariableDeclaration is called when production variableDeclaration is entered.
func (s *BaseFqlParserListener) EnterVariableDeclaration(ctx *VariableDeclarationContext) {}
// EnterOptionsClause is called when production optionsClause is entered.
func (s *BaseFqlParserListener) EnterOptionsClause(ctx *OptionsClauseContext) {}
// ExitVariableDeclaration is called when production variableDeclaration is exited.
func (s *BaseFqlParserListener) ExitVariableDeclaration(ctx *VariableDeclarationContext) {}
// ExitOptionsClause is called when production optionsClause is exited.
func (s *BaseFqlParserListener) ExitOptionsClause(ctx *OptionsClauseContext) {}
// EnterParam is called when production param is entered.
func (s *BaseFqlParserListener) EnterParam(ctx *ParamContext) {}
// EnterWaitForExpression is called when production waitForExpression is entered.
func (s *BaseFqlParserListener) EnterWaitForExpression(ctx *WaitForExpressionContext) {}
// ExitParam is called when production param is exited.
func (s *BaseFqlParserListener) ExitParam(ctx *ParamContext) {}
// ExitWaitForExpression is called when production waitForExpression is exited.
func (s *BaseFqlParserListener) ExitWaitForExpression(ctx *WaitForExpressionContext) {}
// EnterVariable is called when production variable is entered.
func (s *BaseFqlParserListener) EnterVariable(ctx *VariableContext) {}
// EnterWaitForTimeout is called when production waitForTimeout is entered.
func (s *BaseFqlParserListener) EnterWaitForTimeout(ctx *WaitForTimeoutContext) {}
// ExitVariable is called when production variable is exited.
func (s *BaseFqlParserListener) ExitVariable(ctx *VariableContext) {}
// ExitWaitForTimeout is called when production waitForTimeout is exited.
func (s *BaseFqlParserListener) ExitWaitForTimeout(ctx *WaitForTimeoutContext) {}
// EnterWaitForEventName is called when production waitForEventName is entered.
func (s *BaseFqlParserListener) EnterWaitForEventName(ctx *WaitForEventNameContext) {}
// ExitWaitForEventName is called when production waitForEventName is exited.
func (s *BaseFqlParserListener) ExitWaitForEventName(ctx *WaitForEventNameContext) {}
// EnterWaitForEventSource is called when production waitForEventSource is entered.
func (s *BaseFqlParserListener) EnterWaitForEventSource(ctx *WaitForEventSourceContext) {}
// ExitWaitForEventSource is called when production waitForEventSource is exited.
func (s *BaseFqlParserListener) ExitWaitForEventSource(ctx *WaitForEventSourceContext) {}
// EnterRangeOperator is called when production rangeOperator is entered.
func (s *BaseFqlParserListener) EnterRangeOperator(ctx *RangeOperatorContext) {}
@ -226,54 +236,12 @@ func (s *BaseFqlParserListener) EnterObjectLiteral(ctx *ObjectLiteralContext) {}
// ExitObjectLiteral is called when production objectLiteral is exited.
func (s *BaseFqlParserListener) ExitObjectLiteral(ctx *ObjectLiteralContext) {}
// EnterBooleanLiteral is called when production booleanLiteral is entered.
func (s *BaseFqlParserListener) EnterBooleanLiteral(ctx *BooleanLiteralContext) {}
// ExitBooleanLiteral is called when production booleanLiteral is exited.
func (s *BaseFqlParserListener) ExitBooleanLiteral(ctx *BooleanLiteralContext) {}
// EnterStringLiteral is called when production stringLiteral is entered.
func (s *BaseFqlParserListener) EnterStringLiteral(ctx *StringLiteralContext) {}
// ExitStringLiteral is called when production stringLiteral is exited.
func (s *BaseFqlParserListener) ExitStringLiteral(ctx *StringLiteralContext) {}
// EnterIntegerLiteral is called when production integerLiteral is entered.
func (s *BaseFqlParserListener) EnterIntegerLiteral(ctx *IntegerLiteralContext) {}
// ExitIntegerLiteral is called when production integerLiteral is exited.
func (s *BaseFqlParserListener) ExitIntegerLiteral(ctx *IntegerLiteralContext) {}
// EnterFloatLiteral is called when production floatLiteral is entered.
func (s *BaseFqlParserListener) EnterFloatLiteral(ctx *FloatLiteralContext) {}
// ExitFloatLiteral is called when production floatLiteral is exited.
func (s *BaseFqlParserListener) ExitFloatLiteral(ctx *FloatLiteralContext) {}
// EnterNoneLiteral is called when production noneLiteral is entered.
func (s *BaseFqlParserListener) EnterNoneLiteral(ctx *NoneLiteralContext) {}
// ExitNoneLiteral is called when production noneLiteral is exited.
func (s *BaseFqlParserListener) ExitNoneLiteral(ctx *NoneLiteralContext) {}
// EnterArrayElementList is called when production arrayElementList is entered.
func (s *BaseFqlParserListener) EnterArrayElementList(ctx *ArrayElementListContext) {}
// ExitArrayElementList is called when production arrayElementList is exited.
func (s *BaseFqlParserListener) ExitArrayElementList(ctx *ArrayElementListContext) {}
// EnterPropertyAssignment is called when production propertyAssignment is entered.
func (s *BaseFqlParserListener) EnterPropertyAssignment(ctx *PropertyAssignmentContext) {}
// ExitPropertyAssignment is called when production propertyAssignment is exited.
func (s *BaseFqlParserListener) ExitPropertyAssignment(ctx *PropertyAssignmentContext) {}
// EnterShorthandPropertyName is called when production shorthandPropertyName is entered.
func (s *BaseFqlParserListener) EnterShorthandPropertyName(ctx *ShorthandPropertyNameContext) {}
// ExitShorthandPropertyName is called when production shorthandPropertyName is exited.
func (s *BaseFqlParserListener) ExitShorthandPropertyName(ctx *ShorthandPropertyNameContext) {}
// EnterComputedPropertyName is called when production computedPropertyName is entered.
func (s *BaseFqlParserListener) EnterComputedPropertyName(ctx *ComputedPropertyNameContext) {}
@ -286,71 +254,89 @@ func (s *BaseFqlParserListener) EnterPropertyName(ctx *PropertyNameContext) {}
// ExitPropertyName is called when production propertyName is exited.
func (s *BaseFqlParserListener) ExitPropertyName(ctx *PropertyNameContext) {}
// EnterBooleanLiteral is called when production booleanLiteral is entered.
func (s *BaseFqlParserListener) EnterBooleanLiteral(ctx *BooleanLiteralContext) {}
// ExitBooleanLiteral is called when production booleanLiteral is exited.
func (s *BaseFqlParserListener) ExitBooleanLiteral(ctx *BooleanLiteralContext) {}
// EnterStringLiteral is called when production stringLiteral is entered.
func (s *BaseFqlParserListener) EnterStringLiteral(ctx *StringLiteralContext) {}
// ExitStringLiteral is called when production stringLiteral is exited.
func (s *BaseFqlParserListener) ExitStringLiteral(ctx *StringLiteralContext) {}
// EnterFloatLiteral is called when production floatLiteral is entered.
func (s *BaseFqlParserListener) EnterFloatLiteral(ctx *FloatLiteralContext) {}
// ExitFloatLiteral is called when production floatLiteral is exited.
func (s *BaseFqlParserListener) ExitFloatLiteral(ctx *FloatLiteralContext) {}
// EnterIntegerLiteral is called when production integerLiteral is entered.
func (s *BaseFqlParserListener) EnterIntegerLiteral(ctx *IntegerLiteralContext) {}
// ExitIntegerLiteral is called when production integerLiteral is exited.
func (s *BaseFqlParserListener) ExitIntegerLiteral(ctx *IntegerLiteralContext) {}
// EnterNoneLiteral is called when production noneLiteral is entered.
func (s *BaseFqlParserListener) EnterNoneLiteral(ctx *NoneLiteralContext) {}
// ExitNoneLiteral is called when production noneLiteral is exited.
func (s *BaseFqlParserListener) ExitNoneLiteral(ctx *NoneLiteralContext) {}
// EnterExpressionGroup is called when production expressionGroup is entered.
func (s *BaseFqlParserListener) EnterExpressionGroup(ctx *ExpressionGroupContext) {}
// ExitExpressionGroup is called when production expressionGroup is exited.
func (s *BaseFqlParserListener) ExitExpressionGroup(ctx *ExpressionGroupContext) {}
// EnterNamespaceIdentifier is called when production namespaceIdentifier is entered.
func (s *BaseFqlParserListener) EnterNamespaceIdentifier(ctx *NamespaceIdentifierContext) {}
// ExitNamespaceIdentifier is called when production namespaceIdentifier is exited.
func (s *BaseFqlParserListener) ExitNamespaceIdentifier(ctx *NamespaceIdentifierContext) {}
// EnterNamespace is called when production namespace is entered.
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) {}
// ExitFunctionCallExpression is called when production functionCallExpression is exited.
func (s *BaseFqlParserListener) ExitFunctionCallExpression(ctx *FunctionCallExpressionContext) {}
// EnterMember is called when production member is entered.
func (s *BaseFqlParserListener) EnterMember(ctx *MemberContext) {}
// ExitMember is called when production member is exited.
func (s *BaseFqlParserListener) ExitMember(ctx *MemberContext) {}
// EnterMemberPath is called when production memberPath is entered.
func (s *BaseFqlParserListener) EnterMemberPath(ctx *MemberPathContext) {}
// ExitMemberPath is called when production memberPath is exited.
func (s *BaseFqlParserListener) ExitMemberPath(ctx *MemberPathContext) {}
// EnterMemberExpression is called when production memberExpression is entered.
func (s *BaseFqlParserListener) EnterMemberExpression(ctx *MemberExpressionContext) {}
// ExitMemberExpression is called when production memberExpression is exited.
func (s *BaseFqlParserListener) ExitMemberExpression(ctx *MemberExpressionContext) {}
// EnterArguments is called when production arguments is entered.
func (s *BaseFqlParserListener) EnterArguments(ctx *ArgumentsContext) {}
// ExitArguments is called when production arguments is exited.
func (s *BaseFqlParserListener) ExitArguments(ctx *ArgumentsContext) {}
// EnterExpression is called when production expression is entered.
func (s *BaseFqlParserListener) EnterExpression(ctx *ExpressionContext) {}
// ExitExpression is called when production expression is exited.
func (s *BaseFqlParserListener) ExitExpression(ctx *ExpressionContext) {}
// EnterForTernaryExpression is called when production forTernaryExpression is entered.
func (s *BaseFqlParserListener) EnterForTernaryExpression(ctx *ForTernaryExpressionContext) {}
// EnterMemberExpression is called when production memberExpression is entered.
func (s *BaseFqlParserListener) EnterMemberExpression(ctx *MemberExpressionContext) {}
// ExitForTernaryExpression is called when production forTernaryExpression is exited.
func (s *BaseFqlParserListener) ExitForTernaryExpression(ctx *ForTernaryExpressionContext) {}
// ExitMemberExpression is called when production memberExpression is exited.
func (s *BaseFqlParserListener) ExitMemberExpression(ctx *MemberExpressionContext) {}
// EnterMemberExpressionSource is called when production memberExpressionSource is entered.
func (s *BaseFqlParserListener) EnterMemberExpressionSource(ctx *MemberExpressionSourceContext) {}
// ExitMemberExpressionSource is called when production memberExpressionSource is exited.
func (s *BaseFqlParserListener) ExitMemberExpressionSource(ctx *MemberExpressionSourceContext) {}
// EnterMemberExpressionPath is called when production memberExpressionPath is entered.
func (s *BaseFqlParserListener) EnterMemberExpressionPath(ctx *MemberExpressionPathContext) {}
// ExitMemberExpressionPath is called when production memberExpressionPath is exited.
func (s *BaseFqlParserListener) ExitMemberExpressionPath(ctx *MemberExpressionPathContext) {}
// EnterFunctionCallExpression is called when production functionCallExpression is entered.
func (s *BaseFqlParserListener) EnterFunctionCallExpression(ctx *FunctionCallExpressionContext) {}
// ExitFunctionCallExpression is called when production functionCallExpression is exited.
func (s *BaseFqlParserListener) ExitFunctionCallExpression(ctx *FunctionCallExpressionContext) {}
// 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) {}
// EnterNamespace is called when production namespace is entered.
func (s *BaseFqlParserListener) EnterNamespace(ctx *NamespaceContext) {}
// ExitNamespace is called when production namespace is exited.
func (s *BaseFqlParserListener) ExitNamespace(ctx *NamespaceContext) {}
// EnterArguments is called when production arguments is entered.
func (s *BaseFqlParserListener) EnterArguments(ctx *ArgumentsContext) {}
// ExitArguments is called when production arguments is exited.
func (s *BaseFqlParserListener) ExitArguments(ctx *ArgumentsContext) {}
// EnterArrayOperator is called when production arrayOperator is entered.
func (s *BaseFqlParserListener) EnterArrayOperator(ctx *ArrayOperatorContext) {}
@ -411,3 +397,15 @@ func (s *BaseFqlParserListener) EnterUnaryOperator(ctx *UnaryOperatorContext) {}
// ExitUnaryOperator is called when production unaryOperator is exited.
func (s *BaseFqlParserListener) ExitUnaryOperator(ctx *UnaryOperatorContext) {}
// EnterParam is called when production param is entered.
func (s *BaseFqlParserListener) EnterParam(ctx *ParamContext) {}
// ExitParam is called when production param is exited.
func (s *BaseFqlParserListener) ExitParam(ctx *ParamContext) {}
// EnterVariable is called when production variable is entered.
func (s *BaseFqlParserListener) EnterVariable(ctx *VariableContext) {}
// ExitVariable is called when production variable is exited.
func (s *BaseFqlParserListener) ExitVariable(ctx *VariableContext) {}

View File

@ -23,6 +23,10 @@ func (v *BaseFqlParserVisitor) VisitUse(ctx *UseContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitNamespaceIdentifier(ctx *NamespaceIdentifierContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitBody(ctx *BodyContext) interface{} {
return v.VisitChildren(ctx)
}
@ -35,6 +39,10 @@ func (v *BaseFqlParserVisitor) VisitBodyExpression(ctx *BodyExpressionContext) i
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitVariableDeclaration(ctx *VariableDeclarationContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitReturnExpression(ctx *ReturnExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
@ -43,14 +51,6 @@ func (v *BaseFqlParserVisitor) VisitForExpression(ctx *ForExpressionContext) int
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitForExpressionValueVariable(ctx *ForExpressionValueVariableContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitForExpressionKeyVariable(ctx *ForExpressionKeyVariableContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitForExpressionSource(ctx *ForExpressionSourceContext) interface{} {
return v.VisitChildren(ctx)
}
@ -119,15 +119,23 @@ func (v *BaseFqlParserVisitor) VisitCollectCounter(ctx *CollectCounterContext) i
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitVariableDeclaration(ctx *VariableDeclarationContext) interface{} {
func (v *BaseFqlParserVisitor) VisitOptionsClause(ctx *OptionsClauseContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitParam(ctx *ParamContext) interface{} {
func (v *BaseFqlParserVisitor) VisitWaitForExpression(ctx *WaitForExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitVariable(ctx *VariableContext) interface{} {
func (v *BaseFqlParserVisitor) VisitWaitForTimeout(ctx *WaitForTimeoutContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitWaitForEventName(ctx *WaitForEventNameContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitWaitForEventSource(ctx *WaitForEventSourceContext) interface{} {
return v.VisitChildren(ctx)
}
@ -143,38 +151,10 @@ func (v *BaseFqlParserVisitor) VisitObjectLiteral(ctx *ObjectLiteralContext) int
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitStringLiteral(ctx *StringLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitIntegerLiteral(ctx *IntegerLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFloatLiteral(ctx *FloatLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitNoneLiteral(ctx *NoneLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitArrayElementList(ctx *ArrayElementListContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitPropertyAssignment(ctx *PropertyAssignmentContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitShorthandPropertyName(ctx *ShorthandPropertyNameContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitComputedPropertyName(ctx *ComputedPropertyNameContext) interface{} {
return v.VisitChildren(ctx)
}
@ -183,47 +163,59 @@ func (v *BaseFqlParserVisitor) VisitPropertyName(ctx *PropertyNameContext) inter
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitStringLiteral(ctx *StringLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFloatLiteral(ctx *FloatLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitIntegerLiteral(ctx *IntegerLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitNoneLiteral(ctx *NoneLiteralContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitExpressionGroup(ctx *ExpressionGroupContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitNamespaceIdentifier(ctx *NamespaceIdentifierContext) interface{} {
return v.VisitChildren(ctx)
}
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)
}
func (v *BaseFqlParserVisitor) VisitMember(ctx *MemberContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitMemberPath(ctx *MemberPathContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitMemberExpression(ctx *MemberExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitArguments(ctx *ArgumentsContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitExpression(ctx *ExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitForTernaryExpression(ctx *ForTernaryExpressionContext) interface{} {
func (v *BaseFqlParserVisitor) VisitMemberExpression(ctx *MemberExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitMemberExpressionSource(ctx *MemberExpressionSourceContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitMemberExpressionPath(ctx *MemberExpressionPathContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFunctionCallExpression(ctx *FunctionCallExpressionContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitFunctionIdentifier(ctx *FunctionIdentifierContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitNamespace(ctx *NamespaceContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitArguments(ctx *ArgumentsContext) interface{} {
return v.VisitChildren(ctx)
}
@ -266,3 +258,11 @@ func (v *BaseFqlParserVisitor) VisitAdditiveOperator(ctx *AdditiveOperatorContex
func (v *BaseFqlParserVisitor) VisitUnaryOperator(ctx *UnaryOperatorContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitParam(ctx *ParamContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseFqlParserVisitor) VisitVariable(ctx *VariableContext) interface{} {
return v.VisitChildren(ctx)
}

View File

@ -19,6 +19,9 @@ type FqlParserListener interface {
// EnterUse is called when entering the use production.
EnterUse(c *UseContext)
// EnterNamespaceIdentifier is called when entering the namespaceIdentifier production.
EnterNamespaceIdentifier(c *NamespaceIdentifierContext)
// EnterBody is called when entering the body production.
EnterBody(c *BodyContext)
@ -28,18 +31,15 @@ type FqlParserListener interface {
// EnterBodyExpression is called when entering the bodyExpression production.
EnterBodyExpression(c *BodyExpressionContext)
// EnterVariableDeclaration is called when entering the variableDeclaration production.
EnterVariableDeclaration(c *VariableDeclarationContext)
// EnterReturnExpression is called when entering the returnExpression production.
EnterReturnExpression(c *ReturnExpressionContext)
// EnterForExpression is called when entering the forExpression production.
EnterForExpression(c *ForExpressionContext)
// EnterForExpressionValueVariable is called when entering the forExpressionValueVariable production.
EnterForExpressionValueVariable(c *ForExpressionValueVariableContext)
// EnterForExpressionKeyVariable is called when entering the forExpressionKeyVariable production.
EnterForExpressionKeyVariable(c *ForExpressionKeyVariableContext)
// EnterForExpressionSource is called when entering the forExpressionSource production.
EnterForExpressionSource(c *ForExpressionSourceContext)
@ -91,14 +91,20 @@ type FqlParserListener interface {
// EnterCollectCounter is called when entering the collectCounter production.
EnterCollectCounter(c *CollectCounterContext)
// EnterVariableDeclaration is called when entering the variableDeclaration production.
EnterVariableDeclaration(c *VariableDeclarationContext)
// EnterOptionsClause is called when entering the optionsClause production.
EnterOptionsClause(c *OptionsClauseContext)
// EnterParam is called when entering the param production.
EnterParam(c *ParamContext)
// EnterWaitForExpression is called when entering the waitForExpression production.
EnterWaitForExpression(c *WaitForExpressionContext)
// EnterVariable is called when entering the variable production.
EnterVariable(c *VariableContext)
// EnterWaitForTimeout is called when entering the waitForTimeout production.
EnterWaitForTimeout(c *WaitForTimeoutContext)
// EnterWaitForEventName is called when entering the waitForEventName production.
EnterWaitForEventName(c *WaitForEventNameContext)
// EnterWaitForEventSource is called when entering the waitForEventSource production.
EnterWaitForEventSource(c *WaitForEventSourceContext)
// EnterRangeOperator is called when entering the rangeOperator production.
EnterRangeOperator(c *RangeOperatorContext)
@ -109,68 +115,56 @@ type FqlParserListener interface {
// EnterObjectLiteral is called when entering the objectLiteral production.
EnterObjectLiteral(c *ObjectLiteralContext)
// EnterBooleanLiteral is called when entering the booleanLiteral production.
EnterBooleanLiteral(c *BooleanLiteralContext)
// EnterStringLiteral is called when entering the stringLiteral production.
EnterStringLiteral(c *StringLiteralContext)
// EnterIntegerLiteral is called when entering the integerLiteral production.
EnterIntegerLiteral(c *IntegerLiteralContext)
// EnterFloatLiteral is called when entering the floatLiteral production.
EnterFloatLiteral(c *FloatLiteralContext)
// EnterNoneLiteral is called when entering the noneLiteral production.
EnterNoneLiteral(c *NoneLiteralContext)
// EnterArrayElementList is called when entering the arrayElementList production.
EnterArrayElementList(c *ArrayElementListContext)
// EnterPropertyAssignment is called when entering the propertyAssignment production.
EnterPropertyAssignment(c *PropertyAssignmentContext)
// EnterShorthandPropertyName is called when entering the shorthandPropertyName production.
EnterShorthandPropertyName(c *ShorthandPropertyNameContext)
// EnterComputedPropertyName is called when entering the computedPropertyName production.
EnterComputedPropertyName(c *ComputedPropertyNameContext)
// EnterPropertyName is called when entering the propertyName production.
EnterPropertyName(c *PropertyNameContext)
// EnterBooleanLiteral is called when entering the booleanLiteral production.
EnterBooleanLiteral(c *BooleanLiteralContext)
// EnterStringLiteral is called when entering the stringLiteral production.
EnterStringLiteral(c *StringLiteralContext)
// EnterFloatLiteral is called when entering the floatLiteral production.
EnterFloatLiteral(c *FloatLiteralContext)
// EnterIntegerLiteral is called when entering the integerLiteral production.
EnterIntegerLiteral(c *IntegerLiteralContext)
// EnterNoneLiteral is called when entering the noneLiteral production.
EnterNoneLiteral(c *NoneLiteralContext)
// EnterExpressionGroup is called when entering the expressionGroup production.
EnterExpressionGroup(c *ExpressionGroupContext)
// EnterNamespaceIdentifier is called when entering the namespaceIdentifier production.
EnterNamespaceIdentifier(c *NamespaceIdentifierContext)
// 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)
// EnterMember is called when entering the member production.
EnterMember(c *MemberContext)
// EnterMemberPath is called when entering the memberPath production.
EnterMemberPath(c *MemberPathContext)
// EnterMemberExpression is called when entering the memberExpression production.
EnterMemberExpression(c *MemberExpressionContext)
// EnterArguments is called when entering the arguments production.
EnterArguments(c *ArgumentsContext)
// EnterExpression is called when entering the expression production.
EnterExpression(c *ExpressionContext)
// EnterForTernaryExpression is called when entering the forTernaryExpression production.
EnterForTernaryExpression(c *ForTernaryExpressionContext)
// EnterMemberExpression is called when entering the memberExpression production.
EnterMemberExpression(c *MemberExpressionContext)
// EnterMemberExpressionSource is called when entering the memberExpressionSource production.
EnterMemberExpressionSource(c *MemberExpressionSourceContext)
// EnterMemberExpressionPath is called when entering the memberExpressionPath production.
EnterMemberExpressionPath(c *MemberExpressionPathContext)
// EnterFunctionCallExpression is called when entering the functionCallExpression production.
EnterFunctionCallExpression(c *FunctionCallExpressionContext)
// EnterFunctionIdentifier is called when entering the functionIdentifier production.
EnterFunctionIdentifier(c *FunctionIdentifierContext)
// EnterNamespace is called when entering the namespace production.
EnterNamespace(c *NamespaceContext)
// EnterArguments is called when entering the arguments production.
EnterArguments(c *ArgumentsContext)
// EnterArrayOperator is called when entering the arrayOperator production.
EnterArrayOperator(c *ArrayOperatorContext)
@ -202,6 +196,12 @@ type FqlParserListener interface {
// EnterUnaryOperator is called when entering the unaryOperator production.
EnterUnaryOperator(c *UnaryOperatorContext)
// EnterParam is called when entering the param production.
EnterParam(c *ParamContext)
// EnterVariable is called when entering the variable production.
EnterVariable(c *VariableContext)
// ExitProgram is called when exiting the program production.
ExitProgram(c *ProgramContext)
@ -214,6 +214,9 @@ type FqlParserListener interface {
// ExitUse is called when exiting the use production.
ExitUse(c *UseContext)
// ExitNamespaceIdentifier is called when exiting the namespaceIdentifier production.
ExitNamespaceIdentifier(c *NamespaceIdentifierContext)
// ExitBody is called when exiting the body production.
ExitBody(c *BodyContext)
@ -223,18 +226,15 @@ type FqlParserListener interface {
// ExitBodyExpression is called when exiting the bodyExpression production.
ExitBodyExpression(c *BodyExpressionContext)
// ExitVariableDeclaration is called when exiting the variableDeclaration production.
ExitVariableDeclaration(c *VariableDeclarationContext)
// ExitReturnExpression is called when exiting the returnExpression production.
ExitReturnExpression(c *ReturnExpressionContext)
// ExitForExpression is called when exiting the forExpression production.
ExitForExpression(c *ForExpressionContext)
// ExitForExpressionValueVariable is called when exiting the forExpressionValueVariable production.
ExitForExpressionValueVariable(c *ForExpressionValueVariableContext)
// ExitForExpressionKeyVariable is called when exiting the forExpressionKeyVariable production.
ExitForExpressionKeyVariable(c *ForExpressionKeyVariableContext)
// ExitForExpressionSource is called when exiting the forExpressionSource production.
ExitForExpressionSource(c *ForExpressionSourceContext)
@ -286,14 +286,20 @@ type FqlParserListener interface {
// ExitCollectCounter is called when exiting the collectCounter production.
ExitCollectCounter(c *CollectCounterContext)
// ExitVariableDeclaration is called when exiting the variableDeclaration production.
ExitVariableDeclaration(c *VariableDeclarationContext)
// ExitOptionsClause is called when exiting the optionsClause production.
ExitOptionsClause(c *OptionsClauseContext)
// ExitParam is called when exiting the param production.
ExitParam(c *ParamContext)
// ExitWaitForExpression is called when exiting the waitForExpression production.
ExitWaitForExpression(c *WaitForExpressionContext)
// ExitVariable is called when exiting the variable production.
ExitVariable(c *VariableContext)
// ExitWaitForTimeout is called when exiting the waitForTimeout production.
ExitWaitForTimeout(c *WaitForTimeoutContext)
// ExitWaitForEventName is called when exiting the waitForEventName production.
ExitWaitForEventName(c *WaitForEventNameContext)
// ExitWaitForEventSource is called when exiting the waitForEventSource production.
ExitWaitForEventSource(c *WaitForEventSourceContext)
// ExitRangeOperator is called when exiting the rangeOperator production.
ExitRangeOperator(c *RangeOperatorContext)
@ -304,68 +310,56 @@ type FqlParserListener interface {
// ExitObjectLiteral is called when exiting the objectLiteral production.
ExitObjectLiteral(c *ObjectLiteralContext)
// ExitBooleanLiteral is called when exiting the booleanLiteral production.
ExitBooleanLiteral(c *BooleanLiteralContext)
// ExitStringLiteral is called when exiting the stringLiteral production.
ExitStringLiteral(c *StringLiteralContext)
// ExitIntegerLiteral is called when exiting the integerLiteral production.
ExitIntegerLiteral(c *IntegerLiteralContext)
// ExitFloatLiteral is called when exiting the floatLiteral production.
ExitFloatLiteral(c *FloatLiteralContext)
// ExitNoneLiteral is called when exiting the noneLiteral production.
ExitNoneLiteral(c *NoneLiteralContext)
// ExitArrayElementList is called when exiting the arrayElementList production.
ExitArrayElementList(c *ArrayElementListContext)
// ExitPropertyAssignment is called when exiting the propertyAssignment production.
ExitPropertyAssignment(c *PropertyAssignmentContext)
// ExitShorthandPropertyName is called when exiting the shorthandPropertyName production.
ExitShorthandPropertyName(c *ShorthandPropertyNameContext)
// ExitComputedPropertyName is called when exiting the computedPropertyName production.
ExitComputedPropertyName(c *ComputedPropertyNameContext)
// ExitPropertyName is called when exiting the propertyName production.
ExitPropertyName(c *PropertyNameContext)
// ExitBooleanLiteral is called when exiting the booleanLiteral production.
ExitBooleanLiteral(c *BooleanLiteralContext)
// ExitStringLiteral is called when exiting the stringLiteral production.
ExitStringLiteral(c *StringLiteralContext)
// ExitFloatLiteral is called when exiting the floatLiteral production.
ExitFloatLiteral(c *FloatLiteralContext)
// ExitIntegerLiteral is called when exiting the integerLiteral production.
ExitIntegerLiteral(c *IntegerLiteralContext)
// ExitNoneLiteral is called when exiting the noneLiteral production.
ExitNoneLiteral(c *NoneLiteralContext)
// ExitExpressionGroup is called when exiting the expressionGroup production.
ExitExpressionGroup(c *ExpressionGroupContext)
// ExitNamespaceIdentifier is called when exiting the namespaceIdentifier production.
ExitNamespaceIdentifier(c *NamespaceIdentifierContext)
// 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)
// ExitMember is called when exiting the member production.
ExitMember(c *MemberContext)
// ExitMemberPath is called when exiting the memberPath production.
ExitMemberPath(c *MemberPathContext)
// ExitMemberExpression is called when exiting the memberExpression production.
ExitMemberExpression(c *MemberExpressionContext)
// ExitArguments is called when exiting the arguments production.
ExitArguments(c *ArgumentsContext)
// ExitExpression is called when exiting the expression production.
ExitExpression(c *ExpressionContext)
// ExitForTernaryExpression is called when exiting the forTernaryExpression production.
ExitForTernaryExpression(c *ForTernaryExpressionContext)
// ExitMemberExpression is called when exiting the memberExpression production.
ExitMemberExpression(c *MemberExpressionContext)
// ExitMemberExpressionSource is called when exiting the memberExpressionSource production.
ExitMemberExpressionSource(c *MemberExpressionSourceContext)
// ExitMemberExpressionPath is called when exiting the memberExpressionPath production.
ExitMemberExpressionPath(c *MemberExpressionPathContext)
// ExitFunctionCallExpression is called when exiting the functionCallExpression production.
ExitFunctionCallExpression(c *FunctionCallExpressionContext)
// ExitFunctionIdentifier is called when exiting the functionIdentifier production.
ExitFunctionIdentifier(c *FunctionIdentifierContext)
// ExitNamespace is called when exiting the namespace production.
ExitNamespace(c *NamespaceContext)
// ExitArguments is called when exiting the arguments production.
ExitArguments(c *ArgumentsContext)
// ExitArrayOperator is called when exiting the arrayOperator production.
ExitArrayOperator(c *ArrayOperatorContext)
@ -396,4 +390,10 @@ type FqlParserListener interface {
// ExitUnaryOperator is called when exiting the unaryOperator production.
ExitUnaryOperator(c *UnaryOperatorContext)
// ExitParam is called when exiting the param production.
ExitParam(c *ParamContext)
// ExitVariable is called when exiting the variable production.
ExitVariable(c *VariableContext)
}

View File

@ -19,6 +19,9 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#use.
VisitUse(ctx *UseContext) interface{}
// Visit a parse tree produced by FqlParser#namespaceIdentifier.
VisitNamespaceIdentifier(ctx *NamespaceIdentifierContext) interface{}
// Visit a parse tree produced by FqlParser#body.
VisitBody(ctx *BodyContext) interface{}
@ -28,18 +31,15 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#bodyExpression.
VisitBodyExpression(ctx *BodyExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#variableDeclaration.
VisitVariableDeclaration(ctx *VariableDeclarationContext) interface{}
// Visit a parse tree produced by FqlParser#returnExpression.
VisitReturnExpression(ctx *ReturnExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#forExpression.
VisitForExpression(ctx *ForExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#forExpressionValueVariable.
VisitForExpressionValueVariable(ctx *ForExpressionValueVariableContext) interface{}
// Visit a parse tree produced by FqlParser#forExpressionKeyVariable.
VisitForExpressionKeyVariable(ctx *ForExpressionKeyVariableContext) interface{}
// Visit a parse tree produced by FqlParser#forExpressionSource.
VisitForExpressionSource(ctx *ForExpressionSourceContext) interface{}
@ -91,14 +91,20 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#collectCounter.
VisitCollectCounter(ctx *CollectCounterContext) interface{}
// Visit a parse tree produced by FqlParser#variableDeclaration.
VisitVariableDeclaration(ctx *VariableDeclarationContext) interface{}
// Visit a parse tree produced by FqlParser#optionsClause.
VisitOptionsClause(ctx *OptionsClauseContext) interface{}
// Visit a parse tree produced by FqlParser#param.
VisitParam(ctx *ParamContext) interface{}
// Visit a parse tree produced by FqlParser#waitForExpression.
VisitWaitForExpression(ctx *WaitForExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#variable.
VisitVariable(ctx *VariableContext) interface{}
// Visit a parse tree produced by FqlParser#waitForTimeout.
VisitWaitForTimeout(ctx *WaitForTimeoutContext) interface{}
// Visit a parse tree produced by FqlParser#waitForEventName.
VisitWaitForEventName(ctx *WaitForEventNameContext) interface{}
// Visit a parse tree produced by FqlParser#waitForEventSource.
VisitWaitForEventSource(ctx *WaitForEventSourceContext) interface{}
// Visit a parse tree produced by FqlParser#rangeOperator.
VisitRangeOperator(ctx *RangeOperatorContext) interface{}
@ -109,68 +115,56 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#objectLiteral.
VisitObjectLiteral(ctx *ObjectLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#booleanLiteral.
VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#stringLiteral.
VisitStringLiteral(ctx *StringLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#integerLiteral.
VisitIntegerLiteral(ctx *IntegerLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#floatLiteral.
VisitFloatLiteral(ctx *FloatLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#noneLiteral.
VisitNoneLiteral(ctx *NoneLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#arrayElementList.
VisitArrayElementList(ctx *ArrayElementListContext) interface{}
// Visit a parse tree produced by FqlParser#propertyAssignment.
VisitPropertyAssignment(ctx *PropertyAssignmentContext) interface{}
// Visit a parse tree produced by FqlParser#shorthandPropertyName.
VisitShorthandPropertyName(ctx *ShorthandPropertyNameContext) interface{}
// Visit a parse tree produced by FqlParser#computedPropertyName.
VisitComputedPropertyName(ctx *ComputedPropertyNameContext) interface{}
// Visit a parse tree produced by FqlParser#propertyName.
VisitPropertyName(ctx *PropertyNameContext) interface{}
// Visit a parse tree produced by FqlParser#booleanLiteral.
VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#stringLiteral.
VisitStringLiteral(ctx *StringLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#floatLiteral.
VisitFloatLiteral(ctx *FloatLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#integerLiteral.
VisitIntegerLiteral(ctx *IntegerLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#noneLiteral.
VisitNoneLiteral(ctx *NoneLiteralContext) interface{}
// Visit a parse tree produced by FqlParser#expressionGroup.
VisitExpressionGroup(ctx *ExpressionGroupContext) interface{}
// Visit a parse tree produced by FqlParser#namespaceIdentifier.
VisitNamespaceIdentifier(ctx *NamespaceIdentifierContext) 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{}
// Visit a parse tree produced by FqlParser#member.
VisitMember(ctx *MemberContext) interface{}
// Visit a parse tree produced by FqlParser#memberPath.
VisitMemberPath(ctx *MemberPathContext) interface{}
// Visit a parse tree produced by FqlParser#memberExpression.
VisitMemberExpression(ctx *MemberExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#arguments.
VisitArguments(ctx *ArgumentsContext) interface{}
// Visit a parse tree produced by FqlParser#expression.
VisitExpression(ctx *ExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#forTernaryExpression.
VisitForTernaryExpression(ctx *ForTernaryExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#memberExpression.
VisitMemberExpression(ctx *MemberExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#memberExpressionSource.
VisitMemberExpressionSource(ctx *MemberExpressionSourceContext) interface{}
// Visit a parse tree produced by FqlParser#memberExpressionPath.
VisitMemberExpressionPath(ctx *MemberExpressionPathContext) interface{}
// Visit a parse tree produced by FqlParser#functionCallExpression.
VisitFunctionCallExpression(ctx *FunctionCallExpressionContext) interface{}
// Visit a parse tree produced by FqlParser#functionIdentifier.
VisitFunctionIdentifier(ctx *FunctionIdentifierContext) interface{}
// Visit a parse tree produced by FqlParser#namespace.
VisitNamespace(ctx *NamespaceContext) interface{}
// Visit a parse tree produced by FqlParser#arguments.
VisitArguments(ctx *ArgumentsContext) interface{}
// Visit a parse tree produced by FqlParser#arrayOperator.
VisitArrayOperator(ctx *ArrayOperatorContext) interface{}
@ -201,4 +195,10 @@ type FqlParserVisitor interface {
// Visit a parse tree produced by FqlParser#unaryOperator.
VisitUnaryOperator(ctx *UnaryOperatorContext) interface{}
// Visit a parse tree produced by FqlParser#param.
VisitParam(ctx *ParamContext) interface{}
// Visit a parse tree produced by FqlParser#variable.
VisitVariable(ctx *VariableContext) interface{}
}

View File

@ -13,7 +13,7 @@ type Parser struct {
func New(query string) *Parser {
input := antlr.NewInputStream(query)
// converts tokens to upper case, so now it doesnt matter
// converts tokens to upper case, so now it doesn't matter
// in which case the tokens were entered
upper := resources.NewCaseChangingStream(input, true)
@ -22,7 +22,6 @@ func New(query string) *Parser {
p := fql.NewFqlParser(stream)
p.BuildParseTrees = true
p.AddErrorListener(antlr.NewDiagnosticErrorListener(true))
return &Parser{tree: p}
}

View File

@ -0,0 +1,22 @@
package events
import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
)
type (
// Event represents an event object that contains either an optional event data
// or error that occurred during an event
Event struct {
Data core.Value
Err error
}
// Observable represents an interface of
// complex types that can have event subscribers.
Observable interface {
Subscribe(ctx context.Context, eventName string, options *values.Object) <-chan Event
}
)

View File

@ -41,8 +41,8 @@ func TestReturnExpression(t *testing.T) {
rootScope, fn := core.NewRootScope()
scope := rootScope.Fork()
scope.SetVariable("test", values.NewString("value"))
fn()
So(scope.SetVariable("test", values.NewString("value")), ShouldBeNil)
So(fn(), ShouldBeNil)
value, err := exp.Exec(context.Background(), scope)
So(err, ShouldBeNil)

View File

@ -0,0 +1,143 @@
package expressions
import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/events"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
"time"
"github.com/pkg/errors"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/expressions/literals"
"github.com/MontFerret/ferret/pkg/runtime/values"
)
const DefaultWaitTimeout = 5000
type WaitForEventExpression struct {
src core.SourceMap
eventName core.Expression
eventSource core.Expression
options core.Expression
timeout core.Expression
}
func NewWaitForEventExpression(
src core.SourceMap,
eventName core.Expression,
eventSource core.Expression,
options core.Expression,
timeout core.Expression,
) (*WaitForEventExpression, error) {
if eventName == nil {
return nil, core.Error(core.ErrInvalidArgument, "event name")
}
if eventSource == nil {
return nil, core.Error(core.ErrMissedArgument, "event source")
}
if timeout == nil {
timeout = literals.NewIntLiteral(DefaultWaitTimeout)
}
return &WaitForEventExpression{
src: src,
eventName: eventName,
eventSource: eventSource,
options: options,
timeout: timeout,
}, nil
}
func (e *WaitForEventExpression) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) {
eventName, err := e.getEventName(ctx, scope)
if err != nil {
return values.None, core.SourceError(e.src, errors.Wrap(err, "unable to calculate event name"))
}
eventSource, err := e.eventSource.Exec(ctx, scope)
if err != nil {
return values.None, core.SourceError(e.src, err)
}
observable, ok := eventSource.(events.Observable)
if !ok {
return values.None, core.TypeError(eventSource.Type(), core.NewType("Observable"))
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
opts, err := e.getOptions(ctx, scope)
if err != nil {
return values.None, core.SourceError(e.src, err)
}
ch := observable.Subscribe(ctx, eventName, opts)
timeout, err := e.getTimeout(ctx, scope)
if err != nil {
return values.None, core.SourceError(e.src, errors.Wrap(err, "failed to calculate timeout value"))
}
timer := time.After(timeout * time.Millisecond)
select {
case evt := <-ch:
if evt.Err != nil {
return values.None, core.SourceError(e.src, evt.Err)
}
return evt.Data, nil
case <-timer:
return values.None, core.SourceError(e.src, core.ErrTimeout)
}
}
func (e *WaitForEventExpression) getEventName(ctx context.Context, scope *core.Scope) (string, error) {
eventName, err := e.eventName.Exec(ctx, scope)
if err != nil {
return "", err
}
return eventName.String(), nil
}
func (e *WaitForEventExpression) getOptions(ctx context.Context, scope *core.Scope) (*values.Object, error) {
if e.options == nil {
return nil, nil
}
options, err := e.options.Exec(ctx, scope)
if err != nil {
return nil, err
}
if err := core.ValidateType(options, types.Object); err != nil {
return nil, err
}
return options.(*values.Object), nil
}
func (e *WaitForEventExpression) getTimeout(ctx context.Context, scope *core.Scope) (time.Duration, error) {
timeoutValue, err := e.timeout.Exec(ctx, scope)
if err != nil {
return 0, err
}
timeoutInt := values.ToIntDefault(timeoutValue, DefaultWaitTimeout)
return time.Duration(timeoutInt), nil
}

View File

@ -0,0 +1,203 @@
package expressions_test
import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/events"
"github.com/MontFerret/ferret/pkg/runtime/expressions"
"github.com/MontFerret/ferret/pkg/runtime/expressions/literals"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
"github.com/MontFerret/ferret/pkg/runtime/values"
)
type MockedObservable struct {
*values.Object
subscribers map[string]chan events.Event
Args map[string][]*values.Object
}
func NewMockedObservable() *MockedObservable {
return &MockedObservable{
Object: values.NewObject(),
subscribers: map[string]chan events.Event{},
Args: map[string][]*values.Object{},
}
}
func (m *MockedObservable) Emit(eventName string, args core.Value, err error, timeout int64) {
ch := make(chan events.Event)
m.subscribers[eventName] = ch
go func() {
<-time.After(time.Millisecond * time.Duration(timeout))
ch <- events.Event{
Data: args,
Err: err,
}
}()
}
func (m *MockedObservable) Subscribe(_ context.Context, eventName string, opts *values.Object) <-chan events.Event {
calls, found := m.Args[eventName]
if !found {
calls = make([]*values.Object, 0, 10)
m.Args[eventName] = calls
}
m.Args[eventName] = append(calls, opts)
return m.subscribers[eventName]
}
func TestWaitForEventExpression(t *testing.T) {
Convey("Should create a return expression", t, func() {
variable, err := expressions.NewVariableExpression(core.NewSourceMap("test", 1, 10), "test")
So(err, ShouldBeNil)
sourceMap := core.NewSourceMap("test", 2, 10)
expression, err := expressions.NewWaitForEventExpression(
sourceMap,
literals.NewStringLiteral("test"),
variable,
nil,
nil,
)
So(err, ShouldBeNil)
So(expression, ShouldNotBeNil)
})
Convey("Should wait for an event", t, func() {
mock := NewMockedObservable()
eventName := "foobar"
variable, err := expressions.NewVariableExpression(
core.NewSourceMap("test", 1, 10),
"observable",
)
So(err, ShouldBeNil)
sourceMap := core.NewSourceMap("test", 2, 10)
expression, err := expressions.NewWaitForEventExpression(
sourceMap,
literals.NewStringLiteral(eventName),
variable,
nil,
nil,
)
So(err, ShouldBeNil)
scope, _ := core.NewRootScope()
So(scope.SetVariable("observable", mock), ShouldBeNil)
mock.Emit(eventName, values.None, nil, 100)
_, err = expression.Exec(context.Background(), scope)
So(err, ShouldBeNil)
})
Convey("Should receive opts", t, func() {
mock := NewMockedObservable()
eventName := "foobar"
variable, err := expressions.NewVariableExpression(
core.NewSourceMap("test", 1, 10),
"observable",
)
So(err, ShouldBeNil)
prop, err := literals.NewObjectPropertyAssignment(
literals.NewStringLiteral("value"),
literals.NewStringLiteral("bar"),
)
So(err, ShouldBeNil)
sourceMap := core.NewSourceMap("test", 2, 10)
expression, err := expressions.NewWaitForEventExpression(
sourceMap,
literals.NewStringLiteral(eventName),
variable,
literals.NewObjectLiteralWith(prop),
nil,
)
So(err, ShouldBeNil)
scope, _ := core.NewRootScope()
So(scope.SetVariable("observable", mock), ShouldBeNil)
mock.Emit(eventName, values.None, nil, 100)
_, err = expression.Exec(context.Background(), scope)
So(err, ShouldBeNil)
opts := mock.Args[eventName][0]
So(opts, ShouldNotBeNil)
})
Convey("Should return event arg", t, func() {
mock := NewMockedObservable()
eventName := "foobar"
variable, err := expressions.NewVariableExpression(
core.NewSourceMap("test", 1, 10),
"observable",
)
So(err, ShouldBeNil)
sourceMap := core.NewSourceMap("test", 2, 10)
expression, err := expressions.NewWaitForEventExpression(
sourceMap,
literals.NewStringLiteral(eventName),
variable,
nil,
nil,
)
So(err, ShouldBeNil)
scope, _ := core.NewRootScope()
So(scope.SetVariable("observable", mock), ShouldBeNil)
arg := values.NewString("foo")
mock.Emit(eventName, arg, nil, 100)
out, err := expression.Exec(context.Background(), scope)
So(err, ShouldBeNil)
So(out.String(), ShouldEqual, arg.String())
})
Convey("Should timeout", t, func() {
mock := NewMockedObservable()
eventName := "foobar"
variable, err := expressions.NewVariableExpression(
core.NewSourceMap("test", 1, 10),
"observable",
)
So(err, ShouldBeNil)
sourceMap := core.NewSourceMap("test", 2, 10)
expression, err := expressions.NewWaitForEventExpression(
sourceMap,
literals.NewStringLiteral(eventName),
variable,
nil,
nil,
)
So(err, ShouldBeNil)
scope, _ := core.NewRootScope()
So(scope.SetVariable("observable", mock), ShouldBeNil)
_, err = expression.Exec(context.Background(), scope)
So(err, ShouldNotBeNil)
})
}

View File

@ -343,6 +343,14 @@ func ToInt(input core.Value) Int {
}
}
func ToIntDefault(input core.Value, defaultValue Int) Int {
if result := ToInt(input); result > 0 {
return result
}
return defaultValue
}
func ToArray(ctx context.Context, input core.Value) *Array {
switch value := input.(type) {
case Boolean,
@ -393,6 +401,49 @@ func ToArray(ctx context.Context, input core.Value) *Array {
}
}
func ToObject(ctx context.Context, input core.Value) *Object {
switch value := input.(type) {
case *Object:
return value
case *Array:
obj := NewObject()
value.ForEach(func(value core.Value, idx int) bool {
obj.Set(ToString(Int(idx)), value)
return true
})
return obj
case core.Iterable:
iterator, err := value.Iterate(ctx)
if err != nil {
return NewObject()
}
obj := NewObject()
for {
val, key, err := iterator.Next(ctx)
if err != nil {
return obj
}
if val == None {
break
}
obj.Set(String(key.String()), val)
}
return obj
default:
return NewObject()
}
}
func ToStrings(input []core.Value) []String {
res := make([]String, len(input))