several changes:

1. moved scan/symbol.go to new package sym and adapted all files that reference Symbol type and its values.
2. new type interval defined by begin, end and step values.
3. replaced operator-range.go with operator-interval.go.
4. replaced range operator begin:end with begin..end..step.
5. new implementation of sub-collection extraction based on new interval literal.
This commit is contained in:
2026-07-27 16:01:52 +02:00
parent 07aecfc4e7
commit 8e596d5979
63 changed files with 1125 additions and 755 deletions
+118 -110
View File
@@ -10,6 +10,7 @@ import (
"slices"
"git.portale-stac.it/go-pkg/expr/scan"
"git.portale-stac.it/go-pkg/expr/sym"
"golang.org/x/exp/constraints"
)
@@ -58,7 +59,7 @@ func NewParser() (p *parser) {
}
func (parser *parser) Next(scanner *scan.Scanner) (tk *scan.Token) {
for tk = scanner.Next(); tk.IsSymbol(scan.SymComment); tk = scanner.Next() {
for tk = scanner.Next(); tk.IsSymbol(sym.SymComment); tk = scanner.Next() {
}
return
}
@@ -66,10 +67,10 @@ func (parser *parser) Next(scanner *scan.Scanner) (tk *scan.Token) {
func (parser *parser) parseFuncCall(scanner *scan.Scanner, ctx parserContext, tk *scan.Token) (tree *scan.Term, err error) {
args := make([]*scan.Term, 0, 10)
itemExpected := false
lastSym := scan.SymUnknown
for lastSym != scan.SymClosedRound && lastSym != scan.SymEos {
lastSym := sym.SymUnknown
for lastSym != sym.SymClosedRound && lastSym != sym.SymEos {
var subTree *scan.Ast
if subTree, err = parser.parseItem(scanner, ctx, scan.SymComma, scan.SymClosedRound); err != nil {
if subTree, err = parser.parseItem(scanner, ctx, sym.SymComma, sym.SymClosedRound); err != nil {
break
}
prev := scanner.Previous()
@@ -80,11 +81,11 @@ func (parser *parser) parseFuncCall(scanner *scan.Scanner, ctx parserContext, tk
break
}
itemExpected = prev.Sym == scan.SymComma
itemExpected = prev.Sym == sym.SymComma
lastSym = scanner.Previous().Sym
}
if err == nil {
if lastSym != scan.SymClosedRound {
if lastSym != sym.SymClosedRound {
err = errors.New("unterminated arguments list")
} else {
tree = newFuncCallTerm(tk, args)
@@ -97,13 +98,13 @@ func (parser *parser) parseFuncDef(scanner *scan.Scanner) (tree *scan.Term, err
// Example: "add = func(x,y) {x+y}
var body *scan.Ast
args := make([]*scan.Term, 0)
lastSym := scan.SymUnknown
lastSym := sym.SymUnknown
defaultParamsStarted := false
itemExpected := false
tk := scanner.Previous()
for lastSym != scan.SymClosedRound && lastSym != scan.SymEos {
for lastSym != sym.SymClosedRound && lastSym != sym.SymEos {
tk = parser.Next(scanner)
if tk.IsSymbol(scan.SymIdentifier) {
if tk.IsSymbol(sym.SymIdentifier) {
param := scan.NewTerm(tk)
if len(args) > 0 {
if pos := paramAlreadyDefined(args, param); pos > 0 {
@@ -113,10 +114,10 @@ func (parser *parser) parseFuncDef(scanner *scan.Scanner) (tree *scan.Term, err
}
args = append(args, param)
tk = parser.Next(scanner)
if tk.Sym == scan.SymEqual {
if tk.Sym == sym.SymEqual {
var paramExpr *scan.Ast
defaultParamsStarted = true
if paramExpr, err = parser.parseItem(scanner, parserNoFlags, scan.SymComma, scan.SymClosedRound); err != nil {
if paramExpr, err = parser.parseItem(scanner, parserNoFlags, sym.SymComma, sym.SymClosedRound); err != nil {
break
}
param.ForceChild(paramExpr.Root())
@@ -130,25 +131,25 @@ func (parser *parser) parseFuncDef(scanner *scan.Scanner) (tree *scan.Term, err
break
}
lastSym = scanner.Previous().Sym
itemExpected = lastSym == scan.SymComma
itemExpected = lastSym == sym.SymComma
}
if err == nil && lastSym != scan.SymClosedRound {
if err == nil && lastSym != sym.SymClosedRound {
err = tk.ErrorExpectedGot(")")
}
if err == nil {
tk = parser.Next(scanner)
if tk.IsSymbol(scan.SymOpenBrace) {
body, err = parser.parseGeneral(scanner, allowMultiExpr|allowVarRef, scan.SymClosedBrace)
if tk.IsSymbol(sym.SymOpenBrace) {
body, err = parser.parseGeneral(scanner, allowMultiExpr|allowVarRef, sym.SymClosedBrace)
} else {
err = tk.ErrorExpectedGot("{")
}
}
if err == nil {
if scanner.Previous().Sym != scan.SymClosedBrace {
if scanner.Previous().Sym != sym.SymClosedBrace {
err = scanner.Previous().ErrorExpectedGot("}")
} else {
tk = scanner.MakeValueToken(scan.SymExpression, "", body)
tk = scanner.MakeValueToken(sym.SymExpression, "", body)
tree = newFuncDefTerm(tk, args)
}
}
@@ -165,40 +166,40 @@ func paramAlreadyDefined(args []*scan.Term, param *scan.Term) (position int) {
return
}
func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext, termSym scan.Symbol) (listTerm *scan.Term, err error) {
func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext, termSym sym.Symbol) (listTerm *scan.Term, err error) {
r, c := scanner.LastPos()
args := make([]*scan.Term, 0)
lastSym := scan.SymUnknown
lastSym := sym.SymUnknown
itemExpected := false
itemCtx := remFlags(ctx, allowIndex)
for lastSym != termSym && lastSym != scan.SymEos {
zeroRequired := scanner.Current().Sym == scan.SymColon
for lastSym != termSym && lastSym != sym.SymEos {
// zeroRequired := scanner.Current().Sym == sym.SymDoubleDot
var itemTree *scan.Ast
if itemTree, err = parser.parseItem(scanner, itemCtx, scan.SymComma, termSym); err == nil {
if itemTree, err = parser.parseItem(scanner, itemCtx, sym.SymComma, termSym); err == nil {
root := itemTree.Root()
if root != nil {
if hasFlag(ctx, allowIndex) && root.Symbol() == scan.SymColon {
changeColonToRange(root)
if hasFlag(ctx, allowIndex) && root.Symbol() == sym.SymDoubleDot {
changeColonToInterval(root)
}
if !hasFlag(ctx, allowIndex) && root.Symbol() == scan.SymRange {
if !hasFlag(ctx, allowIndex) && root.Symbol() == sym.SymInterval {
// err = root.Errorf("unexpected range expression")
err = errRangeUnexpectedExpression(root)
err = errIntervalUnexpectedExpression(root)
break
}
args = append(args, root)
if hasFlag(ctx, allowIndex) && root.Symbol() == scan.SymRange && zeroRequired { //len(root.children) == 0 {
if len(root.Children) == 1 {
root.Children = append(root.Children, root.Children[0])
} else if len(root.Children) > 1 {
// err = root.Errorf("invalid range specification")
err = errRangeInvalidSpecification(root)
break
}
zeroTk := scan.NewValueToken(root.Tk.Row(), root.Tk.Col(), scan.SymInteger, "0", int64(0))
zeroTerm := scan.NewTerm(zeroTk)
zeroTerm.SetParent(root)
root.Children[0] = zeroTerm
}
// if hasFlag(ctx, allowIndex) && root.Symbol() == sym.SymInterval && zeroRequired { //len(root.children) == 0 {
// if len(root.Children) == 1 {
// root.Children = append(root.Children, root.Children[0])
// } else if len(root.Children) > 1 {
// // err = root.Errorf("invalid range specification")
// err = errIntervalInvalidSpecification(root)
// break
// }
// zeroTk := scan.NewValueToken(root.Tk.Row(), root.Tk.Col(), sym.SymInteger, "0", int64(0))
// zeroTerm := scan.NewTerm(zeroTk)
// zeroTerm.SetParent(root)
// root.Children[0] = zeroTerm
// }
} else if itemExpected {
prev := scanner.Previous()
err = prev.ErrorExpectedGot("list-item")
@@ -208,16 +209,16 @@ func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext, termSy
break
}
lastSym = scanner.Previous().Sym
if itemExpected = lastSym == scan.SymComma; itemExpected {
if itemExpected = lastSym == sym.SymComma; itemExpected {
remFlags(ctx, allowIndex)
}
}
if err == nil {
if lastSym != termSym {
err = scanner.Previous().ErrorExpectedGot("]")
} else if termSym == scan.SymClosedSquare {
} else if termSym == sym.SymClosedSquare {
listTerm = newListTerm(r, c, args)
} else if termSym == scan.SymGreaterClosedSquare {
} else if termSym == sym.SymGreaterClosedSquare {
listTerm = newLinkedListTerm(r, c, args)
} else {
err = fmt.Errorf("[%d:%d] unknown list type", r, c)
@@ -229,11 +230,11 @@ func (parser *parser) parseList(scanner *scan.Scanner, ctx parserContext, termSy
func (parser *parser) parseIterDef(scanner *scan.Scanner, ctx parserContext) (subtree *scan.Term, err error) {
tk := scanner.Previous()
args := make([]*scan.Term, 0)
lastSym := scan.SymUnknown
lastSym := sym.SymUnknown
itemExpected := false
for lastSym != scan.SymClosedRound && lastSym != scan.SymEos {
for lastSym != sym.SymClosedRound && lastSym != sym.SymEos {
var subTree *scan.Ast
if subTree, err = parser.parseItem(scanner, ctx, scan.SymComma, scan.SymClosedRound); err == nil {
if subTree, err = parser.parseItem(scanner, ctx, sym.SymComma, sym.SymClosedRound); err == nil {
if subTree.Root() != nil {
args = append(args, subTree.Root())
} else if itemExpected {
@@ -245,10 +246,10 @@ func (parser *parser) parseIterDef(scanner *scan.Scanner, ctx parserContext) (su
break
}
lastSym = scanner.Previous().Sym
itemExpected = lastSym == scan.SymComma
itemExpected = lastSym == sym.SymComma
}
if err == nil {
if lastSym != scan.SymClosedRound {
if lastSym != sym.SymClosedRound {
err = scanner.Previous().ErrorExpectedGot(")")
} else {
subtree = newIteratorTerm(tk, args)
@@ -259,16 +260,16 @@ func (parser *parser) parseIterDef(scanner *scan.Scanner, ctx parserContext) (su
// func (parser *parser) parseDictKey(scanner *scan.Scanner) (key any, err error) {
// tk := parser.Next(scanner)
// if tk.Sym == scan.SymError {
// if tk.Sym == sym.SymError {
// err = tk.Error()
// return
// }
// if tk.Sym == scan.SymClosedBrace || tk.Sym == scan.SymEos {
// if tk.Sym == sym.SymClosedBrace || tk.Sym == sym.SymEos {
// return
// }
// if tk.Sym == scan.SymInteger || tk.Sym == scan.SymString || tk.Sym == scan.SymIdentifier {
// if tk.Sym == sym.SymInteger || tk.Sym == sym.SymString || tk.Sym == sym.SymIdentifier {
// tkSep := parser.Next(scanner)
// if tkSep.Sym != scan.SymColon {
// if tkSep.Sym != sym.SymColon {
// err = tkSep.ErrorExpectedGot(":")
// } else {
// key = tk.Value
@@ -281,15 +282,15 @@ func (parser *parser) parseIterDef(scanner *scan.Scanner, ctx parserContext) (su
func (parser *parser) parseDictKey(scanner *scan.Scanner) (key *scan.Term, err error) {
var keyTree *scan.Ast
if keyTree, err = parser.parseItem(scanner, parserNoFlags, scan.SymColon, scan.SymClosedBrace); err == nil {
if keyTree, err = parser.parseItem(scanner, parserNoFlags, sym.SymColon, sym.SymClosedBrace); err == nil {
key = keyTree.Root()
tkSep := scanner.Previous()
sym := tkSep.Sym
if sym == scan.SymClosedBrace || sym == scan.SymEos {
symbol := tkSep.Sym
if symbol == sym.SymClosedBrace || symbol == sym.SymEos {
if key != nil {
err = tkSep.ErrorExpectedGot(":")
}
} else if sym != scan.SymColon {
} else if symbol != sym.SymColon {
err = tkSep.ErrorExpectedGot(":")
}
}
@@ -298,9 +299,9 @@ func (parser *parser) parseDictKey(scanner *scan.Scanner) (key *scan.Term, err e
func (parser *parser) parseDictionary(scanner *scan.Scanner, ctx parserContext) (subtree *scan.Term, err error) {
args := make(map[any]*scan.Term, 0)
lastSym := scan.SymUnknown
lastSym := sym.SymUnknown
itemExpected := false
for lastSym != scan.SymClosedBrace && lastSym != scan.SymEos {
for lastSym != sym.SymClosedBrace && lastSym != sym.SymEos {
var valueTree *scan.Ast
var key any
if key, err = parser.parseDictKey(scanner); err != nil {
@@ -313,7 +314,7 @@ func (parser *parser) parseDictionary(scanner *scan.Scanner, ctx parserContext)
}
break
}
if valueTree, err = parser.parseItem(scanner, ctx, scan.SymComma, scan.SymClosedBrace); err == nil {
if valueTree, err = parser.parseItem(scanner, ctx, sym.SymComma, sym.SymClosedBrace); err == nil {
if valueTree.Root() != nil {
args[key] = valueTree.Root()
} else /*if key != nil*/ {
@@ -325,10 +326,10 @@ func (parser *parser) parseDictionary(scanner *scan.Scanner, ctx parserContext)
break
}
lastSym = scanner.Previous().Sym
itemExpected = lastSym == scan.SymComma
itemExpected = lastSym == sym.SymComma
}
if err == nil {
if lastSym != scan.SymClosedBrace {
if lastSym != sym.SymClosedBrace {
err = scanner.Previous().ErrorExpectedGot("}")
} else {
subtree = newDictTerm(args)
@@ -344,12 +345,12 @@ func (parser *parser) parseSelectorCase(scanner *scan.Scanner, ctx parserContext
tk := parser.Next(scanner)
startRow := tk.Row()
startCol := tk.Col()
if tk.Sym == scan.SymOpenSquare {
if tk.Sym == sym.SymOpenSquare {
if defaultCase {
err = tk.Errorf("case list in default clause")
return
}
if filterList, err = parser.parseList(scanner, remFlags(ctx, allowIndex), scan.SymClosedSquare); err != nil {
if filterList, err = parser.parseList(scanner, remFlags(ctx, allowIndex), sym.SymClosedSquare); err != nil {
return
}
tk = parser.Next(scanner)
@@ -359,8 +360,8 @@ func (parser *parser) parseSelectorCase(scanner *scan.Scanner, ctx parserContext
filterList = newListTerm(startRow, startCol, make([]*scan.Term, 0))
}
if tk.Sym == scan.SymOpenBrace {
if caseExpr, err = parser.parseGeneral(scanner, ctx|allowMultiExpr, scan.SymClosedBrace); err != nil {
if tk.Sym == sym.SymOpenBrace {
if caseExpr, err = parser.parseGeneral(scanner, ctx|allowMultiExpr, sym.SymClosedBrace); err != nil {
return
}
} else {
@@ -390,7 +391,7 @@ func (parser *parser) parseSelector(scanner *scan.Scanner, tree *scan.Ast, ctx p
var caseTerm *scan.Term
ctx = remFlags(ctx, allowIndex)
tk := scanner.MakeToken(scan.SymSelector, '?')
tk := scanner.MakeToken(sym.SymSelector, '?')
if selectorTerm, err = tree.AddToken(tk); err != nil {
return
}
@@ -401,11 +402,11 @@ func (parser *parser) parseSelector(scanner *scan.Scanner, tree *scan.Ast, ctx p
return
}
func (parser *parser) parseItem(scanner *scan.Scanner, ctx parserContext, termSymbols ...scan.Symbol) (tree *scan.Ast, err error) {
func (parser *parser) parseItem(scanner *scan.Scanner, ctx parserContext, termSymbols ...sym.Symbol) (tree *scan.Ast, err error) {
return parser.parseGeneral(scanner, ctx|allowVarRef, termSymbols...)
}
func (parser *parser) Parse(scanner *scan.Scanner, termSymbols ...scan.Symbol) (tree *scan.Ast, err error) {
func (parser *parser) Parse(scanner *scan.Scanner, termSymbols ...sym.Symbol) (tree *scan.Ast, err error) {
defer func() {
if r := recover(); r != nil {
if errVal, ok := r.(error); ok {
@@ -415,23 +416,23 @@ func (parser *parser) Parse(scanner *scan.Scanner, termSymbols ...scan.Symbol) (
}
}
}()
termSymbols = append(termSymbols, scan.SymEos)
termSymbols = append(termSymbols, sym.SymEos)
return parser.parseGeneral(scanner, allowMultiExpr, termSymbols...)
}
func couldBeACollection(t *scan.Term) bool {
var sym = scan.SymUnknown
var symbol = sym.SymUnknown
if t != nil {
sym = t.Symbol()
symbol = t.Symbol()
}
// return sym == scan.SymList || sym == scan.SymString || sym == scan.SymDict || sym == scan.SymExpression || sym == scan.SymVariable
return slices.Contains([]scan.Symbol{scan.SymList, scan.SymLinkedList, scan.SymString, scan.SymDict, scan.SymExpression, scan.SymVariable, scan.SymIndex}, sym)
// return sym == sym.SymList || sym == sym.SymString || sym == sym.SymDict || sym == sym.SymExpression || sym == sym.SymVariable
return slices.Contains([]sym.Symbol{sym.SymList, sym.SymLinkedList, sym.SymString, sym.SymDict, sym.SymExpression, sym.SymVariable, sym.SymIndex}, symbol)
}
func listSubTree(tree *scan.Ast, listTerm *scan.Term, allowIndeces bool) (root *scan.Term, err error) {
var tk *scan.Token
if allowIndeces {
tk = scan.NewToken(listTerm.Tk.Row(), listTerm.Tk.Col(), scan.SymIndex, listTerm.Source())
tk = scan.NewToken(listTerm.Tk.Row(), listTerm.Tk.Col(), sym.SymIndex, listTerm.Source())
root = scan.NewTerm(tk)
if err = tree.AddTerm(root); err == nil {
err = tree.AddTerm(listTerm)
@@ -445,22 +446,22 @@ func listSubTree(tree *scan.Ast, listTerm *scan.Term, allowIndeces bool) (root *
func changePrefix(tk *scan.Token) {
switch tk.Sym {
case scan.SymMinus:
tk.SetSymbol(scan.SymChangeSign)
case scan.SymPlus:
tk.SetSymbol(scan.SymUnchangeSign)
case scan.SymStar:
tk.SetSymbol(scan.SymDereference)
case scan.SymExclamation:
tk.SetSymbol(scan.SymNot)
case scan.SymDoublePlus:
tk.SetSymbol(scan.SymPreInc)
case scan.SymDoubleMinus:
tk.SetSymbol(scan.SymPreDec)
case sym.SymMinus:
tk.SetSymbol(sym.SymChangeSign)
case sym.SymPlus:
tk.SetSymbol(sym.SymUnchangeSign)
case sym.SymStar:
tk.SetSymbol(sym.SymDereference)
case sym.SymExclamation:
tk.SetSymbol(sym.SymNot)
case sym.SymDoublePlus:
tk.SetSymbol(sym.SymPreInc)
case sym.SymDoubleMinus:
tk.SetSymbol(sym.SymPreDec)
}
}
func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, termSymbols ...scan.Symbol) (tree *scan.Ast, err error) {
func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, termSymbols ...sym.Symbol) (tree *scan.Ast, err error) {
var selectorTerm *scan.Term = nil
var currentTerm *scan.Term = nil
var tk *scan.Token
@@ -473,7 +474,7 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
// continue
// }
if tk.Sym == scan.SymSemiColon {
if tk.Sym == sym.SymSemiColon {
if hasFlag(ctx, allowMultiExpr) {
tree.ToForest()
firstToken = true
@@ -493,9 +494,9 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
}
switch tk.Sym {
case scan.SymOpenRound:
case sym.SymOpenRound:
var subTree *scan.Ast
if subTree, err = parser.parseGeneral(scanner, ctx, scan.SymClosedRound); err == nil {
if subTree, err = parser.parseGeneral(scanner, ctx, sym.SymClosedRound); err == nil {
if subTree.Root() == nil {
err = tk.ErrorExpectedGotString("expression", "()")
} else {
@@ -504,26 +505,26 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
currentTerm = exprTerm
}
}
case scan.SymFuncCall:
case sym.SymFuncCall:
var funcCallTerm *scan.Term
if funcCallTerm, err = parser.parseFuncCall(scanner, ctx, tk); err == nil {
err = tree.AddTerm(funcCallTerm)
currentTerm = funcCallTerm
}
case scan.SymOpenSquare:
case sym.SymOpenSquare:
var listTerm *scan.Term
newCtx := addFlagsCond(addFlags(ctx, squareContext), allowIndex, couldBeACollection(currentTerm))
if listTerm, err = parser.parseList(scanner, newCtx, scan.SymClosedSquare); err == nil {
if listTerm, err = parser.parseList(scanner, newCtx, sym.SymClosedSquare); err == nil {
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
}
case scan.SymOpenSquareLess:
case sym.SymOpenSquareLess:
var listTerm *scan.Term
newCtx := addFlagsCond(addFlags(ctx, listContext), allowIndex, false)
if listTerm, err = parser.parseList(scanner, newCtx, scan.SymGreaterClosedSquare); err == nil {
if listTerm, err = parser.parseList(scanner, newCtx, sym.SymGreaterClosedSquare); err == nil {
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
}
case scan.SymOpenBrace:
if currentTerm != nil && currentTerm.Symbol() == scan.SymColon {
case sym.SymOpenBrace:
if currentTerm != nil && currentTerm.Symbol() == sym.SymColon {
err = currentTerm.Errorf(`selector-case outside of a selector context`)
} else {
var mapTerm *scan.Term
@@ -532,54 +533,61 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
currentTerm = mapTerm
}
}
case scan.SymEqual, scan.SymPlusEqual, scan.SymMinusEqual, scan.SymStarEqual, scan.SymSlashEqual, scan.SymPercEqual, scan.SymAmpersandEqual, scan.SymVertBarEqual, scan.SymDoubleLessEqual, scan.SymDoubleGreaterEqual, scan.SymCaretEqual:
case sym.SymEqual, sym.SymPlusEqual, sym.SymMinusEqual, sym.SymStarEqual, sym.SymSlashEqual, sym.SymPercEqual, sym.SymAmpersandEqual, sym.SymVertBarEqual, sym.SymDoubleLessEqual, sym.SymDoubleGreaterEqual, sym.SymCaretEqual:
currentTerm, err = tree.AddToken(tk)
firstToken = true
case scan.SymFuncDef:
case sym.SymFuncDef:
var funcDefTerm *scan.Term
if funcDefTerm, err = parser.parseFuncDef(scanner); err == nil {
err = tree.AddTerm(funcDefTerm)
currentTerm = funcDefTerm
}
case scan.SymDollarRound:
case sym.SymDollarRound:
var iterDefTerm *scan.Term
if iterDefTerm, err = parser.parseIterDef(scanner, ctx); err == nil {
err = tree.AddTerm(iterDefTerm)
currentTerm = iterDefTerm
}
case scan.SymIdentifier:
case sym.SymIdentifier:
if tk.Source()[0] == '@' && !hasFlag(ctx, allowVarRef) {
err = tk.Errorf("variable references are not allowed in top level expressions: %q", tk.Source())
} else {
currentTerm, err = tree.AddToken(tk)
}
case scan.SymQuestion:
case sym.SymQuestion:
if selectorTerm, err = parser.parseSelector(scanner, tree, ctx); err == nil {
currentTerm = selectorTerm
addFlags(ctx, selectorContext)
}
case scan.SymColon, scan.SymDoubleColon:
case sym.SymColon, sym.SymDoubleColon:
var caseTerm *scan.Term
if selectorTerm != nil {
if caseTerm, err = parser.parseSelectorCase(scanner, ctx, tk.Sym == scan.SymDoubleColon); err == nil {
if caseTerm, err = parser.parseSelectorCase(scanner, ctx, tk.Sym == sym.SymDoubleColon); err == nil {
addSelectorCase(selectorTerm, caseTerm)
currentTerm = caseTerm
if tk.Sym == scan.SymDoubleColon {
if tk.Sym == sym.SymDoubleColon {
selectorTerm = nil
}
}
} else {
// err = tk.Errorf("colon outside a selector context")
currentTerm, err = tree.AddToken(tk)
if tk.IsOneOfA(scan.SymColon, scan.SymRange) {
// Colon outside a selector term acts like a separator
firstToken = true
}
// Colon outside a selector term acts like a separator
firstToken = tk.IsOneOfA(sym.SymColon, sym.SymInterval)
}
case sym.SymDoubleDot:
currentTerm, err = tree.AddToken(tk)
if currentTerm.GetLeftChild() == nil {
zeroTk := scan.NewValueToken(tk.Row(), tk.Col(), sym.SymInteger, "0", int64(0))
tree.AddToken(zeroTk)
}
// Double dot acts like a separator
firstToken = tk.IsOneOfA(sym.SymDoubleDot, sym.SymInterval)
default:
currentTerm, err = tree.AddToken(tk)
}
if currentTerm != nil && currentTerm.Tk.Sym != scan.SymSelector && currentTerm.Parent != nil && currentTerm.Parent.Tk.Sym != scan.SymSelector {
if currentTerm != nil && currentTerm.Tk.Sym != sym.SymSelector && currentTerm.Parent != nil && currentTerm.Parent.Tk.Sym != sym.SymSelector {
selectorTerm = nil
remFlags(ctx, selectorContext)
}
@@ -589,7 +597,7 @@ func (parser *parser) parseGeneral(scanner *scan.Scanner, ctx parserContext, ter
if err == nil {
if !tk.IsOneOf(termSymbols) {
var symDesc string
if tk.IsSymbol(scan.SymError) {
if tk.IsSymbol(sym.SymError) {
symDesc = tk.ErrorText()
} else {
symDesc = scan.SymToString(tk.Sym)