mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
Reimplement expr parser
This commit is contained in:
-181
@@ -1,181 +0,0 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/antonmedv/expr/file"
|
||||
)
|
||||
|
||||
func (n *NilNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *NilNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *IdentifierNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *IdentifierNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *IntegerNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *IntegerNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *FloatNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *FloatNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *BoolNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *BoolNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *StringNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *StringNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *ConstantNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *ConstantNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *UnaryNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *UnaryNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *BinaryNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *BinaryNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *MatchesNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *MatchesNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *PropertyNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *PropertyNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *IndexNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *IndexNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *SliceNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *SliceNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *MethodNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *MethodNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *FunctionNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *FunctionNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *BuiltinNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *BuiltinNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *ClosureNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *ClosureNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *PointerNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *PointerNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *ConditionalNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *ConditionalNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *ArrayNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *ArrayNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *MapNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
|
||||
func (n *MapNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *PairNode) GetLocation() file.Location {
|
||||
return n.l
|
||||
}
|
||||
|
||||
func (n *PairNode) SetLocation(l file.Location) {
|
||||
n.l = l
|
||||
}
|
||||
+47
-68
@@ -1,182 +1,161 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/antonmedv/expr/file"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
"github.com/antonmedv/expr/file"
|
||||
)
|
||||
|
||||
// Node represents items of abstract syntax tree.
|
||||
type Node interface {
|
||||
GetLocation() file.Location
|
||||
SetLocation(file.Location)
|
||||
GetType() reflect.Type
|
||||
Location() file.Location
|
||||
Type() reflect.Type
|
||||
SetType(reflect.Type)
|
||||
}
|
||||
|
||||
type Base struct {
|
||||
Loc file.Location
|
||||
nodeType reflect.Type
|
||||
}
|
||||
|
||||
func (n *Base) Location() file.Location {
|
||||
return n.Loc
|
||||
}
|
||||
|
||||
func (n *Base) Type() reflect.Type {
|
||||
return n.nodeType
|
||||
}
|
||||
|
||||
func (n *Base) SetType(t reflect.Type) {
|
||||
n.nodeType = t
|
||||
}
|
||||
|
||||
func Loc(l file.Location) Base {
|
||||
return Base{Loc: l}
|
||||
}
|
||||
|
||||
type NilNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
Base
|
||||
}
|
||||
|
||||
type IdentifierNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value string
|
||||
}
|
||||
|
||||
type IntegerNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value int
|
||||
}
|
||||
|
||||
type FloatNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value float64
|
||||
}
|
||||
|
||||
type BoolNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value bool
|
||||
}
|
||||
|
||||
type StringNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value string
|
||||
}
|
||||
|
||||
type ConstantNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type UnaryNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Operator string
|
||||
Node Node
|
||||
}
|
||||
|
||||
type BinaryNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Operator string
|
||||
Left Node
|
||||
Right Node
|
||||
}
|
||||
|
||||
type MatchesNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Regexp *regexp.Regexp
|
||||
Left Node
|
||||
Right Node
|
||||
}
|
||||
|
||||
type PropertyNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Node Node
|
||||
Property string
|
||||
}
|
||||
|
||||
type IndexNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Node Node
|
||||
Index Node
|
||||
}
|
||||
|
||||
type SliceNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Node Node
|
||||
From Node
|
||||
To Node
|
||||
}
|
||||
|
||||
type MethodNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Node Node
|
||||
Method string
|
||||
Arguments []Node
|
||||
}
|
||||
|
||||
type FunctionNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Name string
|
||||
Arguments []Node
|
||||
Fast bool
|
||||
}
|
||||
|
||||
type BuiltinNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Name string
|
||||
Arguments []Node
|
||||
}
|
||||
|
||||
type ClosureNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Node Node
|
||||
}
|
||||
|
||||
type PointerNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
Base
|
||||
}
|
||||
|
||||
type ConditionalNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Cond Node
|
||||
Exp1 Node
|
||||
Exp2 Node
|
||||
}
|
||||
|
||||
type ArrayNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Nodes []Node
|
||||
}
|
||||
|
||||
type MapNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Pairs []Node
|
||||
}
|
||||
|
||||
type PairNode struct {
|
||||
l file.Location
|
||||
t reflect.Type
|
||||
|
||||
Base
|
||||
Key Node
|
||||
Value Node
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func Print(node Node) string {
|
||||
return dump(reflect.ValueOf(node), "")
|
||||
}
|
||||
|
||||
func dump(v reflect.Value, ident string) string {
|
||||
if !v.IsValid() {
|
||||
return "nil"
|
||||
}
|
||||
t := v.Type()
|
||||
switch t.Kind() {
|
||||
case reflect.Struct:
|
||||
out := t.Name() + "{\n"
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Name == "Base" {
|
||||
continue
|
||||
}
|
||||
s := v.Field(i)
|
||||
out += fmt.Sprintf("%v%v: %v,\n", ident+"\t", f.Name, dump(s, ident+"\t"))
|
||||
}
|
||||
return out + ident + "}"
|
||||
case reflect.Slice:
|
||||
if v.Len() == 0 {
|
||||
return "[]"
|
||||
}
|
||||
out := "[\n"
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
s := v.Index(i)
|
||||
out += fmt.Sprintf("%v%v,", ident+"\t", dump(s, ident+"\t"))
|
||||
if i+1 < v.Len() {
|
||||
out += "\n"
|
||||
}
|
||||
}
|
||||
return out + "\n" + ident + "]"
|
||||
case reflect.Ptr:
|
||||
return dump(v.Elem(), ident)
|
||||
case reflect.Interface:
|
||||
return dump(reflect.ValueOf(v.Interface()), ident)
|
||||
|
||||
case reflect.String:
|
||||
return fmt.Sprintf("%q", v)
|
||||
default:
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
package ast
|
||||
|
||||
import "reflect"
|
||||
|
||||
func (n *NilNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *NilNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *IdentifierNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *IdentifierNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *IntegerNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *IntegerNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *FloatNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *FloatNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *BoolNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *BoolNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *StringNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *StringNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *ConstantNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *ConstantNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *UnaryNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *UnaryNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *BinaryNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *BinaryNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *MatchesNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *MatchesNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *PropertyNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *PropertyNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *IndexNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *IndexNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *SliceNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *SliceNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *MethodNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *MethodNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *FunctionNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *FunctionNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *BuiltinNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *BuiltinNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *ClosureNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *ClosureNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *PointerNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *PointerNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *ConditionalNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *ConditionalNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *ArrayNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *ArrayNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *MapNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
|
||||
func (n *MapNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *PairNode) GetType() reflect.Type {
|
||||
return n.t
|
||||
}
|
||||
|
||||
func (n *PairNode) SetType(t reflect.Type) {
|
||||
n.t = t
|
||||
}
|
||||
+5
-4
@@ -5,6 +5,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/antonmedv/expr"
|
||||
"github.com/antonmedv/expr/ast"
|
||||
"github.com/antonmedv/expr/checker"
|
||||
"github.com/antonmedv/expr/compiler"
|
||||
"github.com/antonmedv/expr/optimizer"
|
||||
@@ -18,7 +19,7 @@ var (
|
||||
bytecode bool
|
||||
debug bool
|
||||
run bool
|
||||
ast bool
|
||||
past bool
|
||||
dot bool
|
||||
repl bool
|
||||
opt bool
|
||||
@@ -28,7 +29,7 @@ func init() {
|
||||
flag.BoolVar(&bytecode, "bytecode", false, "disassemble bytecode")
|
||||
flag.BoolVar(&debug, "debug", false, "debug program")
|
||||
flag.BoolVar(&run, "run", false, "run program")
|
||||
flag.BoolVar(&ast, "ast", false, "print ast")
|
||||
flag.BoolVar(&past, "ast", false, "print ast")
|
||||
flag.BoolVar(&dot, "dot", false, "dot format")
|
||||
flag.BoolVar(&repl, "repl", false, "start repl")
|
||||
flag.BoolVar(&opt, "opt", true, "do optimization")
|
||||
@@ -37,7 +38,7 @@ func init() {
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if ast {
|
||||
if past {
|
||||
printAst()
|
||||
os.Exit(0)
|
||||
}
|
||||
@@ -89,7 +90,7 @@ func printAst() {
|
||||
}
|
||||
|
||||
if !dot {
|
||||
litter.Dump(tree.Node)
|
||||
ast.Print(tree.Node)
|
||||
return
|
||||
}
|
||||
dotAst(tree.Node)
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ appendix:
|
||||
Fields: make(map[Identifier]*Type),
|
||||
}
|
||||
|
||||
// Type a should be saved before starting recursion, or it will never end.
|
||||
// baseNode a should be saved before starting recursion, or it will never end.
|
||||
if !anonymous {
|
||||
c.Types[name] = a
|
||||
}
|
||||
|
||||
@@ -144,13 +144,6 @@ func Compile(input string, ops ...Option) (*vm.Program, error) {
|
||||
return program, nil
|
||||
}
|
||||
|
||||
// Parse parses input string to a program.
|
||||
//
|
||||
// Deprecated: use expr.Compile instead.
|
||||
func Parse(input string, ops ...Option) (*vm.Program, error) {
|
||||
return Compile(input, ops...)
|
||||
}
|
||||
|
||||
// Run evaluates given bytecode program.
|
||||
func Run(program *vm.Program, env interface{}) (interface{}, error) {
|
||||
return vm.Run(program, env)
|
||||
|
||||
-253
@@ -1,253 +0,0 @@
|
||||
grammar Expr;
|
||||
|
||||
start
|
||||
: e=expr EOF
|
||||
;
|
||||
|
||||
expr
|
||||
: '.' name=Identifier # ClosureMemberDot
|
||||
| expr '[' index=expr ']' # MemberIndex
|
||||
| expr '[' a=expr? ':' b=expr? ']' # Slice
|
||||
| expr '.' name=Identifier # MemberDot
|
||||
| builtins # BuiltinsList
|
||||
| expr '(' args=arguments? ')' # Call
|
||||
| op=( '+' | '-' | '!' | 'not' ) expr # Unary
|
||||
| expr op='..' expr # Binary
|
||||
| expr op=( '*' | '**' | '/' | '%' ) expr # Binary
|
||||
| expr op=( '+' | '-' ) expr # Binary
|
||||
| expr op=( '<' | '>' | '<=' | '>=' ) expr # Binary
|
||||
| expr op='startsWith' expr # Binary
|
||||
| expr op='endsWith' expr # Binary
|
||||
| expr op='contains' expr # Binary
|
||||
| expr op='matches' pattern=expr # Matches
|
||||
| expr op=( 'in' | 'not in' ) expr # Binary
|
||||
| expr op=( '==' | '!=' ) expr # Binary
|
||||
| expr op=And expr # Binary
|
||||
| expr op=Or expr # Binary
|
||||
| expr '?' e1=expr ':' e2=expr # Ternary
|
||||
| Nil # Nil
|
||||
| BooleanLiteral # Boolean
|
||||
| StringLiteral # String
|
||||
| IntegerLiteral # Integer
|
||||
| HexIntegerLiteral # Integer
|
||||
| FloatLiteral # Float
|
||||
| Identifier # Identifier
|
||||
| Pointer # Pointer
|
||||
| arrayLiteral # Array
|
||||
| mapLiteral # Map
|
||||
| '(' expr ')' # Parenthesized
|
||||
;
|
||||
|
||||
builtins
|
||||
: name='len' '(' e=expr ')' # BuiltinLen
|
||||
| name='all' '(' e=expr ',' c=closure ')' # Builtin
|
||||
| name='none' '(' e=expr ',' c=closure ')' # Builtin
|
||||
| name='any' '(' e=expr ',' c=closure ')' # Builtin
|
||||
| name='one' '(' e=expr ',' c=closure ')' # Builtin
|
||||
| name='filter' '(' e=expr ',' c=closure ')' # Builtin
|
||||
| name='map' '(' e=expr ',' c=closure ')' # Builtin
|
||||
;
|
||||
|
||||
closure
|
||||
: '{' body=expr '}'
|
||||
;
|
||||
|
||||
arguments
|
||||
: list+=expr ( ',' list+=expr )*
|
||||
;
|
||||
|
||||
arrayLiteral
|
||||
: '[' ']'
|
||||
| '[' list+=expr ( ',' list+=expr )* ','? ']'
|
||||
;
|
||||
|
||||
mapLiteral
|
||||
: '{' '}'
|
||||
| '{' e=propertyNameAndValueList ','? '}'
|
||||
;
|
||||
|
||||
propertyNameAndValueList
|
||||
: list+=propertyAssignment ( ',' list+=propertyAssignment )*
|
||||
;
|
||||
|
||||
propertyAssignment
|
||||
: name=propertyName ':' value=expr
|
||||
;
|
||||
|
||||
propertyName
|
||||
: Identifier
|
||||
| StringLiteral
|
||||
;
|
||||
|
||||
/*****************************/
|
||||
/* */
|
||||
/* LEXER */
|
||||
/* */
|
||||
/*****************************/
|
||||
|
||||
OpenBracket : '[';
|
||||
CloseBracket : ']';
|
||||
OpenParen : '(';
|
||||
CloseParen : ')';
|
||||
OpenBrace : '{';
|
||||
CloseBrace : '}';
|
||||
SemiColon : ';';
|
||||
Comma : ',';
|
||||
Assign : '=';
|
||||
QuestionMark : '?';
|
||||
Colon : ':';
|
||||
Dot : '.';
|
||||
Plus : '+';
|
||||
Minus : '-';
|
||||
Negate : '!';
|
||||
Not : 'not';
|
||||
Nil : 'nil';
|
||||
Multiply : '*';
|
||||
Exponent : '**';
|
||||
Divide : '/';
|
||||
Modulus : '%';
|
||||
RightShiftArithmetic : '>>';
|
||||
LeftShiftArithmetic : '<<';
|
||||
LessThan : '<';
|
||||
MoreThan : '>';
|
||||
LessThanEquals : '<=';
|
||||
GreaterThanEquals : '>=';
|
||||
Equals : '==';
|
||||
NotEquals : '!=';
|
||||
Pointer : '#';
|
||||
And : ( '&&' | 'and' );
|
||||
Or : ( '||' | 'or' );
|
||||
Builtins : ( 'all' | 'none' | 'any' | 'one' | 'filter' | 'map' );
|
||||
Ops : ( 'startsWith' | 'endsWith' | 'contains' | 'matches' | 'in' | 'not in' );
|
||||
|
||||
BooleanLiteral
|
||||
: 'true'
|
||||
| 'false'
|
||||
;
|
||||
|
||||
IntegerLiteral
|
||||
: '0'
|
||||
| [1-9] [0-9_]*
|
||||
;
|
||||
|
||||
FloatLiteral
|
||||
: DecimalLiteral '.' Digit+
|
||||
| '.' Digit+
|
||||
;
|
||||
|
||||
HexIntegerLiteral
|
||||
: '0' [xX] HexDigit+
|
||||
;
|
||||
|
||||
Identifier
|
||||
: IdentifierStart IdentifierPart*
|
||||
;
|
||||
|
||||
StringLiteral
|
||||
: '"' DoubleStringCharacter* '"'
|
||||
| '\'' SingleStringCharacter* '\''
|
||||
;
|
||||
|
||||
WhiteSpaces
|
||||
: [\t\u000B\u000C\u0020\u00A0]+ -> channel(HIDDEN)
|
||||
;
|
||||
|
||||
MultiLineComment
|
||||
: '/*' .*? '*/' -> channel(HIDDEN)
|
||||
;
|
||||
|
||||
SingleLineComment
|
||||
: '//' ~[\r\n\u2028\u2029]* -> channel(HIDDEN)
|
||||
;
|
||||
|
||||
LineTerminator
|
||||
: [\r\n\u2028\u2029] -> channel(HIDDEN)
|
||||
;
|
||||
|
||||
UnexpectedCharacter
|
||||
: .
|
||||
;
|
||||
|
||||
fragment DoubleStringCharacter
|
||||
: ~["\\\r\n]
|
||||
| '\\' EscapeSequence
|
||||
| LineContinuation
|
||||
;
|
||||
|
||||
fragment SingleStringCharacter
|
||||
: ~['\\\r\n]
|
||||
| '\\' EscapeSequence
|
||||
| LineContinuation
|
||||
;
|
||||
|
||||
fragment EscapeSequence
|
||||
: CharacterEscapeSequence
|
||||
| '0' // no digit ahead! TODO
|
||||
| HexEscapeSequence
|
||||
| UnicodeEscapeSequence
|
||||
;
|
||||
|
||||
fragment CharacterEscapeSequence
|
||||
: SingleEscapeCharacter
|
||||
| NonEscapeCharacter
|
||||
;
|
||||
|
||||
fragment HexEscapeSequence
|
||||
: 'x' HexDigit HexDigit
|
||||
;
|
||||
|
||||
fragment UnicodeEscapeSequence
|
||||
: 'u' HexDigit HexDigit HexDigit HexDigit
|
||||
;
|
||||
|
||||
fragment SingleEscapeCharacter
|
||||
: ['"\\bfnrtv]
|
||||
;
|
||||
|
||||
fragment NonEscapeCharacter
|
||||
: ~['"\\bfnrtv0-9xu\r\n]
|
||||
;
|
||||
|
||||
fragment EscapeCharacter
|
||||
: SingleEscapeCharacter
|
||||
| Digit
|
||||
| [xu]
|
||||
;
|
||||
|
||||
fragment LineContinuation
|
||||
: '\\' LineTerminatorSequence
|
||||
;
|
||||
|
||||
fragment LineTerminatorSequence
|
||||
: '\r\n'
|
||||
| LineTerminator
|
||||
;
|
||||
|
||||
fragment IdentifierStart
|
||||
: Letter
|
||||
| [$_]
|
||||
;
|
||||
|
||||
fragment IdentifierPart
|
||||
: Letter
|
||||
| Digit
|
||||
| [_]
|
||||
;
|
||||
|
||||
fragment Letter
|
||||
: 'A'..'Z'
|
||||
| 'a'..'z'
|
||||
;
|
||||
|
||||
fragment Digit
|
||||
: '0'..'9'
|
||||
;
|
||||
|
||||
fragment DecimalLiteral
|
||||
: '0'
|
||||
| [1-9] Digit*
|
||||
;
|
||||
|
||||
fragment HexDigit
|
||||
: [0-9a-fA-F]
|
||||
;
|
||||
File diff suppressed because one or more lines are too long
@@ -1,103 +0,0 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
OpenBracket=15
|
||||
CloseBracket=16
|
||||
OpenParen=17
|
||||
CloseParen=18
|
||||
OpenBrace=19
|
||||
CloseBrace=20
|
||||
SemiColon=21
|
||||
Comma=22
|
||||
Assign=23
|
||||
QuestionMark=24
|
||||
Colon=25
|
||||
Dot=26
|
||||
Plus=27
|
||||
Minus=28
|
||||
Negate=29
|
||||
Not=30
|
||||
Nil=31
|
||||
Multiply=32
|
||||
Exponent=33
|
||||
Divide=34
|
||||
Modulus=35
|
||||
RightShiftArithmetic=36
|
||||
LeftShiftArithmetic=37
|
||||
LessThan=38
|
||||
MoreThan=39
|
||||
LessThanEquals=40
|
||||
GreaterThanEquals=41
|
||||
Equals=42
|
||||
NotEquals=43
|
||||
Pointer=44
|
||||
And=45
|
||||
Or=46
|
||||
Builtins=47
|
||||
Ops=48
|
||||
BooleanLiteral=49
|
||||
IntegerLiteral=50
|
||||
FloatLiteral=51
|
||||
HexIntegerLiteral=52
|
||||
Identifier=53
|
||||
StringLiteral=54
|
||||
WhiteSpaces=55
|
||||
MultiLineComment=56
|
||||
SingleLineComment=57
|
||||
LineTerminator=58
|
||||
UnexpectedCharacter=59
|
||||
'..'=1
|
||||
'startsWith'=2
|
||||
'endsWith'=3
|
||||
'contains'=4
|
||||
'matches'=5
|
||||
'in'=6
|
||||
'not in'=7
|
||||
'len'=8
|
||||
'all'=9
|
||||
'none'=10
|
||||
'any'=11
|
||||
'one'=12
|
||||
'filter'=13
|
||||
'map'=14
|
||||
'['=15
|
||||
']'=16
|
||||
'('=17
|
||||
')'=18
|
||||
'{'=19
|
||||
'}'=20
|
||||
';'=21
|
||||
','=22
|
||||
'='=23
|
||||
'?'=24
|
||||
':'=25
|
||||
'.'=26
|
||||
'+'=27
|
||||
'-'=28
|
||||
'!'=29
|
||||
'not'=30
|
||||
'nil'=31
|
||||
'*'=32
|
||||
'**'=33
|
||||
'/'=34
|
||||
'%'=35
|
||||
'>>'=36
|
||||
'<<'=37
|
||||
'<'=38
|
||||
'>'=39
|
||||
'<='=40
|
||||
'>='=41
|
||||
'=='=42
|
||||
'!='=43
|
||||
'#'=44
|
||||
File diff suppressed because one or more lines are too long
@@ -1,103 +0,0 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
OpenBracket=15
|
||||
CloseBracket=16
|
||||
OpenParen=17
|
||||
CloseParen=18
|
||||
OpenBrace=19
|
||||
CloseBrace=20
|
||||
SemiColon=21
|
||||
Comma=22
|
||||
Assign=23
|
||||
QuestionMark=24
|
||||
Colon=25
|
||||
Dot=26
|
||||
Plus=27
|
||||
Minus=28
|
||||
Negate=29
|
||||
Not=30
|
||||
Nil=31
|
||||
Multiply=32
|
||||
Exponent=33
|
||||
Divide=34
|
||||
Modulus=35
|
||||
RightShiftArithmetic=36
|
||||
LeftShiftArithmetic=37
|
||||
LessThan=38
|
||||
MoreThan=39
|
||||
LessThanEquals=40
|
||||
GreaterThanEquals=41
|
||||
Equals=42
|
||||
NotEquals=43
|
||||
Pointer=44
|
||||
And=45
|
||||
Or=46
|
||||
Builtins=47
|
||||
Ops=48
|
||||
BooleanLiteral=49
|
||||
IntegerLiteral=50
|
||||
FloatLiteral=51
|
||||
HexIntegerLiteral=52
|
||||
Identifier=53
|
||||
StringLiteral=54
|
||||
WhiteSpaces=55
|
||||
MultiLineComment=56
|
||||
SingleLineComment=57
|
||||
LineTerminator=58
|
||||
UnexpectedCharacter=59
|
||||
'..'=1
|
||||
'startsWith'=2
|
||||
'endsWith'=3
|
||||
'contains'=4
|
||||
'matches'=5
|
||||
'in'=6
|
||||
'not in'=7
|
||||
'len'=8
|
||||
'all'=9
|
||||
'none'=10
|
||||
'any'=11
|
||||
'one'=12
|
||||
'filter'=13
|
||||
'map'=14
|
||||
'['=15
|
||||
']'=16
|
||||
'('=17
|
||||
')'=18
|
||||
'{'=19
|
||||
'}'=20
|
||||
';'=21
|
||||
','=22
|
||||
'='=23
|
||||
'?'=24
|
||||
':'=25
|
||||
'.'=26
|
||||
'+'=27
|
||||
'-'=28
|
||||
'!'=29
|
||||
'not'=30
|
||||
'nil'=31
|
||||
'*'=32
|
||||
'**'=33
|
||||
'/'=34
|
||||
'%'=35
|
||||
'>>'=36
|
||||
'<<'=37
|
||||
'<'=38
|
||||
'>'=39
|
||||
'<='=40
|
||||
'>='=41
|
||||
'=='=42
|
||||
'!='=43
|
||||
'#'=44
|
||||
@@ -1,201 +0,0 @@
|
||||
// Code generated from Expr.g4 by ANTLR 4.7.2. DO NOT EDIT.
|
||||
|
||||
package gen // Expr
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
// BaseExprListener is a complete listener for a parse tree produced by ExprParser.
|
||||
type BaseExprListener struct{}
|
||||
|
||||
var _ ExprListener = &BaseExprListener{}
|
||||
|
||||
// VisitTerminal is called when a terminal node is visited.
|
||||
func (s *BaseExprListener) VisitTerminal(node antlr.TerminalNode) {}
|
||||
|
||||
// VisitErrorNode is called when an error node is visited.
|
||||
func (s *BaseExprListener) VisitErrorNode(node antlr.ErrorNode) {}
|
||||
|
||||
// EnterEveryRule is called when any rule is entered.
|
||||
func (s *BaseExprListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
|
||||
|
||||
// ExitEveryRule is called when any rule is exited.
|
||||
func (s *BaseExprListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
|
||||
|
||||
// EnterStart is called when production start is entered.
|
||||
func (s *BaseExprListener) EnterStart(ctx *StartContext) {}
|
||||
|
||||
// ExitStart is called when production start is exited.
|
||||
func (s *BaseExprListener) ExitStart(ctx *StartContext) {}
|
||||
|
||||
// EnterCall is called when production Call is entered.
|
||||
func (s *BaseExprListener) EnterCall(ctx *CallContext) {}
|
||||
|
||||
// ExitCall is called when production Call is exited.
|
||||
func (s *BaseExprListener) ExitCall(ctx *CallContext) {}
|
||||
|
||||
// EnterMatches is called when production Matches is entered.
|
||||
func (s *BaseExprListener) EnterMatches(ctx *MatchesContext) {}
|
||||
|
||||
// ExitMatches is called when production Matches is exited.
|
||||
func (s *BaseExprListener) ExitMatches(ctx *MatchesContext) {}
|
||||
|
||||
// EnterTernary is called when production Ternary is entered.
|
||||
func (s *BaseExprListener) EnterTernary(ctx *TernaryContext) {}
|
||||
|
||||
// ExitTernary is called when production Ternary is exited.
|
||||
func (s *BaseExprListener) ExitTernary(ctx *TernaryContext) {}
|
||||
|
||||
// EnterPointer is called when production Pointer is entered.
|
||||
func (s *BaseExprListener) EnterPointer(ctx *PointerContext) {}
|
||||
|
||||
// ExitPointer is called when production Pointer is exited.
|
||||
func (s *BaseExprListener) ExitPointer(ctx *PointerContext) {}
|
||||
|
||||
// EnterString is called when production String is entered.
|
||||
func (s *BaseExprListener) EnterString(ctx *StringContext) {}
|
||||
|
||||
// ExitString is called when production String is exited.
|
||||
func (s *BaseExprListener) ExitString(ctx *StringContext) {}
|
||||
|
||||
// EnterClosureMemberDot is called when production ClosureMemberDot is entered.
|
||||
func (s *BaseExprListener) EnterClosureMemberDot(ctx *ClosureMemberDotContext) {}
|
||||
|
||||
// ExitClosureMemberDot is called when production ClosureMemberDot is exited.
|
||||
func (s *BaseExprListener) ExitClosureMemberDot(ctx *ClosureMemberDotContext) {}
|
||||
|
||||
// EnterUnary is called when production Unary is entered.
|
||||
func (s *BaseExprListener) EnterUnary(ctx *UnaryContext) {}
|
||||
|
||||
// ExitUnary is called when production Unary is exited.
|
||||
func (s *BaseExprListener) ExitUnary(ctx *UnaryContext) {}
|
||||
|
||||
// EnterNil is called when production Nil is entered.
|
||||
func (s *BaseExprListener) EnterNil(ctx *NilContext) {}
|
||||
|
||||
// ExitNil is called when production Nil is exited.
|
||||
func (s *BaseExprListener) ExitNil(ctx *NilContext) {}
|
||||
|
||||
// EnterInteger is called when production Integer is entered.
|
||||
func (s *BaseExprListener) EnterInteger(ctx *IntegerContext) {}
|
||||
|
||||
// ExitInteger is called when production Integer is exited.
|
||||
func (s *BaseExprListener) ExitInteger(ctx *IntegerContext) {}
|
||||
|
||||
// EnterArray is called when production Array is entered.
|
||||
func (s *BaseExprListener) EnterArray(ctx *ArrayContext) {}
|
||||
|
||||
// ExitArray is called when production Array is exited.
|
||||
func (s *BaseExprListener) ExitArray(ctx *ArrayContext) {}
|
||||
|
||||
// EnterFloat is called when production Float is entered.
|
||||
func (s *BaseExprListener) EnterFloat(ctx *FloatContext) {}
|
||||
|
||||
// ExitFloat is called when production Float is exited.
|
||||
func (s *BaseExprListener) ExitFloat(ctx *FloatContext) {}
|
||||
|
||||
// EnterIdentifier is called when production Identifier is entered.
|
||||
func (s *BaseExprListener) EnterIdentifier(ctx *IdentifierContext) {}
|
||||
|
||||
// ExitIdentifier is called when production Identifier is exited.
|
||||
func (s *BaseExprListener) ExitIdentifier(ctx *IdentifierContext) {}
|
||||
|
||||
// EnterParenthesized is called when production Parenthesized is entered.
|
||||
func (s *BaseExprListener) EnterParenthesized(ctx *ParenthesizedContext) {}
|
||||
|
||||
// ExitParenthesized is called when production Parenthesized is exited.
|
||||
func (s *BaseExprListener) ExitParenthesized(ctx *ParenthesizedContext) {}
|
||||
|
||||
// EnterSlice is called when production Slice is entered.
|
||||
func (s *BaseExprListener) EnterSlice(ctx *SliceContext) {}
|
||||
|
||||
// ExitSlice is called when production Slice is exited.
|
||||
func (s *BaseExprListener) ExitSlice(ctx *SliceContext) {}
|
||||
|
||||
// EnterMemberIndex is called when production MemberIndex is entered.
|
||||
func (s *BaseExprListener) EnterMemberIndex(ctx *MemberIndexContext) {}
|
||||
|
||||
// ExitMemberIndex is called when production MemberIndex is exited.
|
||||
func (s *BaseExprListener) ExitMemberIndex(ctx *MemberIndexContext) {}
|
||||
|
||||
// EnterBuiltinsList is called when production BuiltinsList is entered.
|
||||
func (s *BaseExprListener) EnterBuiltinsList(ctx *BuiltinsListContext) {}
|
||||
|
||||
// ExitBuiltinsList is called when production BuiltinsList is exited.
|
||||
func (s *BaseExprListener) ExitBuiltinsList(ctx *BuiltinsListContext) {}
|
||||
|
||||
// EnterBinary is called when production Binary is entered.
|
||||
func (s *BaseExprListener) EnterBinary(ctx *BinaryContext) {}
|
||||
|
||||
// ExitBinary is called when production Binary is exited.
|
||||
func (s *BaseExprListener) ExitBinary(ctx *BinaryContext) {}
|
||||
|
||||
// EnterBoolean is called when production Boolean is entered.
|
||||
func (s *BaseExprListener) EnterBoolean(ctx *BooleanContext) {}
|
||||
|
||||
// ExitBoolean is called when production Boolean is exited.
|
||||
func (s *BaseExprListener) ExitBoolean(ctx *BooleanContext) {}
|
||||
|
||||
// EnterMap is called when production Map is entered.
|
||||
func (s *BaseExprListener) EnterMap(ctx *MapContext) {}
|
||||
|
||||
// ExitMap is called when production Map is exited.
|
||||
func (s *BaseExprListener) ExitMap(ctx *MapContext) {}
|
||||
|
||||
// EnterMemberDot is called when production MemberDot is entered.
|
||||
func (s *BaseExprListener) EnterMemberDot(ctx *MemberDotContext) {}
|
||||
|
||||
// ExitMemberDot is called when production MemberDot is exited.
|
||||
func (s *BaseExprListener) ExitMemberDot(ctx *MemberDotContext) {}
|
||||
|
||||
// EnterBuiltinLen is called when production BuiltinLen is entered.
|
||||
func (s *BaseExprListener) EnterBuiltinLen(ctx *BuiltinLenContext) {}
|
||||
|
||||
// ExitBuiltinLen is called when production BuiltinLen is exited.
|
||||
func (s *BaseExprListener) ExitBuiltinLen(ctx *BuiltinLenContext) {}
|
||||
|
||||
// EnterBuiltin is called when production Builtin is entered.
|
||||
func (s *BaseExprListener) EnterBuiltin(ctx *BuiltinContext) {}
|
||||
|
||||
// ExitBuiltin is called when production Builtin is exited.
|
||||
func (s *BaseExprListener) ExitBuiltin(ctx *BuiltinContext) {}
|
||||
|
||||
// EnterClosure is called when production closure is entered.
|
||||
func (s *BaseExprListener) EnterClosure(ctx *ClosureContext) {}
|
||||
|
||||
// ExitClosure is called when production closure is exited.
|
||||
func (s *BaseExprListener) ExitClosure(ctx *ClosureContext) {}
|
||||
|
||||
// EnterArguments is called when production arguments is entered.
|
||||
func (s *BaseExprListener) EnterArguments(ctx *ArgumentsContext) {}
|
||||
|
||||
// ExitArguments is called when production arguments is exited.
|
||||
func (s *BaseExprListener) ExitArguments(ctx *ArgumentsContext) {}
|
||||
|
||||
// EnterArrayLiteral is called when production arrayLiteral is entered.
|
||||
func (s *BaseExprListener) EnterArrayLiteral(ctx *ArrayLiteralContext) {}
|
||||
|
||||
// ExitArrayLiteral is called when production arrayLiteral is exited.
|
||||
func (s *BaseExprListener) ExitArrayLiteral(ctx *ArrayLiteralContext) {}
|
||||
|
||||
// EnterMapLiteral is called when production mapLiteral is entered.
|
||||
func (s *BaseExprListener) EnterMapLiteral(ctx *MapLiteralContext) {}
|
||||
|
||||
// ExitMapLiteral is called when production mapLiteral is exited.
|
||||
func (s *BaseExprListener) ExitMapLiteral(ctx *MapLiteralContext) {}
|
||||
|
||||
// EnterPropertyNameAndValueList is called when production propertyNameAndValueList is entered.
|
||||
func (s *BaseExprListener) EnterPropertyNameAndValueList(ctx *PropertyNameAndValueListContext) {}
|
||||
|
||||
// ExitPropertyNameAndValueList is called when production propertyNameAndValueList is exited.
|
||||
func (s *BaseExprListener) ExitPropertyNameAndValueList(ctx *PropertyNameAndValueListContext) {}
|
||||
|
||||
// EnterPropertyAssignment is called when production propertyAssignment is entered.
|
||||
func (s *BaseExprListener) EnterPropertyAssignment(ctx *PropertyAssignmentContext) {}
|
||||
|
||||
// ExitPropertyAssignment is called when production propertyAssignment is exited.
|
||||
func (s *BaseExprListener) ExitPropertyAssignment(ctx *PropertyAssignmentContext) {}
|
||||
|
||||
// EnterPropertyName is called when production propertyName is entered.
|
||||
func (s *BaseExprListener) EnterPropertyName(ctx *PropertyNameContext) {}
|
||||
|
||||
// ExitPropertyName is called when production propertyName is exited.
|
||||
func (s *BaseExprListener) ExitPropertyName(ctx *PropertyNameContext) {}
|
||||
@@ -1,128 +0,0 @@
|
||||
// Code generated from Expr.g4 by ANTLR 4.7.2. DO NOT EDIT.
|
||||
|
||||
package gen // Expr
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
type BaseExprVisitor struct {
|
||||
*antlr.BaseParseTreeVisitor
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitStart(ctx *StartContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitCall(ctx *CallContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitMatches(ctx *MatchesContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitTernary(ctx *TernaryContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitPointer(ctx *PointerContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitString(ctx *StringContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitClosureMemberDot(ctx *ClosureMemberDotContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitUnary(ctx *UnaryContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitNil(ctx *NilContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitInteger(ctx *IntegerContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitArray(ctx *ArrayContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitFloat(ctx *FloatContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitParenthesized(ctx *ParenthesizedContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitSlice(ctx *SliceContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitMemberIndex(ctx *MemberIndexContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitBuiltinsList(ctx *BuiltinsListContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitBinary(ctx *BinaryContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitBoolean(ctx *BooleanContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitMap(ctx *MapContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitMemberDot(ctx *MemberDotContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitBuiltinLen(ctx *BuiltinLenContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitBuiltin(ctx *BuiltinContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitClosure(ctx *ClosureContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitArguments(ctx *ArgumentsContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitArrayLiteral(ctx *ArrayLiteralContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitMapLiteral(ctx *MapLiteralContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitPropertyNameAndValueList(ctx *PropertyNameAndValueListContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitPropertyAssignment(ctx *PropertyAssignmentContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BaseExprVisitor) VisitPropertyName(ctx *PropertyNameContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
@@ -1,419 +0,0 @@
|
||||
// Code generated from Expr.g4 by ANTLR 4.7.2. DO NOT EDIT.
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
|
||||
// Suppress unused import error
|
||||
var _ = fmt.Printf
|
||||
var _ = unicode.IsLetter
|
||||
|
||||
var serializedLexerAtn = []uint16{
|
||||
3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 61, 568,
|
||||
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,
|
||||
18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23,
|
||||
9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9,
|
||||
28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33,
|
||||
4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4,
|
||||
39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44,
|
||||
9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9,
|
||||
49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54,
|
||||
4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4,
|
||||
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, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
|
||||
4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3,
|
||||
5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3,
|
||||
8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3,
|
||||
10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12,
|
||||
3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3,
|
||||
14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18,
|
||||
3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 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, 28, 3, 28,
|
||||
3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3,
|
||||
32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36,
|
||||
3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3,
|
||||
41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44,
|
||||
3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 5, 46, 314, 10,
|
||||
46, 3, 47, 3, 47, 3, 47, 3, 47, 5, 47, 320, 10, 47, 3, 48, 3, 48, 3, 48,
|
||||
3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3,
|
||||
48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 344,
|
||||
10, 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, 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, 3, 49, 3, 49, 3, 49, 3, 49, 3,
|
||||
49, 5, 49, 387, 10, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50,
|
||||
3, 50, 3, 50, 5, 50, 398, 10, 50, 3, 51, 3, 51, 3, 51, 7, 51, 403, 10,
|
||||
51, 12, 51, 14, 51, 406, 11, 51, 5, 51, 408, 10, 51, 3, 52, 3, 52, 3, 52,
|
||||
6, 52, 413, 10, 52, 13, 52, 14, 52, 414, 3, 52, 3, 52, 6, 52, 419, 10,
|
||||
52, 13, 52, 14, 52, 420, 5, 52, 423, 10, 52, 3, 53, 3, 53, 3, 53, 6, 53,
|
||||
428, 10, 53, 13, 53, 14, 53, 429, 3, 54, 3, 54, 7, 54, 434, 10, 54, 12,
|
||||
54, 14, 54, 437, 11, 54, 3, 55, 3, 55, 7, 55, 441, 10, 55, 12, 55, 14,
|
||||
55, 444, 11, 55, 3, 55, 3, 55, 3, 55, 7, 55, 449, 10, 55, 12, 55, 14, 55,
|
||||
452, 11, 55, 3, 55, 5, 55, 455, 10, 55, 3, 56, 6, 56, 458, 10, 56, 13,
|
||||
56, 14, 56, 459, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 7, 57, 468,
|
||||
10, 57, 12, 57, 14, 57, 471, 11, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57,
|
||||
3, 58, 3, 58, 3, 58, 3, 58, 7, 58, 482, 10, 58, 12, 58, 14, 58, 485, 11,
|
||||
58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61,
|
||||
3, 61, 3, 61, 5, 61, 499, 10, 61, 3, 62, 3, 62, 3, 62, 3, 62, 5, 62, 505,
|
||||
10, 62, 3, 63, 3, 63, 3, 63, 3, 63, 5, 63, 511, 10, 63, 3, 64, 3, 64, 5,
|
||||
64, 515, 10, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66,
|
||||
3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 5, 69, 534,
|
||||
10, 69, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 5, 71, 542, 10, 71, 3,
|
||||
72, 3, 72, 5, 72, 546, 10, 72, 3, 73, 3, 73, 3, 73, 5, 73, 551, 10, 73,
|
||||
3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 7, 76, 560, 10, 76, 12,
|
||||
76, 14, 76, 563, 11, 76, 5, 76, 565, 10, 76, 3, 77, 3, 77, 3, 469, 2, 78,
|
||||
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, 2, 123, 2, 125, 2, 127, 2, 129,
|
||||
2, 131, 2, 133, 2, 135, 2, 137, 2, 139, 2, 141, 2, 143, 2, 145, 2, 147,
|
||||
2, 149, 2, 151, 2, 153, 2, 3, 2, 16, 3, 2, 51, 59, 4, 2, 50, 59, 97, 97,
|
||||
4, 2, 90, 90, 122, 122, 6, 2, 11, 11, 13, 14, 34, 34, 162, 162, 5, 2, 12,
|
||||
12, 15, 15, 8234, 8235, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 6, 2, 12,
|
||||
12, 15, 15, 41, 41, 94, 94, 11, 2, 36, 36, 41, 41, 94, 94, 100, 100, 104,
|
||||
104, 112, 112, 116, 116, 118, 118, 120, 120, 14, 2, 12, 12, 15, 15, 36,
|
||||
36, 41, 41, 50, 59, 94, 94, 100, 100, 104, 104, 112, 112, 116, 116, 118,
|
||||
120, 122, 122, 4, 2, 119, 119, 122, 122, 4, 2, 38, 38, 97, 97, 3, 2, 97,
|
||||
97, 4, 2, 67, 92, 99, 124, 5, 2, 50, 59, 67, 72, 99, 104, 2, 592, 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, 3, 155, 3, 2, 2, 2, 5, 158, 3, 2, 2, 2, 7,
|
||||
169, 3, 2, 2, 2, 9, 178, 3, 2, 2, 2, 11, 187, 3, 2, 2, 2, 13, 195, 3, 2,
|
||||
2, 2, 15, 198, 3, 2, 2, 2, 17, 205, 3, 2, 2, 2, 19, 209, 3, 2, 2, 2, 21,
|
||||
213, 3, 2, 2, 2, 23, 218, 3, 2, 2, 2, 25, 222, 3, 2, 2, 2, 27, 226, 3,
|
||||
2, 2, 2, 29, 233, 3, 2, 2, 2, 31, 237, 3, 2, 2, 2, 33, 239, 3, 2, 2, 2,
|
||||
35, 241, 3, 2, 2, 2, 37, 243, 3, 2, 2, 2, 39, 245, 3, 2, 2, 2, 41, 247,
|
||||
3, 2, 2, 2, 43, 249, 3, 2, 2, 2, 45, 251, 3, 2, 2, 2, 47, 253, 3, 2, 2,
|
||||
2, 49, 255, 3, 2, 2, 2, 51, 257, 3, 2, 2, 2, 53, 259, 3, 2, 2, 2, 55, 261,
|
||||
3, 2, 2, 2, 57, 263, 3, 2, 2, 2, 59, 265, 3, 2, 2, 2, 61, 267, 3, 2, 2,
|
||||
2, 63, 271, 3, 2, 2, 2, 65, 275, 3, 2, 2, 2, 67, 277, 3, 2, 2, 2, 69, 280,
|
||||
3, 2, 2, 2, 71, 282, 3, 2, 2, 2, 73, 284, 3, 2, 2, 2, 75, 287, 3, 2, 2,
|
||||
2, 77, 290, 3, 2, 2, 2, 79, 292, 3, 2, 2, 2, 81, 294, 3, 2, 2, 2, 83, 297,
|
||||
3, 2, 2, 2, 85, 300, 3, 2, 2, 2, 87, 303, 3, 2, 2, 2, 89, 306, 3, 2, 2,
|
||||
2, 91, 313, 3, 2, 2, 2, 93, 319, 3, 2, 2, 2, 95, 343, 3, 2, 2, 2, 97, 386,
|
||||
3, 2, 2, 2, 99, 397, 3, 2, 2, 2, 101, 407, 3, 2, 2, 2, 103, 422, 3, 2,
|
||||
2, 2, 105, 424, 3, 2, 2, 2, 107, 431, 3, 2, 2, 2, 109, 454, 3, 2, 2, 2,
|
||||
111, 457, 3, 2, 2, 2, 113, 463, 3, 2, 2, 2, 115, 477, 3, 2, 2, 2, 117,
|
||||
488, 3, 2, 2, 2, 119, 492, 3, 2, 2, 2, 121, 498, 3, 2, 2, 2, 123, 504,
|
||||
3, 2, 2, 2, 125, 510, 3, 2, 2, 2, 127, 514, 3, 2, 2, 2, 129, 516, 3, 2,
|
||||
2, 2, 131, 520, 3, 2, 2, 2, 133, 526, 3, 2, 2, 2, 135, 528, 3, 2, 2, 2,
|
||||
137, 533, 3, 2, 2, 2, 139, 535, 3, 2, 2, 2, 141, 541, 3, 2, 2, 2, 143,
|
||||
545, 3, 2, 2, 2, 145, 550, 3, 2, 2, 2, 147, 552, 3, 2, 2, 2, 149, 554,
|
||||
3, 2, 2, 2, 151, 564, 3, 2, 2, 2, 153, 566, 3, 2, 2, 2, 155, 156, 7, 48,
|
||||
2, 2, 156, 157, 7, 48, 2, 2, 157, 4, 3, 2, 2, 2, 158, 159, 7, 117, 2, 2,
|
||||
159, 160, 7, 118, 2, 2, 160, 161, 7, 99, 2, 2, 161, 162, 7, 116, 2, 2,
|
||||
162, 163, 7, 118, 2, 2, 163, 164, 7, 117, 2, 2, 164, 165, 7, 89, 2, 2,
|
||||
165, 166, 7, 107, 2, 2, 166, 167, 7, 118, 2, 2, 167, 168, 7, 106, 2, 2,
|
||||
168, 6, 3, 2, 2, 2, 169, 170, 7, 103, 2, 2, 170, 171, 7, 112, 2, 2, 171,
|
||||
172, 7, 102, 2, 2, 172, 173, 7, 117, 2, 2, 173, 174, 7, 89, 2, 2, 174,
|
||||
175, 7, 107, 2, 2, 175, 176, 7, 118, 2, 2, 176, 177, 7, 106, 2, 2, 177,
|
||||
8, 3, 2, 2, 2, 178, 179, 7, 101, 2, 2, 179, 180, 7, 113, 2, 2, 180, 181,
|
||||
7, 112, 2, 2, 181, 182, 7, 118, 2, 2, 182, 183, 7, 99, 2, 2, 183, 184,
|
||||
7, 107, 2, 2, 184, 185, 7, 112, 2, 2, 185, 186, 7, 117, 2, 2, 186, 10,
|
||||
3, 2, 2, 2, 187, 188, 7, 111, 2, 2, 188, 189, 7, 99, 2, 2, 189, 190, 7,
|
||||
118, 2, 2, 190, 191, 7, 101, 2, 2, 191, 192, 7, 106, 2, 2, 192, 193, 7,
|
||||
103, 2, 2, 193, 194, 7, 117, 2, 2, 194, 12, 3, 2, 2, 2, 195, 196, 7, 107,
|
||||
2, 2, 196, 197, 7, 112, 2, 2, 197, 14, 3, 2, 2, 2, 198, 199, 7, 112, 2,
|
||||
2, 199, 200, 7, 113, 2, 2, 200, 201, 7, 118, 2, 2, 201, 202, 7, 34, 2,
|
||||
2, 202, 203, 7, 107, 2, 2, 203, 204, 7, 112, 2, 2, 204, 16, 3, 2, 2, 2,
|
||||
205, 206, 7, 110, 2, 2, 206, 207, 7, 103, 2, 2, 207, 208, 7, 112, 2, 2,
|
||||
208, 18, 3, 2, 2, 2, 209, 210, 7, 99, 2, 2, 210, 211, 7, 110, 2, 2, 211,
|
||||
212, 7, 110, 2, 2, 212, 20, 3, 2, 2, 2, 213, 214, 7, 112, 2, 2, 214, 215,
|
||||
7, 113, 2, 2, 215, 216, 7, 112, 2, 2, 216, 217, 7, 103, 2, 2, 217, 22,
|
||||
3, 2, 2, 2, 218, 219, 7, 99, 2, 2, 219, 220, 7, 112, 2, 2, 220, 221, 7,
|
||||
123, 2, 2, 221, 24, 3, 2, 2, 2, 222, 223, 7, 113, 2, 2, 223, 224, 7, 112,
|
||||
2, 2, 224, 225, 7, 103, 2, 2, 225, 26, 3, 2, 2, 2, 226, 227, 7, 104, 2,
|
||||
2, 227, 228, 7, 107, 2, 2, 228, 229, 7, 110, 2, 2, 229, 230, 7, 118, 2,
|
||||
2, 230, 231, 7, 103, 2, 2, 231, 232, 7, 116, 2, 2, 232, 28, 3, 2, 2, 2,
|
||||
233, 234, 7, 111, 2, 2, 234, 235, 7, 99, 2, 2, 235, 236, 7, 114, 2, 2,
|
||||
236, 30, 3, 2, 2, 2, 237, 238, 7, 93, 2, 2, 238, 32, 3, 2, 2, 2, 239, 240,
|
||||
7, 95, 2, 2, 240, 34, 3, 2, 2, 2, 241, 242, 7, 42, 2, 2, 242, 36, 3, 2,
|
||||
2, 2, 243, 244, 7, 43, 2, 2, 244, 38, 3, 2, 2, 2, 245, 246, 7, 125, 2,
|
||||
2, 246, 40, 3, 2, 2, 2, 247, 248, 7, 127, 2, 2, 248, 42, 3, 2, 2, 2, 249,
|
||||
250, 7, 61, 2, 2, 250, 44, 3, 2, 2, 2, 251, 252, 7, 46, 2, 2, 252, 46,
|
||||
3, 2, 2, 2, 253, 254, 7, 63, 2, 2, 254, 48, 3, 2, 2, 2, 255, 256, 7, 65,
|
||||
2, 2, 256, 50, 3, 2, 2, 2, 257, 258, 7, 60, 2, 2, 258, 52, 3, 2, 2, 2,
|
||||
259, 260, 7, 48, 2, 2, 260, 54, 3, 2, 2, 2, 261, 262, 7, 45, 2, 2, 262,
|
||||
56, 3, 2, 2, 2, 263, 264, 7, 47, 2, 2, 264, 58, 3, 2, 2, 2, 265, 266, 7,
|
||||
35, 2, 2, 266, 60, 3, 2, 2, 2, 267, 268, 7, 112, 2, 2, 268, 269, 7, 113,
|
||||
2, 2, 269, 270, 7, 118, 2, 2, 270, 62, 3, 2, 2, 2, 271, 272, 7, 112, 2,
|
||||
2, 272, 273, 7, 107, 2, 2, 273, 274, 7, 110, 2, 2, 274, 64, 3, 2, 2, 2,
|
||||
275, 276, 7, 44, 2, 2, 276, 66, 3, 2, 2, 2, 277, 278, 7, 44, 2, 2, 278,
|
||||
279, 7, 44, 2, 2, 279, 68, 3, 2, 2, 2, 280, 281, 7, 49, 2, 2, 281, 70,
|
||||
3, 2, 2, 2, 282, 283, 7, 39, 2, 2, 283, 72, 3, 2, 2, 2, 284, 285, 7, 64,
|
||||
2, 2, 285, 286, 7, 64, 2, 2, 286, 74, 3, 2, 2, 2, 287, 288, 7, 62, 2, 2,
|
||||
288, 289, 7, 62, 2, 2, 289, 76, 3, 2, 2, 2, 290, 291, 7, 62, 2, 2, 291,
|
||||
78, 3, 2, 2, 2, 292, 293, 7, 64, 2, 2, 293, 80, 3, 2, 2, 2, 294, 295, 7,
|
||||
62, 2, 2, 295, 296, 7, 63, 2, 2, 296, 82, 3, 2, 2, 2, 297, 298, 7, 64,
|
||||
2, 2, 298, 299, 7, 63, 2, 2, 299, 84, 3, 2, 2, 2, 300, 301, 7, 63, 2, 2,
|
||||
301, 302, 7, 63, 2, 2, 302, 86, 3, 2, 2, 2, 303, 304, 7, 35, 2, 2, 304,
|
||||
305, 7, 63, 2, 2, 305, 88, 3, 2, 2, 2, 306, 307, 7, 37, 2, 2, 307, 90,
|
||||
3, 2, 2, 2, 308, 309, 7, 40, 2, 2, 309, 314, 7, 40, 2, 2, 310, 311, 7,
|
||||
99, 2, 2, 311, 312, 7, 112, 2, 2, 312, 314, 7, 102, 2, 2, 313, 308, 3,
|
||||
2, 2, 2, 313, 310, 3, 2, 2, 2, 314, 92, 3, 2, 2, 2, 315, 316, 7, 126, 2,
|
||||
2, 316, 320, 7, 126, 2, 2, 317, 318, 7, 113, 2, 2, 318, 320, 7, 116, 2,
|
||||
2, 319, 315, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 320, 94, 3, 2, 2, 2, 321,
|
||||
322, 7, 99, 2, 2, 322, 323, 7, 110, 2, 2, 323, 344, 7, 110, 2, 2, 324,
|
||||
325, 7, 112, 2, 2, 325, 326, 7, 113, 2, 2, 326, 327, 7, 112, 2, 2, 327,
|
||||
344, 7, 103, 2, 2, 328, 329, 7, 99, 2, 2, 329, 330, 7, 112, 2, 2, 330,
|
||||
344, 7, 123, 2, 2, 331, 332, 7, 113, 2, 2, 332, 333, 7, 112, 2, 2, 333,
|
||||
344, 7, 103, 2, 2, 334, 335, 7, 104, 2, 2, 335, 336, 7, 107, 2, 2, 336,
|
||||
337, 7, 110, 2, 2, 337, 338, 7, 118, 2, 2, 338, 339, 7, 103, 2, 2, 339,
|
||||
344, 7, 116, 2, 2, 340, 341, 7, 111, 2, 2, 341, 342, 7, 99, 2, 2, 342,
|
||||
344, 7, 114, 2, 2, 343, 321, 3, 2, 2, 2, 343, 324, 3, 2, 2, 2, 343, 328,
|
||||
3, 2, 2, 2, 343, 331, 3, 2, 2, 2, 343, 334, 3, 2, 2, 2, 343, 340, 3, 2,
|
||||
2, 2, 344, 96, 3, 2, 2, 2, 345, 346, 7, 117, 2, 2, 346, 347, 7, 118, 2,
|
||||
2, 347, 348, 7, 99, 2, 2, 348, 349, 7, 116, 2, 2, 349, 350, 7, 118, 2,
|
||||
2, 350, 351, 7, 117, 2, 2, 351, 352, 7, 89, 2, 2, 352, 353, 7, 107, 2,
|
||||
2, 353, 354, 7, 118, 2, 2, 354, 387, 7, 106, 2, 2, 355, 356, 7, 103, 2,
|
||||
2, 356, 357, 7, 112, 2, 2, 357, 358, 7, 102, 2, 2, 358, 359, 7, 117, 2,
|
||||
2, 359, 360, 7, 89, 2, 2, 360, 361, 7, 107, 2, 2, 361, 362, 7, 118, 2,
|
||||
2, 362, 387, 7, 106, 2, 2, 363, 364, 7, 101, 2, 2, 364, 365, 7, 113, 2,
|
||||
2, 365, 366, 7, 112, 2, 2, 366, 367, 7, 118, 2, 2, 367, 368, 7, 99, 2,
|
||||
2, 368, 369, 7, 107, 2, 2, 369, 370, 7, 112, 2, 2, 370, 387, 7, 117, 2,
|
||||
2, 371, 372, 7, 111, 2, 2, 372, 373, 7, 99, 2, 2, 373, 374, 7, 118, 2,
|
||||
2, 374, 375, 7, 101, 2, 2, 375, 376, 7, 106, 2, 2, 376, 377, 7, 103, 2,
|
||||
2, 377, 387, 7, 117, 2, 2, 378, 379, 7, 107, 2, 2, 379, 387, 7, 112, 2,
|
||||
2, 380, 381, 7, 112, 2, 2, 381, 382, 7, 113, 2, 2, 382, 383, 7, 118, 2,
|
||||
2, 383, 384, 7, 34, 2, 2, 384, 385, 7, 107, 2, 2, 385, 387, 7, 112, 2,
|
||||
2, 386, 345, 3, 2, 2, 2, 386, 355, 3, 2, 2, 2, 386, 363, 3, 2, 2, 2, 386,
|
||||
371, 3, 2, 2, 2, 386, 378, 3, 2, 2, 2, 386, 380, 3, 2, 2, 2, 387, 98, 3,
|
||||
2, 2, 2, 388, 389, 7, 118, 2, 2, 389, 390, 7, 116, 2, 2, 390, 391, 7, 119,
|
||||
2, 2, 391, 398, 7, 103, 2, 2, 392, 393, 7, 104, 2, 2, 393, 394, 7, 99,
|
||||
2, 2, 394, 395, 7, 110, 2, 2, 395, 396, 7, 117, 2, 2, 396, 398, 7, 103,
|
||||
2, 2, 397, 388, 3, 2, 2, 2, 397, 392, 3, 2, 2, 2, 398, 100, 3, 2, 2, 2,
|
||||
399, 408, 7, 50, 2, 2, 400, 404, 9, 2, 2, 2, 401, 403, 9, 3, 2, 2, 402,
|
||||
401, 3, 2, 2, 2, 403, 406, 3, 2, 2, 2, 404, 402, 3, 2, 2, 2, 404, 405,
|
||||
3, 2, 2, 2, 405, 408, 3, 2, 2, 2, 406, 404, 3, 2, 2, 2, 407, 399, 3, 2,
|
||||
2, 2, 407, 400, 3, 2, 2, 2, 408, 102, 3, 2, 2, 2, 409, 410, 5, 151, 76,
|
||||
2, 410, 412, 7, 48, 2, 2, 411, 413, 5, 149, 75, 2, 412, 411, 3, 2, 2, 2,
|
||||
413, 414, 3, 2, 2, 2, 414, 412, 3, 2, 2, 2, 414, 415, 3, 2, 2, 2, 415,
|
||||
423, 3, 2, 2, 2, 416, 418, 7, 48, 2, 2, 417, 419, 5, 149, 75, 2, 418, 417,
|
||||
3, 2, 2, 2, 419, 420, 3, 2, 2, 2, 420, 418, 3, 2, 2, 2, 420, 421, 3, 2,
|
||||
2, 2, 421, 423, 3, 2, 2, 2, 422, 409, 3, 2, 2, 2, 422, 416, 3, 2, 2, 2,
|
||||
423, 104, 3, 2, 2, 2, 424, 425, 7, 50, 2, 2, 425, 427, 9, 4, 2, 2, 426,
|
||||
428, 5, 153, 77, 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, 106, 3, 2, 2, 2, 431, 435, 5, 143,
|
||||
72, 2, 432, 434, 5, 145, 73, 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, 108, 3, 2, 2, 2, 437,
|
||||
435, 3, 2, 2, 2, 438, 442, 7, 36, 2, 2, 439, 441, 5, 121, 61, 2, 440, 439,
|
||||
3, 2, 2, 2, 441, 444, 3, 2, 2, 2, 442, 440, 3, 2, 2, 2, 442, 443, 3, 2,
|
||||
2, 2, 443, 445, 3, 2, 2, 2, 444, 442, 3, 2, 2, 2, 445, 455, 7, 36, 2, 2,
|
||||
446, 450, 7, 41, 2, 2, 447, 449, 5, 123, 62, 2, 448, 447, 3, 2, 2, 2, 449,
|
||||
452, 3, 2, 2, 2, 450, 448, 3, 2, 2, 2, 450, 451, 3, 2, 2, 2, 451, 453,
|
||||
3, 2, 2, 2, 452, 450, 3, 2, 2, 2, 453, 455, 7, 41, 2, 2, 454, 438, 3, 2,
|
||||
2, 2, 454, 446, 3, 2, 2, 2, 455, 110, 3, 2, 2, 2, 456, 458, 9, 5, 2, 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, 461, 3, 2, 2, 2, 461, 462, 8, 56, 2, 2, 462, 112,
|
||||
3, 2, 2, 2, 463, 464, 7, 49, 2, 2, 464, 465, 7, 44, 2, 2, 465, 469, 3,
|
||||
2, 2, 2, 466, 468, 11, 2, 2, 2, 467, 466, 3, 2, 2, 2, 468, 471, 3, 2, 2,
|
||||
2, 469, 470, 3, 2, 2, 2, 469, 467, 3, 2, 2, 2, 470, 472, 3, 2, 2, 2, 471,
|
||||
469, 3, 2, 2, 2, 472, 473, 7, 44, 2, 2, 473, 474, 7, 49, 2, 2, 474, 475,
|
||||
3, 2, 2, 2, 475, 476, 8, 57, 2, 2, 476, 114, 3, 2, 2, 2, 477, 478, 7, 49,
|
||||
2, 2, 478, 479, 7, 49, 2, 2, 479, 483, 3, 2, 2, 2, 480, 482, 10, 6, 2,
|
||||
2, 481, 480, 3, 2, 2, 2, 482, 485, 3, 2, 2, 2, 483, 481, 3, 2, 2, 2, 483,
|
||||
484, 3, 2, 2, 2, 484, 486, 3, 2, 2, 2, 485, 483, 3, 2, 2, 2, 486, 487,
|
||||
8, 58, 2, 2, 487, 116, 3, 2, 2, 2, 488, 489, 9, 6, 2, 2, 489, 490, 3, 2,
|
||||
2, 2, 490, 491, 8, 59, 2, 2, 491, 118, 3, 2, 2, 2, 492, 493, 11, 2, 2,
|
||||
2, 493, 120, 3, 2, 2, 2, 494, 499, 10, 7, 2, 2, 495, 496, 7, 94, 2, 2,
|
||||
496, 499, 5, 125, 63, 2, 497, 499, 5, 139, 70, 2, 498, 494, 3, 2, 2, 2,
|
||||
498, 495, 3, 2, 2, 2, 498, 497, 3, 2, 2, 2, 499, 122, 3, 2, 2, 2, 500,
|
||||
505, 10, 8, 2, 2, 501, 502, 7, 94, 2, 2, 502, 505, 5, 125, 63, 2, 503,
|
||||
505, 5, 139, 70, 2, 504, 500, 3, 2, 2, 2, 504, 501, 3, 2, 2, 2, 504, 503,
|
||||
3, 2, 2, 2, 505, 124, 3, 2, 2, 2, 506, 511, 5, 127, 64, 2, 507, 511, 7,
|
||||
50, 2, 2, 508, 511, 5, 129, 65, 2, 509, 511, 5, 131, 66, 2, 510, 506, 3,
|
||||
2, 2, 2, 510, 507, 3, 2, 2, 2, 510, 508, 3, 2, 2, 2, 510, 509, 3, 2, 2,
|
||||
2, 511, 126, 3, 2, 2, 2, 512, 515, 5, 133, 67, 2, 513, 515, 5, 135, 68,
|
||||
2, 514, 512, 3, 2, 2, 2, 514, 513, 3, 2, 2, 2, 515, 128, 3, 2, 2, 2, 516,
|
||||
517, 7, 122, 2, 2, 517, 518, 5, 153, 77, 2, 518, 519, 5, 153, 77, 2, 519,
|
||||
130, 3, 2, 2, 2, 520, 521, 7, 119, 2, 2, 521, 522, 5, 153, 77, 2, 522,
|
||||
523, 5, 153, 77, 2, 523, 524, 5, 153, 77, 2, 524, 525, 5, 153, 77, 2, 525,
|
||||
132, 3, 2, 2, 2, 526, 527, 9, 9, 2, 2, 527, 134, 3, 2, 2, 2, 528, 529,
|
||||
10, 10, 2, 2, 529, 136, 3, 2, 2, 2, 530, 534, 5, 133, 67, 2, 531, 534,
|
||||
5, 149, 75, 2, 532, 534, 9, 11, 2, 2, 533, 530, 3, 2, 2, 2, 533, 531, 3,
|
||||
2, 2, 2, 533, 532, 3, 2, 2, 2, 534, 138, 3, 2, 2, 2, 535, 536, 7, 94, 2,
|
||||
2, 536, 537, 5, 141, 71, 2, 537, 140, 3, 2, 2, 2, 538, 539, 7, 15, 2, 2,
|
||||
539, 542, 7, 12, 2, 2, 540, 542, 5, 117, 59, 2, 541, 538, 3, 2, 2, 2, 541,
|
||||
540, 3, 2, 2, 2, 542, 142, 3, 2, 2, 2, 543, 546, 5, 147, 74, 2, 544, 546,
|
||||
9, 12, 2, 2, 545, 543, 3, 2, 2, 2, 545, 544, 3, 2, 2, 2, 546, 144, 3, 2,
|
||||
2, 2, 547, 551, 5, 147, 74, 2, 548, 551, 5, 149, 75, 2, 549, 551, 9, 13,
|
||||
2, 2, 550, 547, 3, 2, 2, 2, 550, 548, 3, 2, 2, 2, 550, 549, 3, 2, 2, 2,
|
||||
551, 146, 3, 2, 2, 2, 552, 553, 9, 14, 2, 2, 553, 148, 3, 2, 2, 2, 554,
|
||||
555, 4, 50, 59, 2, 555, 150, 3, 2, 2, 2, 556, 565, 7, 50, 2, 2, 557, 561,
|
||||
9, 2, 2, 2, 558, 560, 5, 149, 75, 2, 559, 558, 3, 2, 2, 2, 560, 563, 3,
|
||||
2, 2, 2, 561, 559, 3, 2, 2, 2, 561, 562, 3, 2, 2, 2, 562, 565, 3, 2, 2,
|
||||
2, 563, 561, 3, 2, 2, 2, 564, 556, 3, 2, 2, 2, 564, 557, 3, 2, 2, 2, 565,
|
||||
152, 3, 2, 2, 2, 566, 567, 9, 15, 2, 2, 567, 154, 3, 2, 2, 2, 31, 2, 313,
|
||||
319, 343, 386, 397, 404, 407, 414, 420, 422, 429, 435, 442, 450, 454, 459,
|
||||
469, 483, 498, 504, 510, 514, 533, 541, 545, 550, 561, 564, 3, 2, 3, 2,
|
||||
}
|
||||
|
||||
var lexerDeserializer = antlr.NewATNDeserializer(nil)
|
||||
var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn)
|
||||
|
||||
var lexerChannelNames = []string{
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
|
||||
}
|
||||
|
||||
var lexerModeNames = []string{
|
||||
"DEFAULT_MODE",
|
||||
}
|
||||
|
||||
var lexerLiteralNames = []string{
|
||||
"", "'..'", "'startsWith'", "'endsWith'", "'contains'", "'matches'", "'in'",
|
||||
"'not in'", "'len'", "'all'", "'none'", "'any'", "'one'", "'filter'", "'map'",
|
||||
"'['", "']'", "'('", "')'", "'{'", "'}'", "';'", "','", "'='", "'?'", "':'",
|
||||
"'.'", "'+'", "'-'", "'!'", "'not'", "'nil'", "'*'", "'**'", "'/'", "'%'",
|
||||
"'>>'", "'<<'", "'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "'#'",
|
||||
}
|
||||
|
||||
var lexerSymbolicNames = []string{
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "OpenBracket",
|
||||
"CloseBracket", "OpenParen", "CloseParen", "OpenBrace", "CloseBrace", "SemiColon",
|
||||
"Comma", "Assign", "QuestionMark", "Colon", "Dot", "Plus", "Minus", "Negate",
|
||||
"Not", "Nil", "Multiply", "Exponent", "Divide", "Modulus", "RightShiftArithmetic",
|
||||
"LeftShiftArithmetic", "LessThan", "MoreThan", "LessThanEquals", "GreaterThanEquals",
|
||||
"Equals", "NotEquals", "Pointer", "And", "Or", "Builtins", "Ops", "BooleanLiteral",
|
||||
"IntegerLiteral", "FloatLiteral", "HexIntegerLiteral", "Identifier", "StringLiteral",
|
||||
"WhiteSpaces", "MultiLineComment", "SingleLineComment", "LineTerminator",
|
||||
"UnexpectedCharacter",
|
||||
}
|
||||
|
||||
var lexerRuleNames = []string{
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
|
||||
"T__9", "T__10", "T__11", "T__12", "T__13", "OpenBracket", "CloseBracket",
|
||||
"OpenParen", "CloseParen", "OpenBrace", "CloseBrace", "SemiColon", "Comma",
|
||||
"Assign", "QuestionMark", "Colon", "Dot", "Plus", "Minus", "Negate", "Not",
|
||||
"Nil", "Multiply", "Exponent", "Divide", "Modulus", "RightShiftArithmetic",
|
||||
"LeftShiftArithmetic", "LessThan", "MoreThan", "LessThanEquals", "GreaterThanEquals",
|
||||
"Equals", "NotEquals", "Pointer", "And", "Or", "Builtins", "Ops", "BooleanLiteral",
|
||||
"IntegerLiteral", "FloatLiteral", "HexIntegerLiteral", "Identifier", "StringLiteral",
|
||||
"WhiteSpaces", "MultiLineComment", "SingleLineComment", "LineTerminator",
|
||||
"UnexpectedCharacter", "DoubleStringCharacter", "SingleStringCharacter",
|
||||
"EscapeSequence", "CharacterEscapeSequence", "HexEscapeSequence", "UnicodeEscapeSequence",
|
||||
"SingleEscapeCharacter", "NonEscapeCharacter", "EscapeCharacter", "LineContinuation",
|
||||
"LineTerminatorSequence", "IdentifierStart", "IdentifierPart", "Letter",
|
||||
"Digit", "DecimalLiteral", "HexDigit",
|
||||
}
|
||||
|
||||
type ExprLexer struct {
|
||||
*antlr.BaseLexer
|
||||
channelNames []string
|
||||
modeNames []string
|
||||
// TODO: EOF string
|
||||
}
|
||||
|
||||
var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState))
|
||||
|
||||
func init() {
|
||||
for index, ds := range lexerAtn.DecisionToState {
|
||||
lexerDecisionToDFA[index] = antlr.NewDFA(ds, index)
|
||||
}
|
||||
}
|
||||
|
||||
func NewExprLexer(input antlr.CharStream) *ExprLexer {
|
||||
|
||||
l := new(ExprLexer)
|
||||
|
||||
l.BaseLexer = antlr.NewBaseLexer(input)
|
||||
l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache())
|
||||
|
||||
l.channelNames = lexerChannelNames
|
||||
l.modeNames = lexerModeNames
|
||||
l.RuleNames = lexerRuleNames
|
||||
l.LiteralNames = lexerLiteralNames
|
||||
l.SymbolicNames = lexerSymbolicNames
|
||||
l.GrammarFileName = "Expr.g4"
|
||||
// TODO: l.EOF = antlr.TokenEOF
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// ExprLexer tokens.
|
||||
const (
|
||||
ExprLexerT__0 = 1
|
||||
ExprLexerT__1 = 2
|
||||
ExprLexerT__2 = 3
|
||||
ExprLexerT__3 = 4
|
||||
ExprLexerT__4 = 5
|
||||
ExprLexerT__5 = 6
|
||||
ExprLexerT__6 = 7
|
||||
ExprLexerT__7 = 8
|
||||
ExprLexerT__8 = 9
|
||||
ExprLexerT__9 = 10
|
||||
ExprLexerT__10 = 11
|
||||
ExprLexerT__11 = 12
|
||||
ExprLexerT__12 = 13
|
||||
ExprLexerT__13 = 14
|
||||
ExprLexerOpenBracket = 15
|
||||
ExprLexerCloseBracket = 16
|
||||
ExprLexerOpenParen = 17
|
||||
ExprLexerCloseParen = 18
|
||||
ExprLexerOpenBrace = 19
|
||||
ExprLexerCloseBrace = 20
|
||||
ExprLexerSemiColon = 21
|
||||
ExprLexerComma = 22
|
||||
ExprLexerAssign = 23
|
||||
ExprLexerQuestionMark = 24
|
||||
ExprLexerColon = 25
|
||||
ExprLexerDot = 26
|
||||
ExprLexerPlus = 27
|
||||
ExprLexerMinus = 28
|
||||
ExprLexerNegate = 29
|
||||
ExprLexerNot = 30
|
||||
ExprLexerNil = 31
|
||||
ExprLexerMultiply = 32
|
||||
ExprLexerExponent = 33
|
||||
ExprLexerDivide = 34
|
||||
ExprLexerModulus = 35
|
||||
ExprLexerRightShiftArithmetic = 36
|
||||
ExprLexerLeftShiftArithmetic = 37
|
||||
ExprLexerLessThan = 38
|
||||
ExprLexerMoreThan = 39
|
||||
ExprLexerLessThanEquals = 40
|
||||
ExprLexerGreaterThanEquals = 41
|
||||
ExprLexerEquals = 42
|
||||
ExprLexerNotEquals = 43
|
||||
ExprLexerPointer = 44
|
||||
ExprLexerAnd = 45
|
||||
ExprLexerOr = 46
|
||||
ExprLexerBuiltins = 47
|
||||
ExprLexerOps = 48
|
||||
ExprLexerBooleanLiteral = 49
|
||||
ExprLexerIntegerLiteral = 50
|
||||
ExprLexerFloatLiteral = 51
|
||||
ExprLexerHexIntegerLiteral = 52
|
||||
ExprLexerIdentifier = 53
|
||||
ExprLexerStringLiteral = 54
|
||||
ExprLexerWhiteSpaces = 55
|
||||
ExprLexerMultiLineComment = 56
|
||||
ExprLexerSingleLineComment = 57
|
||||
ExprLexerLineTerminator = 58
|
||||
ExprLexerUnexpectedCharacter = 59
|
||||
)
|
||||
@@ -1,189 +0,0 @@
|
||||
// Code generated from Expr.g4 by ANTLR 4.7.2. DO NOT EDIT.
|
||||
|
||||
package gen // Expr
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
// ExprListener is a complete listener for a parse tree produced by ExprParser.
|
||||
type ExprListener interface {
|
||||
antlr.ParseTreeListener
|
||||
|
||||
// EnterStart is called when entering the start production.
|
||||
EnterStart(c *StartContext)
|
||||
|
||||
// EnterCall is called when entering the Call production.
|
||||
EnterCall(c *CallContext)
|
||||
|
||||
// EnterMatches is called when entering the Matches production.
|
||||
EnterMatches(c *MatchesContext)
|
||||
|
||||
// EnterTernary is called when entering the Ternary production.
|
||||
EnterTernary(c *TernaryContext)
|
||||
|
||||
// EnterPointer is called when entering the Pointer production.
|
||||
EnterPointer(c *PointerContext)
|
||||
|
||||
// EnterString is called when entering the String production.
|
||||
EnterString(c *StringContext)
|
||||
|
||||
// EnterClosureMemberDot is called when entering the ClosureMemberDot production.
|
||||
EnterClosureMemberDot(c *ClosureMemberDotContext)
|
||||
|
||||
// EnterUnary is called when entering the Unary production.
|
||||
EnterUnary(c *UnaryContext)
|
||||
|
||||
// EnterNil is called when entering the Nil production.
|
||||
EnterNil(c *NilContext)
|
||||
|
||||
// EnterInteger is called when entering the Integer production.
|
||||
EnterInteger(c *IntegerContext)
|
||||
|
||||
// EnterArray is called when entering the Array production.
|
||||
EnterArray(c *ArrayContext)
|
||||
|
||||
// EnterFloat is called when entering the Float production.
|
||||
EnterFloat(c *FloatContext)
|
||||
|
||||
// EnterIdentifier is called when entering the Identifier production.
|
||||
EnterIdentifier(c *IdentifierContext)
|
||||
|
||||
// EnterParenthesized is called when entering the Parenthesized production.
|
||||
EnterParenthesized(c *ParenthesizedContext)
|
||||
|
||||
// EnterSlice is called when entering the Slice production.
|
||||
EnterSlice(c *SliceContext)
|
||||
|
||||
// EnterMemberIndex is called when entering the MemberIndex production.
|
||||
EnterMemberIndex(c *MemberIndexContext)
|
||||
|
||||
// EnterBuiltinsList is called when entering the BuiltinsList production.
|
||||
EnterBuiltinsList(c *BuiltinsListContext)
|
||||
|
||||
// EnterBinary is called when entering the Binary production.
|
||||
EnterBinary(c *BinaryContext)
|
||||
|
||||
// EnterBoolean is called when entering the Boolean production.
|
||||
EnterBoolean(c *BooleanContext)
|
||||
|
||||
// EnterMap is called when entering the Map production.
|
||||
EnterMap(c *MapContext)
|
||||
|
||||
// EnterMemberDot is called when entering the MemberDot production.
|
||||
EnterMemberDot(c *MemberDotContext)
|
||||
|
||||
// EnterBuiltinLen is called when entering the BuiltinLen production.
|
||||
EnterBuiltinLen(c *BuiltinLenContext)
|
||||
|
||||
// EnterBuiltin is called when entering the Builtin production.
|
||||
EnterBuiltin(c *BuiltinContext)
|
||||
|
||||
// EnterClosure is called when entering the closure production.
|
||||
EnterClosure(c *ClosureContext)
|
||||
|
||||
// EnterArguments is called when entering the arguments production.
|
||||
EnterArguments(c *ArgumentsContext)
|
||||
|
||||
// EnterArrayLiteral is called when entering the arrayLiteral production.
|
||||
EnterArrayLiteral(c *ArrayLiteralContext)
|
||||
|
||||
// EnterMapLiteral is called when entering the mapLiteral production.
|
||||
EnterMapLiteral(c *MapLiteralContext)
|
||||
|
||||
// EnterPropertyNameAndValueList is called when entering the propertyNameAndValueList production.
|
||||
EnterPropertyNameAndValueList(c *PropertyNameAndValueListContext)
|
||||
|
||||
// EnterPropertyAssignment is called when entering the propertyAssignment production.
|
||||
EnterPropertyAssignment(c *PropertyAssignmentContext)
|
||||
|
||||
// EnterPropertyName is called when entering the propertyName production.
|
||||
EnterPropertyName(c *PropertyNameContext)
|
||||
|
||||
// ExitStart is called when exiting the start production.
|
||||
ExitStart(c *StartContext)
|
||||
|
||||
// ExitCall is called when exiting the Call production.
|
||||
ExitCall(c *CallContext)
|
||||
|
||||
// ExitMatches is called when exiting the Matches production.
|
||||
ExitMatches(c *MatchesContext)
|
||||
|
||||
// ExitTernary is called when exiting the Ternary production.
|
||||
ExitTernary(c *TernaryContext)
|
||||
|
||||
// ExitPointer is called when exiting the Pointer production.
|
||||
ExitPointer(c *PointerContext)
|
||||
|
||||
// ExitString is called when exiting the String production.
|
||||
ExitString(c *StringContext)
|
||||
|
||||
// ExitClosureMemberDot is called when exiting the ClosureMemberDot production.
|
||||
ExitClosureMemberDot(c *ClosureMemberDotContext)
|
||||
|
||||
// ExitUnary is called when exiting the Unary production.
|
||||
ExitUnary(c *UnaryContext)
|
||||
|
||||
// ExitNil is called when exiting the Nil production.
|
||||
ExitNil(c *NilContext)
|
||||
|
||||
// ExitInteger is called when exiting the Integer production.
|
||||
ExitInteger(c *IntegerContext)
|
||||
|
||||
// ExitArray is called when exiting the Array production.
|
||||
ExitArray(c *ArrayContext)
|
||||
|
||||
// ExitFloat is called when exiting the Float production.
|
||||
ExitFloat(c *FloatContext)
|
||||
|
||||
// ExitIdentifier is called when exiting the Identifier production.
|
||||
ExitIdentifier(c *IdentifierContext)
|
||||
|
||||
// ExitParenthesized is called when exiting the Parenthesized production.
|
||||
ExitParenthesized(c *ParenthesizedContext)
|
||||
|
||||
// ExitSlice is called when exiting the Slice production.
|
||||
ExitSlice(c *SliceContext)
|
||||
|
||||
// ExitMemberIndex is called when exiting the MemberIndex production.
|
||||
ExitMemberIndex(c *MemberIndexContext)
|
||||
|
||||
// ExitBuiltinsList is called when exiting the BuiltinsList production.
|
||||
ExitBuiltinsList(c *BuiltinsListContext)
|
||||
|
||||
// ExitBinary is called when exiting the Binary production.
|
||||
ExitBinary(c *BinaryContext)
|
||||
|
||||
// ExitBoolean is called when exiting the Boolean production.
|
||||
ExitBoolean(c *BooleanContext)
|
||||
|
||||
// ExitMap is called when exiting the Map production.
|
||||
ExitMap(c *MapContext)
|
||||
|
||||
// ExitMemberDot is called when exiting the MemberDot production.
|
||||
ExitMemberDot(c *MemberDotContext)
|
||||
|
||||
// ExitBuiltinLen is called when exiting the BuiltinLen production.
|
||||
ExitBuiltinLen(c *BuiltinLenContext)
|
||||
|
||||
// ExitBuiltin is called when exiting the Builtin production.
|
||||
ExitBuiltin(c *BuiltinContext)
|
||||
|
||||
// ExitClosure is called when exiting the closure production.
|
||||
ExitClosure(c *ClosureContext)
|
||||
|
||||
// ExitArguments is called when exiting the arguments production.
|
||||
ExitArguments(c *ArgumentsContext)
|
||||
|
||||
// ExitArrayLiteral is called when exiting the arrayLiteral production.
|
||||
ExitArrayLiteral(c *ArrayLiteralContext)
|
||||
|
||||
// ExitMapLiteral is called when exiting the mapLiteral production.
|
||||
ExitMapLiteral(c *MapLiteralContext)
|
||||
|
||||
// ExitPropertyNameAndValueList is called when exiting the propertyNameAndValueList production.
|
||||
ExitPropertyNameAndValueList(c *PropertyNameAndValueListContext)
|
||||
|
||||
// ExitPropertyAssignment is called when exiting the propertyAssignment production.
|
||||
ExitPropertyAssignment(c *PropertyAssignmentContext)
|
||||
|
||||
// ExitPropertyName is called when exiting the propertyName production.
|
||||
ExitPropertyName(c *PropertyNameContext)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,99 +0,0 @@
|
||||
// Code generated from Expr.g4 by ANTLR 4.7.2. DO NOT EDIT.
|
||||
|
||||
package gen // Expr
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
// A complete Visitor for a parse tree produced by ExprParser.
|
||||
type ExprVisitor interface {
|
||||
antlr.ParseTreeVisitor
|
||||
|
||||
// Visit a parse tree produced by ExprParser#start.
|
||||
VisitStart(ctx *StartContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Call.
|
||||
VisitCall(ctx *CallContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Matches.
|
||||
VisitMatches(ctx *MatchesContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Ternary.
|
||||
VisitTernary(ctx *TernaryContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Pointer.
|
||||
VisitPointer(ctx *PointerContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#String.
|
||||
VisitString(ctx *StringContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#ClosureMemberDot.
|
||||
VisitClosureMemberDot(ctx *ClosureMemberDotContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Unary.
|
||||
VisitUnary(ctx *UnaryContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Nil.
|
||||
VisitNil(ctx *NilContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Integer.
|
||||
VisitInteger(ctx *IntegerContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Array.
|
||||
VisitArray(ctx *ArrayContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Float.
|
||||
VisitFloat(ctx *FloatContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Identifier.
|
||||
VisitIdentifier(ctx *IdentifierContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Parenthesized.
|
||||
VisitParenthesized(ctx *ParenthesizedContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Slice.
|
||||
VisitSlice(ctx *SliceContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#MemberIndex.
|
||||
VisitMemberIndex(ctx *MemberIndexContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#BuiltinsList.
|
||||
VisitBuiltinsList(ctx *BuiltinsListContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Binary.
|
||||
VisitBinary(ctx *BinaryContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Boolean.
|
||||
VisitBoolean(ctx *BooleanContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Map.
|
||||
VisitMap(ctx *MapContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#MemberDot.
|
||||
VisitMemberDot(ctx *MemberDotContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#BuiltinLen.
|
||||
VisitBuiltinLen(ctx *BuiltinLenContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#Builtin.
|
||||
VisitBuiltin(ctx *BuiltinContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#closure.
|
||||
VisitClosure(ctx *ClosureContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#arguments.
|
||||
VisitArguments(ctx *ArgumentsContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#arrayLiteral.
|
||||
VisitArrayLiteral(ctx *ArrayLiteralContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#mapLiteral.
|
||||
VisitMapLiteral(ctx *MapLiteralContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#propertyNameAndValueList.
|
||||
VisitPropertyNameAndValueList(ctx *PropertyNameAndValueListContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#propertyAssignment.
|
||||
VisitPropertyAssignment(ctx *PropertyAssignmentContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by ExprParser#propertyName.
|
||||
VisitPropertyName(ctx *PropertyNameContext) interface{}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/antonmedv/expr/parser2/lexer"
|
||||
. "github.com/antonmedv/expr/parser/lexer"
|
||||
)
|
||||
|
||||
type lexTest struct {
|
||||
@@ -20,12 +20,13 @@ type lexErrorTest struct {
|
||||
|
||||
var lexTests = []lexTest{
|
||||
{
|
||||
".5 1 02 1e3 1.2e-4 1_000_000 _42",
|
||||
".5 1 02 1e3 0xFF 1.2e-4 1_000_000 _42",
|
||||
[]Token{
|
||||
{Kind: Number, Value: ".5"},
|
||||
{Kind: Number, Value: "1"},
|
||||
{Kind: Number, Value: "02"},
|
||||
{Kind: Number, Value: "1e3"},
|
||||
{Kind: Number, Value: "0xFF"},
|
||||
{Kind: Number, Value: "1.2e-4"},
|
||||
{Kind: Number, Value: "1_000_000"},
|
||||
{Kind: Identifier, Value: "_42"},
|
||||
@@ -51,12 +51,20 @@ func number(l *lexer) stateFn {
|
||||
return root
|
||||
}
|
||||
|
||||
const digits = "0123456789"
|
||||
|
||||
func (l *lexer) scanNumber() bool {
|
||||
digits := "0123456789_"
|
||||
// Is it hex?
|
||||
l.accept(digits)
|
||||
l.acceptRun(digits + "_")
|
||||
if l.accept("0") {
|
||||
// Note: Leading 0 does not mean octal in floats.
|
||||
if l.accept("xX") {
|
||||
digits = "0123456789abcdefABCDEF_"
|
||||
} else if l.accept("oO") {
|
||||
digits = "01234567_"
|
||||
} else if l.accept("bB") {
|
||||
digits = "01_"
|
||||
}
|
||||
}
|
||||
l.acceptRun(digits)
|
||||
if l.accept(".") {
|
||||
// Lookup for .. operator: if after dot there is another dot (1..2), it maybe a range operator.
|
||||
if l.peek() == '.' {
|
||||
@@ -64,7 +72,6 @@ func (l *lexer) scanNumber() bool {
|
||||
return true
|
||||
}
|
||||
l.accept(digits)
|
||||
l.acceptRun(digits + "_")
|
||||
}
|
||||
if l.accept("eE") {
|
||||
l.accept("+-")
|
||||
@@ -87,7 +94,7 @@ func operator(l *lexer) stateFn {
|
||||
|
||||
func dot(l *lexer) stateFn {
|
||||
l.next()
|
||||
if l.accept(digits) {
|
||||
if l.accept("0123456789") {
|
||||
l.backup()
|
||||
return number
|
||||
}
|
||||
@@ -28,3 +28,19 @@ func (t Token) String() string {
|
||||
}
|
||||
return fmt.Sprintf("%s(%#v)", t.Kind, t.Value)
|
||||
}
|
||||
|
||||
func (t Token) Is(kind Kind, values ...string) bool {
|
||||
if len(values) == 0 {
|
||||
return kind == t.Kind
|
||||
}
|
||||
|
||||
for _, v := range values {
|
||||
if v == t.Value {
|
||||
goto found
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
found:
|
||||
return kind == t.Kind
|
||||
}
|
||||
+390
-327
@@ -1,400 +1,463 @@
|
||||
package parser
|
||||
|
||||
//go:generate antlr -Dlanguage=Go -listener -visitor -o gen -package gen Expr.g4
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/antonmedv/expr/parser2/lexer"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
"github.com/antonmedv/expr/ast"
|
||||
. "github.com/antonmedv/expr/ast"
|
||||
"github.com/antonmedv/expr/file"
|
||||
"github.com/antonmedv/expr/parser/gen"
|
||||
. "github.com/antonmedv/expr/parser/lexer"
|
||||
)
|
||||
|
||||
type associativity int
|
||||
|
||||
const (
|
||||
left associativity = iota + 1
|
||||
right
|
||||
)
|
||||
|
||||
type operator struct {
|
||||
precedence int
|
||||
associativity associativity
|
||||
}
|
||||
|
||||
var unaryOperators = map[string]operator{
|
||||
"not": {50, left},
|
||||
"!": {50, left},
|
||||
"-": {500, left},
|
||||
"+": {500, left},
|
||||
}
|
||||
|
||||
var binaryOperators = map[string]operator{
|
||||
"or": {10, left},
|
||||
"||": {10, left},
|
||||
"and": {15, left},
|
||||
"&&": {15, left},
|
||||
"==": {20, left},
|
||||
"!=": {20, left},
|
||||
"<": {20, left},
|
||||
">": {20, left},
|
||||
">=": {20, left},
|
||||
"<=": {20, left},
|
||||
"not in": {20, left},
|
||||
"in": {20, left},
|
||||
"matches": {20, left},
|
||||
"contains": {20, left},
|
||||
"startsWith": {20, left},
|
||||
"endsWith": {20, left},
|
||||
"..": {25, left},
|
||||
"+": {30, left},
|
||||
"-": {30, left},
|
||||
"*": {60, left},
|
||||
"/": {60, left},
|
||||
"%": {60, left},
|
||||
"**": {70, right},
|
||||
}
|
||||
|
||||
var builtins = map[string]bool{
|
||||
"len": true,
|
||||
"all": true,
|
||||
"none": true,
|
||||
"any": true,
|
||||
"one": true,
|
||||
"filter": true,
|
||||
"map": true,
|
||||
}
|
||||
|
||||
type parser struct {
|
||||
tokens []Token
|
||||
current Token
|
||||
pos int
|
||||
err *file.Error
|
||||
}
|
||||
|
||||
type Tree struct {
|
||||
Node ast.Node
|
||||
Node Node
|
||||
Source *file.Source
|
||||
}
|
||||
|
||||
func Parse(input string) (*Tree, error) {
|
||||
source := file.NewSource(input)
|
||||
is := antlr.NewInputStream(input)
|
||||
|
||||
lexer := gen.NewExprLexer(is)
|
||||
stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||
expr := gen.NewExprParser(stream)
|
||||
tokens, err := Lex(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := &parser{
|
||||
errors: file.NewErrors(source),
|
||||
tokens: tokens,
|
||||
current: tokens[0],
|
||||
}
|
||||
|
||||
lexer.RemoveErrorListeners()
|
||||
expr.RemoveErrorListeners()
|
||||
lexer.AddErrorListener(p)
|
||||
expr.AddErrorListener(p)
|
||||
node := p.parseExpression(0)
|
||||
|
||||
antlr.ParseTreeWalkerDefault.Walk(p, expr.Start())
|
||||
if !p.isEOF() {
|
||||
p.error("unexpected token %v", p.current)
|
||||
}
|
||||
|
||||
if p.errors.HasError() {
|
||||
return nil, fmt.Errorf("%v", p.errors.First())
|
||||
}
|
||||
if len(p.stack) == 0 {
|
||||
return nil, fmt.Errorf("empty stack")
|
||||
}
|
||||
if len(p.stack) > 1 {
|
||||
return nil, fmt.Errorf("too long stack")
|
||||
if p.err != nil {
|
||||
return nil, p.err.Format(source)
|
||||
}
|
||||
|
||||
return &Tree{
|
||||
Node: p.stack[0],
|
||||
Node: node,
|
||||
Source: source,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type parser struct {
|
||||
*gen.BaseExprListener
|
||||
stack []ast.Node
|
||||
errors *file.Errors
|
||||
closure bool
|
||||
func (p *parser) error(format string, args ...interface{}) {
|
||||
if p.err == nil { // show first error
|
||||
p.err = &file.Error{
|
||||
Location: p.current.Location,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) push(node ast.Node) ast.Node {
|
||||
p.stack = append(p.stack, node)
|
||||
return node
|
||||
func (p *parser) next() {
|
||||
p.pos++
|
||||
if p.pos >= len(p.tokens) {
|
||||
panic("unexpected end of expression")
|
||||
}
|
||||
p.current = p.tokens[p.pos]
|
||||
}
|
||||
|
||||
func (p *parser) pop(ctx antlr.ParserRuleContext, it ...string) ast.Node {
|
||||
if len(p.stack) == 0 {
|
||||
if len(it) == 0 {
|
||||
p.reportError(ctx, "parse error: the expression lacks something")
|
||||
func (p *parser) expect(kind Kind, values ...string) {
|
||||
if p.current.Is(kind, values...) {
|
||||
p.next()
|
||||
return
|
||||
}
|
||||
p.error("unexpected token %v", p.current)
|
||||
}
|
||||
|
||||
func (p *parser) isEOF() bool {
|
||||
return p.current.Is(EOF)
|
||||
}
|
||||
|
||||
// parse functions
|
||||
|
||||
func (p *parser) parseExpression(precedence int) Node {
|
||||
nodeLeft := p.parsePrimary()
|
||||
|
||||
token := p.current
|
||||
for token.Is(Operator) {
|
||||
if op, ok := binaryOperators[token.Value]; ok {
|
||||
if op.precedence >= precedence {
|
||||
p.next()
|
||||
|
||||
var nodeRight Node
|
||||
if op.associativity == left {
|
||||
nodeRight = p.parseExpression(op.precedence + 1)
|
||||
} else {
|
||||
nodeRight = p.parseExpression(op.precedence)
|
||||
}
|
||||
|
||||
if token.Is(Operator, "matches") {
|
||||
var r *regexp.Regexp
|
||||
var err error
|
||||
|
||||
if s, ok := nodeRight.(*StringNode); ok {
|
||||
r, err = regexp.Compile(s.Value)
|
||||
if err != nil {
|
||||
p.error("%v", err)
|
||||
}
|
||||
}
|
||||
nodeLeft = &MatchesNode{
|
||||
Base: Loc(token.Location),
|
||||
Regexp: r,
|
||||
Left: nodeLeft,
|
||||
Right: nodeRight,
|
||||
}
|
||||
} else {
|
||||
nodeLeft = &BinaryNode{
|
||||
Base: Loc(token.Location),
|
||||
Operator: token.Value,
|
||||
Left: nodeLeft,
|
||||
Right: nodeRight,
|
||||
}
|
||||
}
|
||||
token = p.current
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if precedence == 0 {
|
||||
nodeLeft = p.parseConditionalExpression(nodeLeft)
|
||||
}
|
||||
|
||||
return nodeLeft
|
||||
}
|
||||
|
||||
func (p *parser) parsePrimary() Node {
|
||||
token := p.current
|
||||
|
||||
if token.Is(Operator) {
|
||||
if op, ok := unaryOperators[token.Value]; ok {
|
||||
p.next()
|
||||
expr := p.parseExpression(op.precedence)
|
||||
return p.parsePostfixExpression(&UnaryNode{
|
||||
Base: Base{Loc: token.Location},
|
||||
Operator: token.Value,
|
||||
Node: expr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if token.Is(Bracket, "(") {
|
||||
p.next()
|
||||
expr := p.parseExpression(0)
|
||||
p.expect(Bracket, ")") // "an opened parenthesis is not properly closed"
|
||||
return p.parsePostfixExpression(expr)
|
||||
}
|
||||
|
||||
return p.parsePrimaryExpression()
|
||||
}
|
||||
|
||||
func (p *parser) parseConditionalExpression(node Node) Node {
|
||||
var expr1, expr2 Node
|
||||
for p.current.Is(Operator, "?") {
|
||||
p.next()
|
||||
|
||||
if !p.current.Is(Operator, ":") {
|
||||
expr1 = p.parseExpression(0)
|
||||
p.expect(Operator, ":")
|
||||
expr2 = p.parseExpression(0)
|
||||
} else {
|
||||
p.reportError(ctx, "parse error: the expression lacks "+strings.Join(it, ", "))
|
||||
p.next()
|
||||
expr1 = node
|
||||
expr2 = p.parseExpression(0)
|
||||
}
|
||||
|
||||
node = &ConditionalNode{
|
||||
Cond: node,
|
||||
Exp1: expr1,
|
||||
Exp2: expr2,
|
||||
}
|
||||
return &ast.NilNode{}
|
||||
}
|
||||
node := p.stack[len(p.stack)-1]
|
||||
p.stack = p.stack[:len(p.stack)-1]
|
||||
return node
|
||||
}
|
||||
|
||||
func (p *parser) reportError(ctx antlr.ParserRuleContext, format string, args ...interface{}) {
|
||||
p.errors.ReportError(location(ctx), format, args...)
|
||||
}
|
||||
func (p *parser) parsePrimaryExpression() Node {
|
||||
var node Node
|
||||
token := p.current
|
||||
|
||||
func (p *parser) EnterIdentifier(ctx *gen.IdentifierContext) {
|
||||
p.push(&ast.IdentifierNode{Value: ctx.GetText()}).SetLocation(location(ctx))
|
||||
}
|
||||
switch token.Kind {
|
||||
|
||||
func (p *parser) EnterPointer(ctx *gen.PointerContext) {
|
||||
p.push(&ast.PointerNode{}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) EnterString(ctx *gen.StringContext) {
|
||||
var value string
|
||||
if s, err := lexer.unescape(ctx.GetText()); err == nil {
|
||||
value = s
|
||||
} else {
|
||||
p.reportError(ctx, "parse error: %v", err)
|
||||
return
|
||||
}
|
||||
node := &ast.StringNode{
|
||||
Value: value,
|
||||
}
|
||||
p.push(node).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) EnterInteger(ctx *gen.IntegerContext) {
|
||||
if node := ctx.IntegerLiteral(); node != nil {
|
||||
text := node.GetText()
|
||||
text = strings.Replace(text, "_", "", -1)
|
||||
i, err := strconv.ParseInt(text, 10, 64)
|
||||
if err != nil {
|
||||
p.reportError(ctx, "parse error: invalid int literal")
|
||||
return
|
||||
case Identifier:
|
||||
p.next()
|
||||
switch token.Value {
|
||||
case "true":
|
||||
return &BoolNode{Base: Loc(token.Location), Value: true}
|
||||
case "false":
|
||||
return &BoolNode{Base: Loc(token.Location), Value: false}
|
||||
case "nil":
|
||||
return &NilNode{Base: Loc(token.Location)}
|
||||
default:
|
||||
node = p.parseIdentifierExpression(token)
|
||||
}
|
||||
p.push(&ast.IntegerNode{Value: int(i)}).SetLocation(location(ctx))
|
||||
} else if node := ctx.HexIntegerLiteral(); node != nil {
|
||||
text := node.GetText()
|
||||
i, err := strconv.ParseInt(text, 0, 64)
|
||||
if err != nil {
|
||||
p.reportError(ctx, "parse error: invalid hex literal")
|
||||
return
|
||||
|
||||
case Number:
|
||||
p.next()
|
||||
value := strings.Replace(token.Value, "_", "", -1)
|
||||
if strings.Contains(value, ".") {
|
||||
number, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
p.error("invalid float literal: %v", err)
|
||||
}
|
||||
return &FloatNode{Base: Loc(token.Location), Value: number}
|
||||
} else if strings.Contains(value, "x") {
|
||||
number, err := strconv.ParseInt(value, 0, 64)
|
||||
if err != nil {
|
||||
p.error("invalid hex literal: %v", err)
|
||||
}
|
||||
return &IntegerNode{Base: Loc(token.Location), Value: int(number)}
|
||||
} else {
|
||||
number, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
p.error("invalid integer literal: %v", err)
|
||||
}
|
||||
return &IntegerNode{Base: Loc(token.Location), Value: int(number)}
|
||||
}
|
||||
p.push(&ast.IntegerNode{Value: int(i)}).SetLocation(location(ctx))
|
||||
} else {
|
||||
p.reportError(ctx, "parse error: invalid octal literal")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) EnterFloat(ctx *gen.FloatContext) {
|
||||
f, err := strconv.ParseFloat(ctx.GetText(), 64)
|
||||
if err != nil {
|
||||
p.reportError(ctx, "parse error: invalid float literal")
|
||||
return
|
||||
}
|
||||
p.push(&ast.FloatNode{Value: f}).SetLocation(location(ctx))
|
||||
}
|
||||
case String:
|
||||
p.next()
|
||||
return &StringNode{Base: Loc(token.Location), Value: token.Value}
|
||||
|
||||
func (p *parser) EnterBoolean(ctx *gen.BooleanContext) {
|
||||
b, err := strconv.ParseBool(ctx.GetText())
|
||||
if err != nil {
|
||||
p.reportError(ctx, "parse error: invalid boolean literal")
|
||||
return
|
||||
}
|
||||
p.push(&ast.BoolNode{Value: b}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) EnterNil(ctx *gen.NilContext) {
|
||||
p.push(&ast.NilNode{}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitUnary(ctx *gen.UnaryContext) {
|
||||
p.push(&ast.UnaryNode{
|
||||
Operator: ctx.GetOp().GetText(),
|
||||
Node: p.pop(ctx),
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitBinary(ctx *gen.BinaryContext) {
|
||||
p.push(&ast.BinaryNode{
|
||||
Operator: ctx.GetOp().GetText(),
|
||||
Right: p.pop(ctx),
|
||||
Left: p.pop(ctx),
|
||||
}).SetLocation(locationToken(ctx.GetOp()))
|
||||
}
|
||||
|
||||
func (p *parser) ExitMatches(ctx *gen.MatchesContext) {
|
||||
right := p.pop(ctx)
|
||||
left := p.pop(ctx)
|
||||
node := &ast.MatchesNode{
|
||||
Right: right,
|
||||
Left: left,
|
||||
}
|
||||
|
||||
var err error
|
||||
var r *regexp.Regexp
|
||||
if s, ok := right.(*ast.StringNode); ok {
|
||||
r, err = regexp.Compile(s.Value)
|
||||
if err != nil {
|
||||
p.reportError(ctx.GetPattern(), "%v", err)
|
||||
return
|
||||
}
|
||||
node.Regexp = r
|
||||
}
|
||||
p.push(node).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitCall(ctx *gen.CallContext) {
|
||||
expr := ctx.GetChild(0)
|
||||
args := ctx.GetArgs()
|
||||
|
||||
var list []gen.IExprContext
|
||||
if args != nil {
|
||||
list = args.GetList()
|
||||
}
|
||||
arguments := p.arguments(ctx, list)
|
||||
|
||||
switch c := expr.(type) {
|
||||
case *gen.IdentifierContext:
|
||||
p.push(&ast.FunctionNode{
|
||||
Arguments: arguments,
|
||||
Name: p.pop(ctx).(*ast.IdentifierNode).Value,
|
||||
}).SetLocation(location(ctx))
|
||||
case *gen.MemberDotContext:
|
||||
p.push(&ast.MethodNode{
|
||||
Arguments: arguments,
|
||||
Method: c.GetName().GetText(),
|
||||
Node: p.pop(ctx).(*ast.PropertyNode).Node,
|
||||
}).SetLocation(location(ctx))
|
||||
default:
|
||||
p.reportError(ctx, "parse error: undefined call expression")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) arguments(ctx antlr.ParserRuleContext, list []gen.IExprContext) []ast.Node {
|
||||
args := make([]ast.Node, 0)
|
||||
for range list {
|
||||
args = append([]ast.Node{p.pop(ctx)}, args...)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func (p *parser) ExitMemberIndex(ctx *gen.MemberIndexContext) {
|
||||
p.push(&ast.IndexNode{
|
||||
Index: p.pop(ctx),
|
||||
Node: p.pop(ctx),
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitSlice(ctx *gen.SliceContext) {
|
||||
var a, b ast.Node
|
||||
if ctx.GetB() != nil {
|
||||
b = p.pop(ctx)
|
||||
}
|
||||
if ctx.GetA() != nil {
|
||||
a = p.pop(ctx)
|
||||
}
|
||||
node := p.pop(ctx)
|
||||
p.push(&ast.SliceNode{
|
||||
Node: node,
|
||||
From: a,
|
||||
To: b,
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitMemberDot(ctx *gen.MemberDotContext) {
|
||||
var property string
|
||||
name := ctx.GetName()
|
||||
if name != nil {
|
||||
property = name.GetText()
|
||||
}
|
||||
p.push(&ast.PropertyNode{
|
||||
Node: p.pop(ctx),
|
||||
Property: property,
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitTernary(ctx *gen.TernaryContext) {
|
||||
expr2 := p.pop(ctx)
|
||||
expr1 := p.pop(ctx)
|
||||
cond := p.pop(ctx)
|
||||
p.push(&ast.ConditionalNode{
|
||||
Exp2: expr2,
|
||||
Exp1: expr1,
|
||||
Cond: cond,
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitArrayLiteral(ctx *gen.ArrayLiteralContext) {
|
||||
list := ctx.GetList()
|
||||
nodes := make([]ast.Node, 0)
|
||||
for range list {
|
||||
nodes = append([]ast.Node{p.pop(ctx)}, nodes...)
|
||||
}
|
||||
p.push(&ast.ArrayNode{Nodes: nodes}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitMapLiteral(ctx *gen.MapLiteralContext) {
|
||||
e := ctx.GetE()
|
||||
if e == nil {
|
||||
p.push(&ast.MapNode{}).SetLocation(location(ctx))
|
||||
return
|
||||
}
|
||||
|
||||
nodes := make([]ast.Node, 0)
|
||||
for range e.GetList() {
|
||||
nodes = append([]ast.Node{p.pop(ctx).(*ast.PairNode)}, nodes...)
|
||||
}
|
||||
p.push(&ast.MapNode{Pairs: nodes}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitPropertyAssignment(ctx *gen.PropertyAssignmentContext) {
|
||||
value := p.pop(ctx)
|
||||
name := ctx.GetName().(*gen.PropertyNameContext)
|
||||
|
||||
var s string
|
||||
if id := name.Identifier(); id != nil {
|
||||
s = id.GetText()
|
||||
} else if str := name.StringLiteral(); str != nil {
|
||||
s2, err := lexer.unescape(str.GetText())
|
||||
if err != nil {
|
||||
p.reportError(ctx, "parse error: %v", err)
|
||||
return
|
||||
if token.Is(Bracket, "[") {
|
||||
node = p.parseArrayExpression(token)
|
||||
} else if token.Is(Bracket, "{") {
|
||||
node = p.parseMapExpression(token)
|
||||
} else {
|
||||
p.error("unexpected token %v", token)
|
||||
}
|
||||
}
|
||||
|
||||
return p.parsePostfixExpression(node)
|
||||
}
|
||||
|
||||
func (p *parser) parseIdentifierExpression(token Token) Node {
|
||||
var node Node
|
||||
if p.current.Is(Bracket, "(") {
|
||||
arguments := p.parseArguments()
|
||||
if _, ok := builtins[token.Value]; ok {
|
||||
node = &BuiltinNode{Base: Loc(token.Location), Name: token.Value, Arguments: arguments}
|
||||
} else {
|
||||
node = &FunctionNode{Base: Loc(token.Location), Name: token.Value, Arguments: arguments}
|
||||
}
|
||||
s = s2
|
||||
} else {
|
||||
p.reportError(ctx, "parse error: invalid key type")
|
||||
return
|
||||
node = &IdentifierNode{Base: Loc(token.Location), Value: token.Value}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (p *parser) parseArrayExpression(token Token) Node {
|
||||
nodes := p.parseList("[", "]")
|
||||
return &ArrayNode{Base: Loc(token.Location), Nodes: nodes}
|
||||
}
|
||||
|
||||
func (p *parser) parseMapExpression(token Token) Node {
|
||||
p.expect(Bracket, "{")
|
||||
|
||||
nodes := make([]Node, 0)
|
||||
for !p.current.Is(Bracket, "}") {
|
||||
if len(nodes) > 0 {
|
||||
p.expect(Operator, ",")
|
||||
}
|
||||
|
||||
var key Node
|
||||
// a map key can be:
|
||||
// * a number
|
||||
// * a string
|
||||
// * a identifier, which is equivalent to a string
|
||||
// * an expression, which must be enclosed in parentheses -- (1 + 2)
|
||||
if p.current.Is(Number) || p.current.Is(String) || p.current.Is(Identifier) {
|
||||
key = &StringNode{Base: Loc(token.Location), Value: p.current.Value}
|
||||
p.next()
|
||||
} else if p.current.Is(Bracket, "(") {
|
||||
key = p.parseExpression(0)
|
||||
} else {
|
||||
p.error("a map key must be a quoted string, a number, a identifier, or an expression enclosed in parentheses (unexpected token %v)", p.current)
|
||||
}
|
||||
|
||||
p.expect(Operator, ":")
|
||||
|
||||
node := p.parseExpression(0)
|
||||
nodes = append(nodes, &PairNode{Base: Loc(token.Location), Key: key, Value: node})
|
||||
}
|
||||
|
||||
key := &ast.StringNode{Value: s}
|
||||
key.SetLocation(location(ctx))
|
||||
p.expect(Bracket, "}")
|
||||
|
||||
p.push(&ast.PairNode{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}).SetLocation(location(ctx))
|
||||
return &MapNode{Base: Loc(token.Location), Pairs: nodes}
|
||||
}
|
||||
|
||||
func (p *parser) ExitBuiltinLen(ctx *gen.BuiltinLenContext) {
|
||||
name := ctx.GetName().GetText()
|
||||
node := p.pop(ctx.GetE())
|
||||
func (p *parser) parsePostfixExpression(node Node) Node {
|
||||
token := p.current
|
||||
for token.Is(Operator) || token.Is(Bracket) {
|
||||
if token.Value == "." {
|
||||
p.next()
|
||||
|
||||
p.push(&ast.BuiltinNode{
|
||||
Name: name,
|
||||
Arguments: []ast.Node{node},
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
token = p.current
|
||||
p.next()
|
||||
|
||||
func (p *parser) ExitBuiltin(ctx *gen.BuiltinContext) {
|
||||
name := ctx.GetName().GetText()
|
||||
closure := p.pop(ctx.GetC())
|
||||
node := p.pop(ctx.GetE())
|
||||
if token.Kind != Identifier &&
|
||||
// Operators like "not" and "matches" are valid method or property names,
|
||||
//
|
||||
// In other words, besides name token kind, operator kind could also be parsed as a property or method.
|
||||
// This is because operators are processed by the lexer prior to names. So "not" in "foo.not()"
|
||||
// or "matches" in "foo.matches" will be recognized as an operator first. But in fact, "not"
|
||||
// and "matches" in such expressions shall be parsed as method or property names.
|
||||
//
|
||||
// And this ONLY works if the operator consists of valid characters for a property or method name.
|
||||
//
|
||||
// Other types, such as text kind and number kind, can't be parsed as property nor method names.
|
||||
//
|
||||
// As a result, if token is NOT an operator OR token.value is NOT a valid property or method name,
|
||||
// an error shall be returned.
|
||||
(token.Kind != Operator || !isValidIdentifier(token.Value)) {
|
||||
p.error("expected name")
|
||||
}
|
||||
|
||||
p.push(&ast.BuiltinNode{
|
||||
Name: name,
|
||||
Arguments: []ast.Node{node, closure},
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
if p.current.Is(Bracket, "(") {
|
||||
arguments := p.parseArguments()
|
||||
node = &MethodNode{
|
||||
Base: Loc(token.Location),
|
||||
Node: node,
|
||||
Method: token.Value,
|
||||
Arguments: arguments,
|
||||
}
|
||||
} else {
|
||||
node = &PropertyNode{
|
||||
Base: Loc(token.Location),
|
||||
Node: node,
|
||||
Property: token.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) EnterClosure(ctx *gen.ClosureContext) {
|
||||
p.closure = true
|
||||
}
|
||||
} else if token.Value == "[" {
|
||||
p.next()
|
||||
arg := p.parseExpression(0)
|
||||
node = &IndexNode{
|
||||
Base: Loc(token.Location),
|
||||
Node: node,
|
||||
Index: arg,
|
||||
}
|
||||
p.expect(Bracket, "]")
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
||||
func (p *parser) ExitClosure(ctx *gen.ClosureContext) {
|
||||
p.closure = false
|
||||
p.push(&ast.ClosureNode{
|
||||
Node: p.pop(ctx),
|
||||
}).SetLocation(location(ctx))
|
||||
}
|
||||
|
||||
func (p *parser) ExitClosureMemberDot(ctx *gen.ClosureMemberDotContext) {
|
||||
if !p.closure {
|
||||
p.reportError(ctx, "parse error: dot property accessor can be only inside closure")
|
||||
return
|
||||
token = p.current
|
||||
}
|
||||
var property string
|
||||
name := ctx.GetName()
|
||||
if name != nil {
|
||||
property = name.GetText()
|
||||
return node
|
||||
}
|
||||
|
||||
func isValidIdentifier(str string) bool {
|
||||
if len(str) == 0 {
|
||||
return false
|
||||
}
|
||||
pointer := &ast.PointerNode{}
|
||||
pointer.SetLocation(location(ctx))
|
||||
p.push(&ast.PropertyNode{
|
||||
Node: pointer,
|
||||
Property: property,
|
||||
}).SetLocation(location(ctx))
|
||||
h, w := utf8.DecodeRuneInString(str)
|
||||
if !isAlphabetic(h) {
|
||||
return false
|
||||
}
|
||||
for _, r := range str[w:] {
|
||||
if !isAlphaNumeric(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *parser) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
|
||||
p.errors.ReportError(file.Location{Line: line, Column: column}, fmt.Sprintf("syntax error: %s", msg))
|
||||
func isAlphaNumeric(r rune) bool {
|
||||
return isAlphabetic(r) || unicode.IsDigit(r)
|
||||
}
|
||||
|
||||
func (p *parser) ReportAmbiguity(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ bool, _ *antlr.BitSet, _ antlr.ATNConfigSet) {
|
||||
func isAlphabetic(r rune) bool {
|
||||
return r == '_' || unicode.IsLetter(r)
|
||||
}
|
||||
|
||||
func (p *parser) ReportAttemptingFullContext(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ *antlr.BitSet, _ antlr.ATNConfigSet) {
|
||||
func (p *parser) parseArguments() []Node {
|
||||
return p.parseList("(", ")")
|
||||
}
|
||||
|
||||
func (p *parser) ReportContextSensitivity(_ antlr.Parser, _ *antlr.DFA, _, _, _ int, _ antlr.ATNConfigSet) {
|
||||
}
|
||||
func (p *parser) parseList(start, end string) []Node {
|
||||
p.expect(Bracket, start)
|
||||
|
||||
func location(ctx antlr.ParserRuleContext) file.Location {
|
||||
if ctx == nil {
|
||||
return file.Location{Line: 0, Column: 0}
|
||||
nodes := make([]Node, 0)
|
||||
for !p.current.Is(Bracket, end) {
|
||||
if len(nodes) > 0 {
|
||||
p.expect(Operator, ",")
|
||||
}
|
||||
node := p.parseExpression(0)
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
|
||||
token := ctx.GetStart()
|
||||
if token == nil {
|
||||
return file.Location{Line: 0, Column: 0}
|
||||
}
|
||||
|
||||
return file.Location{Line: token.GetLine(), Column: token.GetColumn()}
|
||||
}
|
||||
|
||||
func locationToken(token antlr.Token) file.Location {
|
||||
return file.Location{Line: token.GetLine(), Column: token.GetColumn()}
|
||||
p.expect(Bracket, end)
|
||||
return nodes
|
||||
}
|
||||
|
||||
+5
-14
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/antonmedv/expr/ast"
|
||||
"github.com/antonmedv/expr/parser"
|
||||
"github.com/sanity-io/litter"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -21,16 +20,8 @@ func TestParse(t *testing.T) {
|
||||
&ast.IdentifierNode{Value: "a"},
|
||||
},
|
||||
{
|
||||
`"\"double\""`,
|
||||
&ast.StringNode{Value: "\"double\""},
|
||||
},
|
||||
{
|
||||
`'\'single\\ \''`,
|
||||
&ast.StringNode{Value: "'single\\ '"},
|
||||
},
|
||||
{
|
||||
`"\xC3\XBF\u263A\U000003A8\?"`,
|
||||
&ast.StringNode{Value: "ÿ☺Ψ?"},
|
||||
`"str"`,
|
||||
&ast.StringNode{Value: "str"},
|
||||
},
|
||||
{
|
||||
"3",
|
||||
@@ -42,7 +33,7 @@ func TestParse(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"10_000_000",
|
||||
&ast.IntegerNode{Value: 10000000},
|
||||
&ast.IntegerNode{Value: 10_000_000},
|
||||
},
|
||||
{
|
||||
"2.5",
|
||||
@@ -54,7 +45,7 @@ func TestParse(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"false",
|
||||
&ast.BoolNode{},
|
||||
&ast.BoolNode{Value: false},
|
||||
},
|
||||
{
|
||||
"nil",
|
||||
@@ -210,7 +201,7 @@ func TestParse(t *testing.T) {
|
||||
m.Regexp = nil
|
||||
actual.Node = m
|
||||
}
|
||||
assert.Equal(t, litter.Sdump(test.expected), litter.Sdump(actual.Node), test.input)
|
||||
assert.Equal(t, ast.Print(test.expected), ast.Print(actual.Node), test.input)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user