<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/parse.go')
-rw-r--r--subex/parse.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/subex/parse.go b/subex/parse.go
index 0c79dc3..db07567 100644
--- a/subex/parse.go
+++ b/subex/parse.go
@@ -5,6 +5,8 @@ import (
)
func parseReplacement(l *RuneReader) (output []TransducerOutput) {
+ // TODO escaping
+ // TODO refactor all the terminator stuff @, #, ~
loop: for {
r := l.next()
switch r {
@@ -18,6 +20,33 @@ func parseReplacement(l *RuneReader) (output []TransducerOutput) {
panic("Missing slot character")
}
output = append(output, TransducerReplacementLoad{datum: slot})
+ case '@':
+ terminal := l.next()
+ if terminal == '(' {
+ output = append(output, TransducerReplacementRune{datum: walk.ArrayBegin})
+ } else if terminal == ')' {
+ output = append(output, TransducerReplacementRune{datum: walk.ArrayEnd})
+ } else {
+ panic("Expected ( or ) after @")
+ }
+ case '~':
+ terminal := l.next()
+ if terminal == '(' {
+ output = append(output, TransducerReplacementRune{datum: walk.StartString{}})
+ } else if terminal == ')' {
+ output = append(output, TransducerReplacementRune{datum: walk.EndString{}})
+ } else {
+ panic("Expected ( or ) after ~")
+ }
+ case '#':
+ terminal := l.next()
+ if terminal == '(' {
+ output = append(output, TransducerReplacementRune{datum: walk.MapBegin})
+ } else if terminal == ')' {
+ output = append(output, TransducerReplacementRune{datum: walk.MapEnd})
+ } else {
+ panic("Expected ( or ) after #")
+ }
default:
output = append(output, TransducerReplacementRune{datum: r})
}
@@ -27,6 +56,7 @@ func parseReplacement(l *RuneReader) (output []TransducerOutput) {
// Parse the contents of a range subex [] into a map
func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum {
+ // TODO escaping
parts := make(map[walk.Datum]walk.Datum)
var froms []walk.Datum
var hasTo bool
@@ -38,6 +68,39 @@ func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum {
} else if fromsStart == '=' {
hasTo = true
break
+ } else if fromsStart == '@' {
+ terminal := l.next()
+ if terminal == '(' {
+ froms = append(froms, walk.ArrayBegin)
+ continue
+ } else if terminal == ')' {
+ froms = append(froms, walk.ArrayEnd)
+ continue
+ } else {
+ panic("Expected ( or ) after @")
+ }
+ } else if fromsStart == '#' {
+ terminal := l.next()
+ if terminal == '(' {
+ froms = append(froms, walk.MapBegin)
+ continue
+ } else if terminal == ')' {
+ froms = append(froms, walk.MapEnd)
+ continue
+ } else {
+ panic("Expected ( or ) after #")
+ }
+ } else if fromsStart == '~' {
+ terminal := l.next()
+ if terminal == '(' {
+ froms = append(froms, walk.StartString{})
+ continue
+ } else if terminal == ')' {
+ froms = append(froms, walk.EndString{})
+ continue
+ } else {
+ panic("Expected ( or ) after ~")
+ }
}
if l.accept("-") {
fromsEnd := l.next()
@@ -62,6 +125,39 @@ func parseRangeSubex(l *RuneReader) map[walk.Datum]walk.Datum {
tosStart := l.next()
if tosStart == ']' {
break
+ } else if tosStart == '@' {
+ terminal := l.next()
+ if terminal == '(' {
+ tos = append(tos, walk.ArrayBegin)
+ continue
+ } else if terminal == ')' {
+ tos = append(tos, walk.ArrayEnd)
+ continue
+ } else {
+ panic("Expected ( or ) after @")
+ }
+ } else if tosStart == '#' {
+ terminal := l.next()
+ if terminal == '(' {
+ tos = append(tos, walk.MapBegin)
+ continue
+ } else if terminal == ')' {
+ tos = append(tos, walk.MapEnd)
+ continue
+ } else {
+ panic("Expected ( or ) after #")
+ }
+ } else if tosStart == '~' {
+ terminal := l.next()
+ if terminal == '(' {
+ tos = append(tos, walk.StartString{})
+ continue
+ } else if terminal == ')' {
+ tos = append(tos, walk.EndString{})
+ continue
+ } else {
+ panic("Expected ( or ) after ~")
+ }
}
if l.accept("-") {
tosEnd := l.next()
@@ -124,6 +220,33 @@ func parseSubex(l *RuneReader, minPower int) SubexAST {
lhs = SubexASTOutput{replacement}
case '.':
lhs = SubexASTCopyAny{}
+ case '@':
+ terminal := l.next()
+ if terminal == '(' {
+ lhs = SubexASTCopyRune{datum: walk.ArrayBegin}
+ } else if terminal == ')' {
+ lhs = SubexASTCopyRune{datum: walk.ArrayEnd}
+ } else {
+ panic("Expected ( or ) after @")
+ }
+ case '~':
+ terminal := l.next()
+ if terminal == '(' {
+ lhs = SubexASTCopyRune{datum: walk.StartString{}}
+ } else if terminal == ')' {
+ lhs = SubexASTCopyRune{datum: walk.EndString{}}
+ } else {
+ panic("Expected ( or ) after ~")
+ }
+ case '#':
+ terminal := l.next()
+ if terminal == '(' {
+ lhs = SubexASTCopyRune{datum: walk.MapBegin}
+ } else if terminal == ')' {
+ lhs = SubexASTCopyRune{datum: walk.MapEnd}
+ } else {
+ panic("Expected ( or ) after #")
+ }
default:
lhs = SubexASTCopyRune{datum: r}
}