diff --git a/pkg/yqlib/path_tokeniser.go b/pkg/yqlib/path_tokeniser.go index a76cf75e..848ee149 100644 --- a/pkg/yqlib/path_tokeniser.go +++ b/pkg/yqlib/path_tokeniser.go @@ -23,9 +23,8 @@ func initTokens() { } Tokens = []string{ "OPERATION", // ==, OR, AND - "PATH", // a.b.c + "PATH_KEY", // apples "ARRAY_INDEX", // 1234 - "PATH_JOIN", // "." } Tokens = append(Tokens, Literals...) TokenIds = make(map[string]int) @@ -79,8 +78,8 @@ func initLexer() (*lex.Lexer, error) { lexer.Add([]byte(`\[-?[0-9]+\]`), numberToken("ARRAY_INDEX", true)) lexer.Add([]byte(`-?[0-9]+`), numberToken("ARRAY_INDEX", false)) lexer.Add([]byte("( |\t|\n|\r)+"), skip) - lexer.Add([]byte(`"[^ "]+"`), wrappedToken("PATH")) - lexer.Add([]byte(`[^ \.\[\(\)=]+`), token("PATH")) + lexer.Add([]byte(`"[^ "]+"`), wrappedToken("PATH_KEY")) + lexer.Add([]byte(`[^ \.\[\(\)=]+`), token("PATH_KEY")) lexer.Add([]byte(`\.`), skip) err := lexer.Compile() if err != nil { diff --git a/pkg/yqlib/path_tree.go b/pkg/yqlib/path_tree.go new file mode 100644 index 00000000..038d4015 --- /dev/null +++ b/pkg/yqlib/path_tree.go @@ -0,0 +1,51 @@ +package yqlib + +import lex "github.com/timtadh/lexmachine" + +type PathElementType uint32 + +const ( + PathKey PathElementType = 1 << iota + ArrayIndex + Operation +) + +type OperationType uint32 + +const ( + None OperationType = 1 << iota + Or + And + ChildEquals +) + +type PathElement struct { + PathElementType PathElementType + OperationType OperationType + Value interface{} + ChildElements [][]*PathElement +} + +func parseTree(tokens []*lex.Token, currentElement *PathElement, allElements []*PathElement) []*PathElement { + currentToken, remainingTokens := tokens[0], tokens[1:] + + switch currentToken.Type { + case TokenIds["PATH_KEY"]: + currentElement.PathElementType = PathKey + currentElement.OperationType = None + currentElement.Value = currentToken.Value + } + + if len(remainingTokens) == 0 { + return append(allElements, currentElement) + } + return parseTree(remainingTokens, &PathElement{}, append(allElements, currentElement)) + +} + +func ParseTree(tokens []*lex.Token) []*PathElement { + if len(tokens) == 0 { + return make([]*PathElement, 0) + } + return parseTree(tokens, &PathElement{}, make([]*PathElement, 0)) +} diff --git a/pkg/yqlib/path_tree_test.go b/pkg/yqlib/path_tree_test.go new file mode 100644 index 00000000..88c44e97 --- /dev/null +++ b/pkg/yqlib/path_tree_test.go @@ -0,0 +1 @@ +package yqlib