diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-21 11:19:18 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-21 11:19:18 +0100 | 
| commit | 184118c1522ee4e78a0588fcac8eb235f512b599 (patch) | |
| tree | cf32b7fff7e820e0b81e6975fee661f554c5c717 | |
| parent | 80e7fd0626bfb98f8c1b7f69726d88f8cfa3e4fc (diff) | |
| download | stred-go-184118c1522ee4e78a0588fcac8eb235f512b599.tar | |
Add :xyz: replacement syntax that removes whatever is before it and inserts whatever is inside it
| -rw-r--r-- | subex/parse.go | 20 | ||||
| -rw-r--r-- | subex/subexast.go | 13 | ||||
| -rw-r--r-- | subex/subexstate.go | 13 | 
3 files changed, 41 insertions, 5 deletions
| diff --git a/subex/parse.go b/subex/parse.go index 52488a7..4e7a3f6 100644 --- a/subex/parse.go +++ b/subex/parse.go @@ -166,7 +166,7 @@ func parseReplacement(l RuneReader) (output []OutputContent) {  		switch r {  			case eof:  				panic("Missing closing \"") -			case '=', '^': +			case '=', '^', ':':  				break loop  			case '$':  				slot := l.Next() @@ -281,7 +281,7 @@ func parseSubex(l RuneReader, minPower int) SubexAST {  		case '[':  			rangeParts := parseRangeSubex(l)  			lhs = SubexASTRange {rangeParts} -		case ')', '|', ';', '{', '+', '-', '*', '/', '!', '$': +		case ')', '|', ';', '{', '+', '-', '*', '/', '!', '$', ':':  			l.Rewind()  			return nil  		case '=': @@ -358,9 +358,19 @@ func parseSubex(l RuneReader, minPower int) SubexAST {  				if slot == eof {  					panic("Missing slot character")  				} -				lhs = SubexASTStore{ -					Match: lhs, -					Slot: slot, +				if slot == '_' { +					lhs = SubexASTDiscard {lhs} +				} else { +					lhs = SubexASTStore{ +						Match: lhs, +						Slot: slot, +					} +				} +			case r == ':' && minPower <= 4: +				replacement := parseReplacement(l) +				lhs = SubexASTConcat { +					SubexASTDiscard {lhs}, +					SubexASTOutput {replacement},  				}  			case r == '|' && minPower <= 8:  				rhs := parseSubex(l, 9) diff --git a/subex/subexast.go b/subex/subexast.go index ee7a959..dd98aa9 100644 --- a/subex/subexast.go +++ b/subex/subexast.go @@ -359,3 +359,16 @@ func (ast SubexASTEmpty) compileWith(next SubexState) SubexState {  func (ast SubexASTEmpty) String() string {  	return "()"  } + +// Discards the output from the content subex +type SubexASTDiscard struct { +	Content SubexAST +} +func (ast SubexASTDiscard) compileWith(next SubexState) SubexState { +	return &SubexCaptureBeginState { +		next: ast.Content.compileWith(&SubexDiscardState {next}), +	} +} +func (ast SubexASTDiscard) String() string { +	return fmt.Sprintf("(%v)$_", ast.Content) +} diff --git a/subex/subexstate.go b/subex/subexstate.go index 997e6ce..b5e1e9b 100644 --- a/subex/subexstate.go +++ b/subex/subexstate.go @@ -36,6 +36,19 @@ func (state SubexCaptureBeginState) accepting(store Store, outputStack OutputSta  	return state.next.accepting(store, outputStack.push(nil))  } +// Discard the top of the OutputStack +type SubexDiscardState struct { +	next SubexState +} +func (state SubexDiscardState) eat(store Store, outputStack OutputStack, char walk.Atom) []SubexBranch { +	_, newStack := outputStack.pop() +	return state.next.eat(store, newStack, char) +} +func (state SubexDiscardState) accepting(store Store, outputStack OutputStack) []OutputStack { +	_, newStack := outputStack.pop() +	return state.next.accepting(store, newStack) +} +  // Pop the top of the OutputStack which contains the stuff outputted since the start of the store  // This outputted data gets stored in a slot  type SubexStoreEndState struct { | 
