Module:Sandbox/Rockingerser/Random sentence generator

local a = "a " local the = "the " local this = "this " local that = "that " local these = "these " local those = "those "

local module = {}

function unknown return "(unknown label)" end

function syntaxerror(text) return "(syntax error: "..text..")" end

function tableReverseFind(Table, callbackTable) if type(callbackTable) ~= "table" then callbackTable = { callbackTable } end

for key, val in ipairs(callbackTable) do		if type(val) ~= "function" then callbackTable[key] = function(findParam) return findParam == callbackTable[key] end end end

local key = #Table while key > 0 do		for _, val in ipairs(callbackTable) do			if val(Table[key], key) then return Table[key] end end key = key - 1 end return false end

module.inputs = { subject = { main = function(data) local enums = { "first", "second", "third" } local target = enums[math.random(#enums)] table.insert(data.pointers, target) target = module.inputs.subject[target] target = target[math.random(#target)] table.insert(data.pointers, target) return target end, first = { "I", "we", },		second = { "you" }, third = { "they", "he", "she", the, "it" },	},	verb = { main = function(data) local target = module.inputs.verb[math.random(#module.inputs.verb)] local plural = false tableReverseFind(data.pointers,				function(item, i)					if item == "third" and (data.pointers[i + 1] ~= those and data.pointers[i + 1] ~= these) then						plural = true						return true					end				end			) if plural then return target.plural end

return target.sing end, {			sing = "kill"; plural = "kills"; tens = "killed"; part = "killed"; pres = "killing"; },		{			sing = "eat"; plural = "eats"; tens = "ate"; part = "eaten"; pres = "eating"; },	},	more = { main = function local more = { " ",				" "			}			local out = more[math.random(#more)] if math.random > .5 then return ", " .. out .. " "			end

return " and " .. out .. "."		end, },	animal = { { sing = "shark"; plural = "sharks" }, { sing = "fish"; plural = "fishes" }, },	object = { main = function(data) local object = module.inputs.object.items[math.random(#module.inputs.object.items)] local result = tableReverseFind("I", "you", "we", "he", "she", "it", "they") local enum = { I = "myself"; you = "yourself"; we = "ourselves"; he = "himself"; she = "herself"; it = "itself"; they = "themselves"; }			if enum[result] ~= nil then return enum[result] end return object end, items = { "you", "us", "him", "her", "it", "them", "yourself", "ourselves", "himself", "herself", "itself", "themselves", the, this, these, those, a, },	},	question = { "what", "why", "where", "who", }, }

module.inputs.thing = { unpack(module.inputs.animal) }

function module.inputs.thing.main(data) local thing = module.inputs.thing[math.random(#module.inputs.thing)] local singularRequired = false local pluralRequired = false tableReverseFind(data.pointers,		function(item, i)			if item == this or item == that then				singularRequired = true			elseif item == these or item == those then				pluralRequired = true				return true			end		end	) if not singularRequired and (pluralRequired or math.random > .5) then return thing.plural end return thing.sing end

module.structures = { sentence = "   ", --question = "  ?" }

module.structureNames = { "sentence", --"question", }

local function pointer(text) local ret = { text = text, position = 1, }	function ret.char(offset) offset = offset or 0 return string.sub(ret.text, ret.position + offset, ret.position + offset) end

function ret:read(unt) if type(unt) ~= "table" then unt = { unt } end

for key, val in ipairs(unt) do			if type(val) ~= "function" then unt[key] = function(char) return char == val end end end

local function check local char = self.char if char == "" then return true end for _, val in ipairs(unt) do				if val(char) then return true end end end

local txtRead = "" local charTest = check if charTest then return "" end

repeat txtRead = txtRead .. self.char self.position = self.position + 1 until check

return txtRead end

function ret:find(chars) self:read(chars) return self.position end

return ret end

local pointReach = false function chance_number(char) if char ~= "0" and char ~= "1" and char ~= "2" and char ~= "3" and char ~= "4" and char ~= "5" and char ~= "6" and char ~= "7" and char ~= "8" and char ~= "9" and char ~= "." then return true end end

function module.generate(frame) frame = frame or { args = {} } local args = frame.args math.randomseed(args.seed or os.time) local stru = module.structureNames local structure = stru[math.random(#stru)] local text = module.structures[structure] local parser = pointer(text) local rep = "" local output = "" local data = { type = structure, pointers = {}, output = "", }	mw.log(parser.text) local i = 0 while parser.text:find("<") and i < 100 do		i = i + 1 local Start = parser:find("<") parser.position = parser.position + 1 local labels = {} local label = parser:read(function(char)			return char == " " or char == ">"		end) local err = nil if parser.char ~= ">" and parser.char(1) ~= ">" then local expr = nil parser:read(function(char)				if char == " " then					return expr ~= nil				end				if expr == nil then					return				end

if char == ">" then return true end

if char == "?" then expr = chance_number return true end end)			if expr == chance_number and parser.char == ">" then				err = syntaxerror				output = "unexpected closing angle"			else				output = expr and parser:read(expr)			end			if expr == chance_number and err ~= nil then				output = tonumber(output)				if output == nil then					err = syntaxerror					output = "Not a number"				end			end		end		if err then			rep = err(output)		else			table.insert(labels, label)			for _, val in ipairs(labels) do				table.insert(data.pointers, ""..val.."")				rep = rep .. (module.inputs[val] and module.inputs[val].main or unknown)(data)			end		end

mw.log(parser.text:sub(Start, parser.position)) parser.text = parser.text:gsub(			parser.text:sub(Start, parser.position),			rep		)

parser.position = 1 end mw.log(parser.text) end

return module