From 0a8690993d572a50b95dd4f1c1903ed00ddb9c2b Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Wed, 21 Sep 2022 21:05:34 +0100 Subject: Initial commit Parses and executes substitute expressions (subexes) So far subex has the following operations: - Concatenation of a and b with ab - Or with | - Repeat maximally with * - Repeat minimally with - - Copy a specific character 'a' - Copy any character '.' - Store text matching a regex into slot 's': `$s(regex)` - Output text in "" including loading from slots with '$' Regexes support all the same operations as subexes minus storing and outputting This first implementation gives very little thought to efficiency Example: ./main 'according to all known laws of aviation' '$1(.-)$m(( .* )| ).*"$m$1"' This swaps the first and last words of the input string --- main/regexast.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 main/regexast.go (limited to 'main/regexast.go') diff --git a/main/regexast.go b/main/regexast.go new file mode 100644 index 0000000..0aab053 --- /dev/null +++ b/main/regexast.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" +) + +type RegexAST interface { + compileWith(next RegexState) RegexState +} + +type RegexASTRune rune +func (ast RegexASTRune) compileWith(next RegexState) RegexState { + return RegexRuneState{ + rune: rune(ast), + next: next, + } +} +func (ast RegexASTRune) String() string { + return string(rune(ast)) +} + +type RegexASTAny struct {} +func (ast RegexASTAny) compileWith(next RegexState) RegexState { + return RegexAnyState{next} +} +func (ast RegexASTAny) String() string { + return "." +} + +type RegexASTConcat struct { + first, second RegexAST +} +func (ast RegexASTConcat) compileWith(next RegexState) RegexState { + return ast.first.compileWith(ast.second.compileWith(next)) +} +func (ast RegexASTConcat) String() string { + return fmt.Sprintf("Concat{%v, %v}", ast.first, ast.second) +} + +type RegexASTOr struct { + first, second RegexAST +} +func (ast RegexASTOr) compileWith(next RegexState) RegexState { + return RegexGroupState{ + ast.first.compileWith(next), + ast.second.compileWith(next), + } +} + +type RegexASTMaximise struct { + content RegexAST +} +func (ast RegexASTMaximise) compileWith(next RegexState) RegexState { + state := &RegexGroupState{ + nil, + next, + } + state.first = ast.content.compileWith(state) + return state +} + +type RegexASTMinimise struct { + content RegexAST +} +func (ast RegexASTMinimise) compileWith(next RegexState) RegexState { + state := &RegexGroupState{ + next, + nil, + } + state.second = ast.content.compileWith(state) + return state +} -- cgit v1.2.3