mirror of
				https://github.com/taigrr/yq
				synced 2025-01-18 04:53:17 -08:00 
			
		
		
		
	postfix with traverse op
This commit is contained in:
		
							parent
							
								
									95bc1e1599
								
							
						
					
					
						commit
						c2159d9861
					
				| @ -21,31 +21,28 @@ type OperationType uint32 | ||||
| 
 | ||||
| const ( | ||||
| 	None OperationType = 1 << iota | ||||
| 	Traverse | ||||
| 	Or | ||||
| 	And | ||||
| 	Equals | ||||
| 	EqualsSelf | ||||
| ) | ||||
| 
 | ||||
| type PathElement struct { | ||||
| 	PathElementType PathElementType | ||||
| 	OperationType   OperationType | ||||
| 	Value           interface{} | ||||
| 	ChildElements   [][]*PathElement | ||||
| 	Finished        bool | ||||
| } | ||||
| 
 | ||||
| // debugging purposes only | ||||
| func (p *PathElement) toString() string { | ||||
| 	var result string = `Type: ` | ||||
| 	var result string = `` | ||||
| 	switch p.PathElementType { | ||||
| 	case PathKey: | ||||
| 		result = result + fmt.Sprintf("PathKey - %v", p.Value) | ||||
| 		for _, next := range p.ChildElements[0] { | ||||
| 			result = result + fmt.Sprintf(".%v", next.Value) | ||||
| 		} | ||||
| 		result = result + "\n" | ||||
| 		result = result + fmt.Sprintf("PathKey - '%v'\n", p.Value) | ||||
| 	case ArrayIndex: | ||||
| 		result = result + fmt.Sprintf("ArrayIndex - %v\n", p.Value) | ||||
| 		result = result + fmt.Sprintf("ArrayIndex - '%v'\n", p.Value) | ||||
| 	case Operation: | ||||
| 		result = result + "Operation - " | ||||
| 		switch p.OperationType { | ||||
| @ -55,7 +52,12 @@ func (p *PathElement) toString() string { | ||||
| 			result = result + "AND\n" | ||||
| 		case Equals: | ||||
| 			result = result + "EQUALS\n" | ||||
| 		case EqualsSelf: | ||||
| 			result = result + "EQUALS SELF\n" | ||||
| 		case Traverse: | ||||
| 			result = result + "TRAVERSE\n" | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| @ -76,11 +78,16 @@ func initMaps() { | ||||
| 
 | ||||
| 	precedenceMap[TokenIds["EQUALS_OPERATOR"]] = 30 | ||||
| 	operationTypeMapper[TokenIds["EQUALS_OPERATOR"]] = Equals | ||||
| 
 | ||||
| 	precedenceMap[TokenIds["EQUALS_SELF_OPERATOR"]] = 30 | ||||
| 	operationTypeMapper[TokenIds["EQUALS_SELF_OPERATOR"]] = EqualsSelf | ||||
| 
 | ||||
| 	precedenceMap[TokenIds["TRAVERSE_OPERATOR"]] = 40 | ||||
| 	operationTypeMapper[TokenIds["TRAVERSE_OPERATOR"]] = Traverse | ||||
| } | ||||
| 
 | ||||
| func createOperationPathElement(opToken *lex.Token) PathElement { | ||||
| 	var childElements = make([][]*PathElement, 2) | ||||
| 	var pathElement = PathElement{PathElementType: Operation, OperationType: operationTypeMapper[opToken.Type], ChildElements: childElements} | ||||
| 	var pathElement = PathElement{PathElementType: Operation, OperationType: operationTypeMapper[opToken.Type]} | ||||
| 	return pathElement | ||||
| } | ||||
| 
 | ||||
| @ -119,22 +126,15 @@ func (p *pathPostFixer) ConvertToPostfix(infixTokens []*lex.Token) ([]*PathEleme | ||||
| 	for _, token := range tokens { | ||||
| 		switch token.Type { | ||||
| 		case TokenIds["PATH_KEY"]: // handle splats and array appends here too | ||||
| 			var emptyArray = [][]*PathElement{make([]*PathElement, 0)} | ||||
| 			var pathElement = PathElement{PathElementType: PathKey, Value: token.Value, ChildElements: emptyArray} | ||||
| 
 | ||||
| 			if len(result) > 0 && result[len(result)-1].PathElementType == PathKey && !result[len(result)-1].Finished { | ||||
| 				var lastElement = result[len(result)-1] | ||||
| 				lastElement.ChildElements[0] = append(lastElement.ChildElements[0], &pathElement) | ||||
| 			} else { | ||||
| 				result = append(result, &pathElement) | ||||
| 			} | ||||
| 			var pathElement = PathElement{PathElementType: PathKey, Value: token.Value} | ||||
| 			result = append(result, &pathElement) | ||||
| 		case TokenIds["("]: | ||||
| 			opStack = append(opStack, token) | ||||
| 			finishPathKey(result) | ||||
| 		case TokenIds["OR_OPERATOR"], TokenIds["AND_OPERATOR"], TokenIds["EQUALS_OPERATOR"]: | ||||
| 		case TokenIds["OR_OPERATOR"], TokenIds["AND_OPERATOR"], TokenIds["EQUALS_OPERATOR"], TokenIds["EQUALS_SELF_OPERATOR"], TokenIds["TRAVERSE_OPERATOR"]: | ||||
| 			var currentPrecedence = precedenceMap[token.Type] | ||||
| 			// pop off higher precedent operators onto the result | ||||
| 			for len(opStack) > 0 && precedenceMap[opStack[len(opStack)-1].Type] > currentPrecedence { | ||||
| 			for len(opStack) > 0 && precedenceMap[opStack[len(opStack)-1].Type] >= currentPrecedence { | ||||
| 				opStack, result = popOpToResult(opStack, result) | ||||
| 			} | ||||
| 			// add this operator to the opStack | ||||
|  | ||||
| @ -25,9 +25,9 @@ func testExpression(expression string) (string, error) { | ||||
| 	return formatted, nil | ||||
| } | ||||
| 
 | ||||
| func TestPostFixSimple(t *testing.T) { | ||||
| func TestPostFixSimpleExample(t *testing.T) { | ||||
| 	var infix = "a" | ||||
| 	var expectedOutput = `Type: PathKey - a | ||||
| 	var expectedOutput = `PathKey - 'a' | ||||
| -------- | ||||
| ` | ||||
| 
 | ||||
| @ -39,9 +39,17 @@ func TestPostFixSimple(t *testing.T) { | ||||
| 	test.AssertResultComplex(t, expectedOutput, actual) | ||||
| } | ||||
| 
 | ||||
| func TestPostFixSimplePath(t *testing.T) { | ||||
| func TestPostFixSimplePathExample(t *testing.T) { | ||||
| 	var infix = "apples.bananas*.cat" | ||||
| 	var expectedOutput = `Type: PathKey - apples.bananas*.cat | ||||
| 	var expectedOutput = `PathKey - 'apples' | ||||
| -------- | ||||
| PathKey - 'bananas*' | ||||
| -------- | ||||
| Operation - TRAVERSE | ||||
| -------- | ||||
| PathKey - 'cat' | ||||
| -------- | ||||
| Operation - TRAVERSE | ||||
| -------- | ||||
| ` | ||||
| 
 | ||||
| @ -53,13 +61,13 @@ func TestPostFixSimplePath(t *testing.T) { | ||||
| 	test.AssertResultComplex(t, expectedOutput, actual) | ||||
| } | ||||
| 
 | ||||
| func TestPostFixOr(t *testing.T) { | ||||
| func TestPostFixOrExample(t *testing.T) { | ||||
| 	var infix = "a OR b" | ||||
| 	var expectedOutput = `Type: PathKey - a | ||||
| 	var expectedOutput = `PathKey - 'a' | ||||
| -------- | ||||
| Type: PathKey - b | ||||
| PathKey - 'b' | ||||
| -------- | ||||
| Type: Operation - OR | ||||
| Operation - OR | ||||
| -------- | ||||
| ` | ||||
| 
 | ||||
| @ -71,21 +79,21 @@ Type: Operation - OR | ||||
| 	test.AssertResultComplex(t, expectedOutput, actual) | ||||
| } | ||||
| 
 | ||||
| func TestPostFixOrWithEquals(t *testing.T) { | ||||
| func TestPostFixOrWithEqualsExample(t *testing.T) { | ||||
| 	var infix = "a==thing OR b==thongs" | ||||
| 	var expectedOutput = `Type: PathKey - a | ||||
| 	var expectedOutput = `PathKey - 'a' | ||||
| -------- | ||||
| Type: PathKey - thing | ||||
| PathKey - 'thing' | ||||
| -------- | ||||
| Type: Operation - EQUALS | ||||
| Operation - EQUALS | ||||
| -------- | ||||
| Type: PathKey - b | ||||
| PathKey - 'b' | ||||
| -------- | ||||
| Type: PathKey - thongs | ||||
| PathKey - 'thongs' | ||||
| -------- | ||||
| Type: Operation - EQUALS | ||||
| Operation - EQUALS | ||||
| -------- | ||||
| Type: Operation - OR | ||||
| Operation - OR | ||||
| -------- | ||||
| ` | ||||
| 
 | ||||
| @ -97,21 +105,29 @@ Type: Operation - OR | ||||
| 	test.AssertResultComplex(t, expectedOutput, actual) | ||||
| } | ||||
| 
 | ||||
| func TestPostFixOrWithEqualsPath(t *testing.T) { | ||||
| func TestPostFixOrWithEqualsPathExample(t *testing.T) { | ||||
| 	var infix = "apples.monkeys==thing OR bogs.bobos==thongs" | ||||
| 	var expectedOutput = `Type: PathKey - apples.monkeys | ||||
| 	var expectedOutput = `PathKey - 'apples' | ||||
| -------- | ||||
| Type: PathKey - thing | ||||
| PathKey - 'monkeys' | ||||
| -------- | ||||
| Type: Operation - EQUALS | ||||
| Operation - TRAVERSE | ||||
| -------- | ||||
| Type: PathKey - bogs.bobos | ||||
| PathKey - 'thing' | ||||
| -------- | ||||
| Type: PathKey - thongs | ||||
| Operation - EQUALS | ||||
| -------- | ||||
| Type: Operation - EQUALS | ||||
| PathKey - 'bogs' | ||||
| -------- | ||||
| Type: Operation - OR | ||||
| PathKey - 'bobos' | ||||
| -------- | ||||
| Operation - TRAVERSE | ||||
| -------- | ||||
| PathKey - 'thongs' | ||||
| -------- | ||||
| Operation - EQUALS | ||||
| -------- | ||||
| Operation - OR | ||||
| -------- | ||||
| ` | ||||
| 
 | ||||
|  | ||||
| @ -25,8 +25,6 @@ func initTokens() { | ||||
| 		")", | ||||
| 	} | ||||
| 	Tokens = []string{ | ||||
| 		"BEGIN_SUB_EXPRESSION", | ||||
| 		"END_SUB_EXPRESSION", | ||||
| 		"OR_OPERATOR", | ||||
| 		"AND_OPERATOR", | ||||
| 		"EQUALS_OPERATOR", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user