4 Star 4 Fork 0

Gitee 极速下载 / Speedle

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/oracle/speedle
克隆/下载
lexerState.go 5.48 KB
一键复制 编辑 原始数据 按行查看 历史
cynthia.ding@oracle.com 提交于 2019-03-26 00:13 . first commit
package govaluate
import (
"errors"
"fmt"
)
type lexerState struct {
isEOF bool
isNullable bool
kind TokenKind
validNextKinds []TokenKind
}
// lexer states.
// Constant for all purposes except compiler.
var validLexerStates = []lexerState{
lexerState{
kind: UNKNOWN,
isEOF: false,
isNullable: true,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
VARIABLE,
PATTERN,
FUNCTION,
ACCESSOR,
STRING,
TIME,
CLAUSE,
},
},
lexerState{
kind: CLAUSE,
isEOF: false,
isNullable: true,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
VARIABLE,
PATTERN,
FUNCTION,
ACCESSOR,
STRING,
TIME,
CLAUSE,
CLAUSE_CLOSE,
},
},
lexerState{
kind: CLAUSE_CLOSE,
isEOF: true,
isNullable: true,
validNextKinds: []TokenKind{
COMPARATOR,
MODIFIER,
NUMERIC,
BOOLEAN,
VARIABLE,
STRING,
PATTERN,
TIME,
CLAUSE,
CLAUSE_CLOSE,
LOGICALOP,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: NUMERIC,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: BOOLEAN,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: STRING,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: TIME,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
SEPARATOR,
},
},
lexerState{
kind: PATTERN,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
SEPARATOR,
},
},
lexerState{
kind: VARIABLE,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: MODIFIER,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
VARIABLE,
FUNCTION,
ACCESSOR,
STRING,
BOOLEAN,
CLAUSE,
CLAUSE_CLOSE,
},
},
lexerState{
kind: COMPARATOR,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
VARIABLE,
FUNCTION,
ACCESSOR,
STRING,
TIME,
CLAUSE,
CLAUSE_CLOSE,
PATTERN,
},
},
lexerState{
kind: LOGICALOP,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
VARIABLE,
FUNCTION,
ACCESSOR,
STRING,
TIME,
CLAUSE,
CLAUSE_CLOSE,
},
},
lexerState{
kind: PREFIX,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
NUMERIC,
BOOLEAN,
VARIABLE,
FUNCTION,
ACCESSOR,
CLAUSE,
CLAUSE_CLOSE,
},
},
lexerState{
kind: TERNARY,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
STRING,
TIME,
VARIABLE,
FUNCTION,
ACCESSOR,
CLAUSE,
SEPARATOR,
},
},
lexerState{
kind: FUNCTION,
isEOF: false,
isNullable: false,
validNextKinds: []TokenKind{
CLAUSE,
},
},
lexerState{
kind: ACCESSOR,
isEOF: true,
isNullable: false,
validNextKinds: []TokenKind{
CLAUSE,
MODIFIER,
COMPARATOR,
LOGICALOP,
CLAUSE_CLOSE,
TERNARY,
SEPARATOR,
},
},
lexerState{
kind: SEPARATOR,
isEOF: false,
isNullable: true,
validNextKinds: []TokenKind{
PREFIX,
NUMERIC,
BOOLEAN,
STRING,
TIME,
VARIABLE,
FUNCTION,
ACCESSOR,
CLAUSE,
},
},
}
func (this lexerState) canTransitionTo(kind TokenKind) bool {
for _, validKind := range this.validNextKinds {
if validKind == kind {
return true
}
}
return false
}
func checkExpressionSyntax(tokens []ExpressionToken) error {
var state lexerState
var lastToken ExpressionToken
var err error
state = validLexerStates[0]
for _, token := range tokens {
if !state.canTransitionTo(token.Kind) {
// call out a specific error for tokens looking like they want to be functions.
if lastToken.Kind == VARIABLE && token.Kind == CLAUSE {
return errors.New("Undefined function " + lastToken.Value.(string))
}
firstStateName := fmt.Sprintf("%s [%v]", state.kind.String(), lastToken.Value)
nextStateName := fmt.Sprintf("%s [%v]", token.Kind.String(), token.Value)
return errors.New("Cannot transition token types from " + firstStateName + " to " + nextStateName)
}
state, err = getLexerStateForToken(token.Kind)
if err != nil {
return err
}
if !state.isNullable && token.Value == nil {
errorMsg := fmt.Sprintf("Token kind '%v' cannot have a nil value", token.Kind.String())
return errors.New(errorMsg)
}
lastToken = token
}
if !state.isEOF {
return errors.New("Unexpected end of expression")
}
return nil
}
func getLexerStateForToken(kind TokenKind) (lexerState, error) {
for _, possibleState := range validLexerStates {
if possibleState.kind == kind {
return possibleState, nil
}
}
errorMsg := fmt.Sprintf("No lexer state found for token kind '%v'\n", kind.String())
return validLexerStates[0], errors.New(errorMsg)
}
1
https://gitee.com/mirrors/Speedle.git
git@gitee.com:mirrors/Speedle.git
mirrors
Speedle
Speedle
1643d905b0e4

搜索帮助