mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-05-06 22:43:27 -05:00
126 lines
2.6 KiB
Go
126 lines
2.6 KiB
Go
// Modified from github.com/zdebeer99/goexpression
|
|
package filter
|
|
|
|
func (p *parser) pumpExpression() {
|
|
p.state = branchExpressionValuePart
|
|
for p.state != nil {
|
|
if p.err != nil {
|
|
break
|
|
}
|
|
p.state = p.state(p)
|
|
}
|
|
endo := p.commit()
|
|
if len(endo) > 0 || !p.scan.IsEOF() {
|
|
panic("unexpected end of expression '" + endo + "' not parsed")
|
|
}
|
|
}
|
|
|
|
/*
|
|
parse expressions
|
|
[value part][operator part] repeat
|
|
*/
|
|
|
|
func branchExpressionValuePart(this *parser) stateFn {
|
|
scan := this.scan
|
|
scan.SkipSpaces()
|
|
if scan.IsEOF() {
|
|
return nil
|
|
}
|
|
if scan.ScanNumber() {
|
|
this.add(NewNumberToken(scan.Commit()))
|
|
return branchExpressionOperatorPart
|
|
}
|
|
if scan.ScanWord() {
|
|
return branchExpressionAfterWord
|
|
}
|
|
c := scan.Next()
|
|
switch c {
|
|
case '"', '\'':
|
|
scan.Backup()
|
|
txt := this.ParseText()
|
|
this.add(NewTextToken(txt))
|
|
return branchExpressionOperatorPart
|
|
case '(':
|
|
this.parseOpenBracket()
|
|
return branchExpressionValuePart
|
|
}
|
|
|
|
panic("unexpected token: " + string(c))
|
|
}
|
|
|
|
func branchExpressionAfterWord(this *parser) stateFn {
|
|
scan := this.scan
|
|
switch scan.Peek() {
|
|
case '(':
|
|
this.curr = this.add(NewFuncToken(scan.Commit()))
|
|
return branchFunctionArguments
|
|
}
|
|
this.add(NewIdentityToken(scan.Commit()))
|
|
return branchExpressionOperatorPart
|
|
}
|
|
|
|
func branchFunctionArguments(this *parser) stateFn {
|
|
scan := this.scan
|
|
r := scan.Next()
|
|
if r != '(' {
|
|
panic("expecting '(' before arguments")
|
|
}
|
|
ftoken, ok := this.curr.Value.(*FuncToken)
|
|
if !ok {
|
|
panic("expecting function token to add arguments to")
|
|
}
|
|
state := branchExpressionValuePart
|
|
currnode := this.curr
|
|
for {
|
|
this.curr = NewTreeNode(NewGroupToken(""))
|
|
for state != nil {
|
|
state = state(this)
|
|
}
|
|
r = scan.Next()
|
|
switch r {
|
|
case ' ':
|
|
scan.Ignore()
|
|
continue
|
|
case ',':
|
|
ftoken.AddArgument(this.curr.Root())
|
|
state = branchExpressionValuePart
|
|
scan.Ignore()
|
|
continue
|
|
case ')':
|
|
ftoken.AddArgument(this.curr.Root())
|
|
this.curr = currnode.parent
|
|
scan.Ignore()
|
|
return branchExpressionOperatorPart
|
|
}
|
|
this.curr = currnode
|
|
if scan.IsEOF() {
|
|
panic("arguments missing end bracket")
|
|
}
|
|
panic("invalid char '" + string(r) + "' in arguments")
|
|
}
|
|
}
|
|
|
|
func branchExpressionOperatorPart(this *parser) stateFn {
|
|
scan := this.scan
|
|
scan.SkipSpaces()
|
|
|
|
if scan.IsEOF() {
|
|
return nil
|
|
}
|
|
if this.AcceptOperator() {
|
|
this.parseOperator()
|
|
return branchExpressionValuePart
|
|
}
|
|
if scan.Accept("=") {
|
|
this.parseLRFunc()
|
|
this.curr = this.add(NewGroupToken(""))
|
|
return branchExpressionValuePart
|
|
}
|
|
switch scan.Next() {
|
|
case ')':
|
|
return this.parseCloseBracket()
|
|
}
|
|
scan.Rollback()
|
|
return nil
|
|
}
|