View difference between Paste ID: J0A0VNaX and hPHgy2iN
SHOW: | | - or go back to the newest paste.
1
2
local sounddict = {
3
    ["hi"] = "",
4
    ["hi there"] = "",
5
    ["eat me"] = "",
6
    ["eat"] = "",
7
    ["an eye for an eye"] = "",
8
    ["an eye for an apple or banana"] = "",
9
    ["orange"] = "",
10
    ["cactus"] = "",
11
    ["cactus please"] = "",
12
    ["no sir"] = "",
13
    ["for"] = "",
14
}
15
16-
    "hello",
16+
17
    "",
18
    "hi",
19
    "say hi",
20
    "hi there",
21
    "oh hi there",
22
    "an eye for an eye for an eye for an apple or banana",
23
    "an eye for an apple or banana",
24
    "cactus orange no sir",
25
    "eat me hi",
26
}
27
28
local soundtree = {}
29
local soundtree_filekey = newproxy and newproxy() or {}
30
for sound_patt, sound_file in pairs(sounddict) do
31
    local currnode = soundtree
32
    for part in string.gmatch(sound_patt, "([a-z_]+)") do
33
        -- TODO: preprocess part to ignore case and such
34
        currnode[part] = currnode[part] or {}
35
        currnode = currnode[part]
36
    end
37
    currnode[soundtree_filekey] = string.gsub(sound_patt, " ", "_")..".wav"
38
end
39
40
function stuff(soundtree, phrase)
41
    -- TODO: preprocess phrase to ignore case and such
42
    
43
    local foundlist = {}
44
    
45
    local stack_i = 0
46
    local stack_eposlist = { [0] = 1 }
47
    local stack_nodelist = { [0] = soundtree }
48
    local complete, atend = false, false
49
    local backtrack = false
50
    repeat
51
        local spos = stack_eposlist[stack_i]
52
        local node = stack_nodelist[stack_i]
53-
        local word_s, word_e, mods = string.find(phrase, "([a-z_]+)(%p%d)+", spos, true)
53+
54
        -- get next word
55
        --local word_s, word, word_e, mods = string.match(phrase, "()([a-z_]+)()(%p%d)*", spos, true)
56
        local word_s, word_e, mods = string.find(phrase, "([a-z_]+)", spos)
57
        if word_s then
58
            --print(stack_i..": "..string.sub(phrase, word_s, word_e))
59
            -- we have a next word
60
            local word = string.sub(phrase, word_s, word_e)
61
            local subnode = node[word] -- (you could do pattern matching here)
62
            if subnode then
63
                -- we have a pattern that matches this next word
64
                -- (could be first, middle or last word in pattern!)
65
                stack_eposlist[stack_i] = word_e+1
66
                stack_nodelist[stack_i] = subnode
67
                -- continue
68
            else
69
                -- there is no continuing pattern that matches this word
70
                if stack_i == 1 then
71
                    -- this is the first word or next unmatched word and no pattern starts with it
72
                    -- so jump to next word
73
                    stack_i = 0
74
                    stack_eposlist[0] = word_e+1
75
                else
76
                    -- we were matching a pattern, see what comes of it
77
                    -- (this word did not continue any pattern, so it's not considered)
78
                    backtrack = true
79
                end
80-
            atend = true
80+
81-
            backtrack = true
81+
82
            --print(stack_i..": END")
83
            -- there is no next word, check for patterns
84
            -- (last few words may be rechecked if there is no sound for their nodes)
85
            if stack_i == 1 then
86
                -- we weren't matching anything
87
                complete = true
88
            else    
89
                atend = true
90
                backtrack = true
91
            end    
92
        end
93
        if backtrack then
94-
                    if stack_j == stack_i and atend then
94+
95
            for stack_j = stack_i-1, 1, -1 do
96
                -- work backwards through each word to see if it has a sound
97
                local node = stack_nodelist[stack_j]
98
                local soundfile = node[soundtree_filekey]
99
                if soundfile then
100
                    -- this word has a sound
101-
                        stack_eposlist[0] = stack_eposlist[stack_j+1]
101+
102
                    -- TODO: handle mods here
103
                    
104
                    if stack_j == stack_i-1 and atend then
105
                        -- we consumed the last word
106
                        complete = true
107
                    else
108
                        -- start searching for new patterns
109
                        stack_i = 0
110
                        -- resume from word after longest pattern with a sound
111
                        stack_eposlist[0] = stack_eposlist[stack_j]
112
                    end
113
                    -- stop backtracking
114
                    break
115
                end
116
            end
117
            backtrack, atend = false, false
118
        end
119
    until complete
120-
end
120+
121
    return foundlist
122
end
123
124
for testphrase_i = 1, #testphraselist do
125
    local testphrase = testphraselist[testphrase_i]
126
    local out = stuff(soundtree, testphrase)
127
    for sound_i = 1, #out do
128
        print(out[sound_i])
129
    end
130
end
131
132
os.execute("pause")