Eprx now supports range of indeces to extract parts of strings or lists
This commit is contained in:
@@ -154,16 +154,34 @@ func (self *parser) parseFuncDef(scanner *scanner) (tree *term, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (self *parser) parseList(scanner *scanner, allowVarRef bool) (subtree *term, err error) {
|
||||
func (self *parser) parseList(scanner *scanner, parsingIndeces bool, allowVarRef bool) (subtree *term, err error) {
|
||||
r, c := scanner.lastPos()
|
||||
args := make([]*term, 0)
|
||||
lastSym := SymUnknown
|
||||
itemExpected := false
|
||||
for lastSym != SymClosedSquare && lastSym != SymEos {
|
||||
var subTree *ast
|
||||
zeroRequired := scanner.current.Sym == SymColon
|
||||
if subTree, err = self.parseItem(scanner, allowVarRef, SymComma, SymClosedSquare); err == nil {
|
||||
if subTree.root != nil {
|
||||
args = append(args, subTree.root)
|
||||
root := subTree.root
|
||||
if root != nil {
|
||||
if !parsingIndeces && root.symbol() == SymColon {
|
||||
err = root.Errorf("unexpected range expression")
|
||||
break
|
||||
}
|
||||
args = append(args, root)
|
||||
if parsingIndeces && root.symbol() == SymColon && 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")
|
||||
break
|
||||
}
|
||||
zeroTk := NewValueToken(root.tk.row, root.tk.col, SymInteger, "0", int64(0))
|
||||
zeroTerm := newTerm(zeroTk)
|
||||
zeroTerm.setParent(root)
|
||||
root.children[0] = zeroTerm
|
||||
}
|
||||
} else if itemExpected {
|
||||
prev := scanner.Previous()
|
||||
err = prev.ErrorExpectedGot("list-item")
|
||||
@@ -176,7 +194,6 @@ func (self *parser) parseList(scanner *scanner, allowVarRef bool) (subtree *term
|
||||
itemExpected = lastSym == SymComma
|
||||
}
|
||||
if err == nil {
|
||||
// TODO Check arguments
|
||||
if lastSym != SymClosedSquare {
|
||||
err = scanner.Previous().ErrorExpectedGot("]")
|
||||
} else {
|
||||
@@ -295,7 +312,7 @@ func (self *parser) parseSelectorCase(scanner *scanner, allowVarRef bool, defaul
|
||||
err = tk.Errorf("case list in default clause")
|
||||
return
|
||||
}
|
||||
if filterList, err = self.parseList(scanner, allowVarRef); err != nil {
|
||||
if filterList, err = self.parseList(scanner, false, allowVarRef); err != nil {
|
||||
return
|
||||
}
|
||||
tk = scanner.Next()
|
||||
@@ -353,6 +370,14 @@ func (self *parser) Parse(scanner *scanner, termSymbols ...Symbol) (tree *ast, e
|
||||
return self.parseGeneral(scanner, true, false, termSymbols...)
|
||||
}
|
||||
|
||||
func couldBeACollection(t *term) bool {
|
||||
var sym = SymUnknown
|
||||
if t != nil {
|
||||
sym = t.symbol()
|
||||
}
|
||||
return sym == SymList || sym == SymString || sym == SymDict || sym == SymExpression || sym == SymVariable
|
||||
}
|
||||
|
||||
func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef bool, termSymbols ...Symbol) (tree *ast, err error) {
|
||||
var selectorTerm *term = nil
|
||||
var currentTerm *term = nil
|
||||
@@ -402,12 +427,9 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
|
||||
}
|
||||
case SymOpenSquare:
|
||||
var listTerm *term
|
||||
if listTerm, err = self.parseList(scanner, allowVarRef); err == nil {
|
||||
var sym = SymUnknown
|
||||
if currentTerm != nil {
|
||||
sym = currentTerm.symbol()
|
||||
}
|
||||
if sym == SymList || sym == SymString || sym == SymDict || sym == SymExpression || sym == SymVariable {
|
||||
parsingIndeces := couldBeACollection(currentTerm)
|
||||
if listTerm, err = self.parseList(scanner, parsingIndeces, allowVarRef); err == nil {
|
||||
if parsingIndeces {
|
||||
indexTk := NewToken(listTerm.tk.row, listTerm.tk.col, SymIndex, listTerm.source())
|
||||
indexTerm := newTerm(indexTk)
|
||||
if err = tree.addTerm(indexTerm); err == nil {
|
||||
@@ -419,10 +441,14 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
|
||||
currentTerm = listTerm
|
||||
}
|
||||
case SymOpenBrace:
|
||||
var mapTerm *term
|
||||
if mapTerm, err = self.parseDictionary(scanner, allowVarRef); err == nil {
|
||||
err = tree.addTerm(mapTerm)
|
||||
currentTerm = mapTerm
|
||||
if currentTerm != nil && currentTerm.symbol() == SymColon {
|
||||
err = currentTerm.Errorf(`selector-case outside of a selector context`)
|
||||
} else {
|
||||
var mapTerm *term
|
||||
if mapTerm, err = self.parseDictionary(scanner, allowVarRef); err == nil {
|
||||
err = tree.addTerm(mapTerm)
|
||||
currentTerm = mapTerm
|
||||
}
|
||||
}
|
||||
case SymEqual:
|
||||
if err = checkPrevSymbol(lastSym, SymIdentifier, tk); err == nil {
|
||||
@@ -452,14 +478,16 @@ func (self *parser) parseGeneral(scanner *scanner, allowForest bool, allowVarRef
|
||||
}
|
||||
case SymColon, SymDoubleColon:
|
||||
var caseTerm *term
|
||||
if selectorTerm == nil {
|
||||
err = tk.Errorf("selector-case outside of a selector context")
|
||||
} else if caseTerm, err = self.parseSelectorCase(scanner, allowVarRef, tk.Sym == SymDoubleColon); err == nil {
|
||||
addSelectorCase(selectorTerm, caseTerm)
|
||||
currentTerm = caseTerm
|
||||
if tk.Sym == SymDoubleColon {
|
||||
selectorTerm = nil
|
||||
if selectorTerm != nil {
|
||||
if caseTerm, err = self.parseSelectorCase(scanner, allowVarRef, tk.Sym == SymDoubleColon); err == nil {
|
||||
addSelectorCase(selectorTerm, caseTerm)
|
||||
currentTerm = caseTerm
|
||||
if tk.Sym == SymDoubleColon {
|
||||
selectorTerm = nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
currentTerm, err = tree.addToken2(tk)
|
||||
}
|
||||
default:
|
||||
currentTerm, err = tree.addToken2(tk)
|
||||
|
||||
Reference in New Issue
Block a user