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 } type RegexASTTry struct { content RegexAST } func (ast RegexASTTry) compileWith(next RegexState) RegexState { return RegexGroupState{ ast.content.compileWith(next), next, } } type RegexASTMaybe struct { content RegexAST } func (ast RegexASTMaybe) compileWith(next RegexState) RegexState { return RegexGroupState { next, ast.content.compileWith(next), } }