diff --git a/main.go b/main.go index f4b83fc..db871a0 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( const CONCAT rune = '~' func isOperator(c rune) bool { - if c == '+' || c == '*' || c == '|' || c == CONCAT { + if c == '+' || c == '?' || c == '*' || c == '|' || c == CONCAT { return true } return false @@ -19,7 +19,7 @@ func isOperator(c rune) bool { /* priority returns the priority of the given operator */ func priority(op rune) int { - precedence := []rune{'|', CONCAT, '+', '*'} + precedence := []rune{'|', CONCAT, '+', '*', '?'} return slices.Index(precedence, op) } @@ -43,7 +43,7 @@ func shuntingYard(re string) string { re_postfix = append(re_postfix, re_runes[i]) if re_runes[i] != '(' && re_runes[i] != '|' { if i < len(re_runes)-1 { - if re_runes[i+1] != '|' && re_runes[i+1] != '*' && re_runes[i+1] != '+' && re_runes[i+1] != ')' { + if re_runes[i+1] != '|' && re_runes[i+1] != '*' && re_runes[i+1] != '+' && re_runes[i+1] != '?' && re_runes[i+1] != ')' { re_postfix = append(re_postfix, CONCAT) } } @@ -153,6 +153,15 @@ func thompson(re string) *State { s2 := kleene(*s1) s1 = concatenate(s1, s2) nfa = append(nfa, s1) + case '?': // ab? is equivalent to a(b|) + s1 := mustPop(&nfa) + s2 := &State{} + s2.transitions = make(map[int][]*State) + s2.content = EPSILON + s2.output = make([]*State, 0) + s2.isEmpty = true + s3 := alternate(s1, s2) + nfa = append(nfa, s3) case '|': s1 := mustPop(&nfa) s2 := mustPop(&nfa)