|
|
|
@ -126,7 +126,7 @@ func shuntingYard(re string) []postfixNode {
|
|
|
|
|
6. If current character is '{', find the appropriate numeric specifier (range start, range end). Apply the range to the postfixNode at the end of outQueue.
|
|
|
|
|
*/
|
|
|
|
|
c := re_postfix[i]
|
|
|
|
|
if isAlphaNum(c) {
|
|
|
|
|
if isNormalChar(c) {
|
|
|
|
|
outQueue = append(outQueue, newPostfixNode(c))
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
@ -379,7 +379,9 @@ func main() {
|
|
|
|
|
// 1. Without '-v': Prints only matches. Prints a newline after every match.
|
|
|
|
|
// 2. With '-v': Substitutes all matches with empty string.
|
|
|
|
|
onlyFlag := flag.Bool("o", false, "Print only colored content. Overrides -l.")
|
|
|
|
|
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled")
|
|
|
|
|
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled (similar to grep's default")
|
|
|
|
|
multiLineFLag := flag.Bool("t", false, "Multi-line mode. Treats newline just like any character.")
|
|
|
|
|
printMatchesFlag := flag.Bool("p", false, "Prints start and end index of each match. Can only be used with '-t' for multi-line mode.")
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
// -l and -o are mutually exclusive: -o overrides -l
|
|
|
|
@ -402,16 +404,50 @@ func main() {
|
|
|
|
|
var test_str string
|
|
|
|
|
var test_runes []rune // Rune-slice representation of test_str
|
|
|
|
|
var err error
|
|
|
|
|
// Create reader for stdin and writer for stdout // End index is one more than last index of match
|
|
|
|
|
var linesRead bool // Whether or not we have read the lines in the file
|
|
|
|
|
// Create reader for stdin and writer for stdout
|
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
|
out := bufio.NewWriter(os.Stdout)
|
|
|
|
|
|
|
|
|
|
re_postfix := shuntingYard(re)
|
|
|
|
|
startState := thompson(re_postfix)
|
|
|
|
|
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.'
|
|
|
|
|
for test_str, err = reader.ReadString('\n'); err == nil; test_str, err = reader.ReadString('\n') {
|
|
|
|
|
for true {
|
|
|
|
|
if linesRead {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if !(*multiLineFLag) {
|
|
|
|
|
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.
|
|
|
|
|
test_str, err = reader.ReadString('\n')
|
|
|
|
|
if err != nil {
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
linesRead = true
|
|
|
|
|
} else {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Multi-line mode - read every line of input into a temp. string.
|
|
|
|
|
// test_str will contain all lines of input (including newline characters)
|
|
|
|
|
// as one string.
|
|
|
|
|
var temp string
|
|
|
|
|
for temp, err = reader.ReadString('\n'); err == nil; temp, err = reader.ReadString('\n') {
|
|
|
|
|
test_str += temp
|
|
|
|
|
}
|
|
|
|
|
// Assuming err != nil
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
linesRead = true
|
|
|
|
|
} else {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
test_runes = []rune(test_str)
|
|
|
|
|
matchIndices := findAllMatches(startState, []rune(test_runes))
|
|
|
|
|
if *printMatchesFlag {
|
|
|
|
|
for _, idx := range matchIndices {
|
|
|
|
|
fmt.Printf("%s\n", idx.toString())
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// Decompose the array of matchIndex structs into a flat unique array of ints - if matchIndex is {4,7}, flat array will contain 4,5,6
|
|
|
|
|
// This should make checking O(1) instead of O(n)
|
|
|
|
|
indicesToPrint := new_uniq_arr[int]()
|
|
|
|
@ -463,7 +499,4 @@ func main() {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if err != io.EOF {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|