<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aparser</id>
	<title>Module:parser - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Aparser"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:parser&amp;action=history"/>
	<updated>2026-04-05T23:04:16Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:parser&amp;diff=474909&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:parser&amp;diff=474909&amp;oldid=prev"/>
		<updated>2025-11-04T17:47:15Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:47, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:parser&amp;diff=474908&amp;oldid=prev</id>
		<title>wikt&gt;Theknightwho: Use Module:table/getNested and Module:table/setNested.</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:parser&amp;diff=474908&amp;oldid=prev"/>
		<updated>2025-05-14T21:53:52Z</updated>

		<summary type="html">&lt;p&gt;Use &lt;a href=&quot;/wiki/Module:table/getNested&quot; title=&quot;Module:table/getNested&quot;&gt;Module:table/getNested&lt;/a&gt; and &lt;a href=&quot;/wiki/Module:table/setNested&quot; title=&quot;Module:table/setNested&quot;&gt;Module:table/setNested&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:parser&amp;amp;diff=474908&amp;amp;oldid=410281&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>wikt&gt;Theknightwho</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:parser&amp;diff=410281&amp;oldid=prev</id>
		<title>Sware at 12:29, 8 January 2025</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:parser&amp;diff=410281&amp;oldid=prev"/>
		<updated>2025-01-08T12:29:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:parser&amp;amp;diff=410281&amp;amp;oldid=373740&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:parser&amp;diff=373740&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local m_table  local concat = table.concat local getmetatable = getmetatable local insert = table.insert local next = next local rawget = rawget local rawset = rawset local remove = table.remove local select = select local setmetatable = setmetatable local type = type local unpack = unpack  local classes = {} local metamethods = mw.loadData(&quot;Module:parser/data&quot;).metamethods  ------------------------------------------------------------------------------------ -- -- Helper...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:parser&amp;diff=373740&amp;oldid=prev"/>
		<updated>2024-07-31T09:41:00Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local m_table  local concat = table.concat local getmetatable = getmetatable local insert = table.insert local next = next local rawget = rawget local rawset = rawset local remove = table.remove local select = select local setmetatable = setmetatable local type = type local unpack = unpack  local classes = {} local metamethods = mw.loadData(&amp;quot;Module:parser/data&amp;quot;).metamethods  ------------------------------------------------------------------------------------ -- -- Helper...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local m_table&lt;br /&gt;
&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local getmetatable = getmetatable&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local next = next&lt;br /&gt;
local rawget = rawget&lt;br /&gt;
local rawset = rawset&lt;br /&gt;
local remove = table.remove&lt;br /&gt;
local select = select&lt;br /&gt;
local setmetatable = setmetatable&lt;br /&gt;
local type = type&lt;br /&gt;
local unpack = unpack&lt;br /&gt;
&lt;br /&gt;
local classes = {}&lt;br /&gt;
local metamethods = mw.loadData(&amp;quot;Module:parser/data&amp;quot;).metamethods&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function get_nested(a, b, ...)&lt;br /&gt;
	if not a then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif ... then&lt;br /&gt;
		return get_nested(a[b], ...)&lt;br /&gt;
	end&lt;br /&gt;
	return a[b]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function set_nested(a, b, c, ...)&lt;br /&gt;
	if not (a and b) then&lt;br /&gt;
		return&lt;br /&gt;
	elseif c and ... then&lt;br /&gt;
		a[b] = a[b] or {}&lt;br /&gt;
		return set_nested(a[b], c, ...)&lt;br /&gt;
	end&lt;br /&gt;
	a[b] = c&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function inherit_metamethods(child, parent)&lt;br /&gt;
	if parent then&lt;br /&gt;
		for method, value in next, parent do&lt;br /&gt;
			if metamethods[method] then&lt;br /&gt;
				child[method] = value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return child&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function signed_index(t, n)&lt;br /&gt;
	return n and n &amp;lt;= 0 and #t + 1 + n or n&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function is_node(value)&lt;br /&gt;
	return classes[getmetatable(value)] and true or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Recursively calling tostring() adds to the C stack (limit: 200), whereas calling __tostring metamethods directly does not. Occasionally relevant when dealing with very deep nesting.&lt;br /&gt;
local tostring&lt;br /&gt;
do&lt;br /&gt;
	local _tostring = _G.tostring&lt;br /&gt;
	&lt;br /&gt;
	function tostring(value)&lt;br /&gt;
		if is_node(value) then&lt;br /&gt;
			return value:__tostring(value)&lt;br /&gt;
		end&lt;br /&gt;
		return _tostring(value)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function type_or_class(value)&lt;br /&gt;
	return classes[getmetatable(value)] or type(value)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
-- Nodes&lt;br /&gt;
--&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local Node = {}&lt;br /&gt;
Node.__index = Node&lt;br /&gt;
&lt;br /&gt;
function Node:next(i)&lt;br /&gt;
	i = i + 1&lt;br /&gt;
	return self[i], i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:next_node(i)&lt;br /&gt;
	local v&lt;br /&gt;
	repeat&lt;br /&gt;
		v, i = self:next(i)&lt;br /&gt;
	until v == nil or is_node(v)&lt;br /&gt;
	return v, i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Implements recursive iteration over a node tree, using functors to maintain state (which uses a lot less memory than closures). Iterator1 exists only to return the calling node on the first iteration, while Iterator2 uses a stack to store the state of each layer in the tree.&lt;br /&gt;
&lt;br /&gt;
-- When a node is encountered (which may contain other nodes), it is returned on the first iteration, and then any child nodes are returned on each subsequent iteration; the same process is followed if any of those children contain nodes themselves. Once a particular node has been fully traversed, the iterator moves back up one layer and continues with any sibling nodes.&lt;br /&gt;
&lt;br /&gt;
-- Each iteration returns three values: `value`, `node` and `key`. Together, these can be used to manipulate the node tree at any given point without needing to know the full structure. Note that when the input node is returned on the first iteration, `node` and `key` will be nil.&lt;br /&gt;
&lt;br /&gt;
-- By default, the iterator will use the `next` method of each node, but this can be changed with the `next_func` parameter, which accepts a string argument with the name of a next method. This is because trees might consist of several different classes of node, and each might have different next methods that are tailored to their particular structures. In addition, each class of node might have multiple different next methods, which can be named according to their purposes. `next_func` ensures that the iterator uses equivalent next methods between different types of node.&lt;br /&gt;
&lt;br /&gt;
-- Currently, two next methods are available: `next`, which simply iterates over the node conventionally, and `next_node`, which only returns children that are themselves nodes. Custom next methods can be declared by any calling module.&lt;br /&gt;
do&lt;br /&gt;
	local Iterator1, Iterator2 = {}, {}&lt;br /&gt;
	Iterator1.__index = Iterator2 -- Not a typo.&lt;br /&gt;
	Iterator2.__index = Iterator2&lt;br /&gt;
	&lt;br /&gt;
	function Iterator1:__call()&lt;br /&gt;
		setmetatable(self, Iterator2)&lt;br /&gt;
		return self[1].node&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Iterator2:push(node)&lt;br /&gt;
		local layer = {&lt;br /&gt;
			k = 0,&lt;br /&gt;
			node = node&lt;br /&gt;
		}&lt;br /&gt;
		self[#self + 1] = layer&lt;br /&gt;
		self[-1] = layer&lt;br /&gt;
		return self&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Iterator2:pop()&lt;br /&gt;
		local len = #self&lt;br /&gt;
		self[len] = nil&lt;br /&gt;
		self[-1] = self[len - 1]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Iterator2:catch_values(node, ...)&lt;br /&gt;
		local v, k = ...&lt;br /&gt;
		if v == nil then&lt;br /&gt;
			self:pop()&lt;br /&gt;
			if self[-1] then&lt;br /&gt;
				return self:__call()&lt;br /&gt;
			end&lt;br /&gt;
			return&lt;br /&gt;
		end&lt;br /&gt;
		self[-1].k = k&lt;br /&gt;
		if is_node(v) then&lt;br /&gt;
			self:push(v)&lt;br /&gt;
		end&lt;br /&gt;
		return v, node, select(2, ...)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Iterator2:__call()&lt;br /&gt;
		local layer = self[-1]&lt;br /&gt;
		local node = layer.node&lt;br /&gt;
		return self:catch_values(node, node[self.next_func](node, layer.k))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Node:__pairs(next_func)&lt;br /&gt;
		return setmetatable({&lt;br /&gt;
			next_func = next_func or &amp;quot;next&amp;quot;&lt;br /&gt;
		}, Iterator1):push(self)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:rawpairs()&lt;br /&gt;
	return next, self&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:__tostring()&lt;br /&gt;
	local output = {}&lt;br /&gt;
	for i = 1, #self do&lt;br /&gt;
		insert(output, tostring(self[i]))&lt;br /&gt;
	end&lt;br /&gt;
	return concat(output)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:clone()&lt;br /&gt;
	return require(&amp;quot;Module:table&amp;quot;).deepcopy(self, &amp;quot;keep&amp;quot;, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:new_class(class)&lt;br /&gt;
	local t = inherit_metamethods({type = class}, self)&lt;br /&gt;
	t.__index = t&lt;br /&gt;
	classes[t] = class&lt;br /&gt;
	return setmetatable(t, self)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Node:new(t)&lt;br /&gt;
	setmetatable(t, nil)&lt;br /&gt;
	t.handler = nil&lt;br /&gt;
	t.override = nil&lt;br /&gt;
	t.route = nil&lt;br /&gt;
	return setmetatable(t, self)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	local Proxy = {}&lt;br /&gt;
&lt;br /&gt;
	function Proxy:__index(k)&lt;br /&gt;
		return Proxy[k] or self.__chars[k]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function Proxy:__newindex(k, v)&lt;br /&gt;
		local key = self.__keys[k]&lt;br /&gt;
		if key then&lt;br /&gt;
			self.__chars[k] = v&lt;br /&gt;
			self.__parents[key] = v&lt;br /&gt;
		elseif key == false then&lt;br /&gt;
			error(&amp;quot;Character is immutable.&amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;quot;Invalid key.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function Proxy:build(a, b, c)&lt;br /&gt;
		local len = self.__len + 1&lt;br /&gt;
		self.__chars[len] = a&lt;br /&gt;
		self.__parents[len] = b&lt;br /&gt;
		self.__keys[len] = c&lt;br /&gt;
		self.__len = len&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function Proxy:iter(i)&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local char = self.__chars[i]&lt;br /&gt;
		if char then&lt;br /&gt;
			return i, self[i], self, self.__parents[i], self.__keys[i]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Node:new_proxy()&lt;br /&gt;
		return setmetatable({&lt;br /&gt;
			__node = self,&lt;br /&gt;
			__chars = {},&lt;br /&gt;
			__parents = {},&lt;br /&gt;
			__keys = {},&lt;br /&gt;
			__len = 0&lt;br /&gt;
		}, Proxy)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
-- Parser&lt;br /&gt;
--&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local Parser = {}&lt;br /&gt;
Parser.__index = Parser&lt;br /&gt;
&lt;br /&gt;
function Parser:read(delta)&lt;br /&gt;
	return self.text[self.head + (delta or 0)] or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:advance(n)&lt;br /&gt;
	self.head = self.head + (n or 1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:layer(n)&lt;br /&gt;
	if n then&lt;br /&gt;
		return rawget(self, #self + n)&lt;br /&gt;
	end&lt;br /&gt;
	return self[-1]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:emit(a, b)&lt;br /&gt;
	local layer = self[-1]&lt;br /&gt;
	if b then&lt;br /&gt;
		insert(layer, signed_index(layer, a), b)&lt;br /&gt;
	else&lt;br /&gt;
		rawset(layer, #layer + 1, a)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:emit_tokens(a, b)&lt;br /&gt;
	local layer = self[-1]&lt;br /&gt;
	if b then&lt;br /&gt;
		a = signed_index(layer, a)&lt;br /&gt;
		for i = 1, #b do&lt;br /&gt;
			insert(layer, a + i - 1, b[i])&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local len = #layer&lt;br /&gt;
		for i = 1, #a do&lt;br /&gt;
			len = len + 1&lt;br /&gt;
			rawset(layer, len, a[i])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:remove(n)&lt;br /&gt;
	local layer = self[-1]&lt;br /&gt;
	if n then&lt;br /&gt;
		return remove(layer, signed_index(layer, n))&lt;br /&gt;
	end&lt;br /&gt;
	local len = #layer&lt;br /&gt;
	local token = layer[len]&lt;br /&gt;
	layer[len] = nil&lt;br /&gt;
	return token&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:replace(a, b)&lt;br /&gt;
	local layer = self[-1]&lt;br /&gt;
	layer[signed_index(layer, a)] = b&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Unlike default table.concat, this respects __tostring metamethods.&lt;br /&gt;
function Parser:concat(a, b, c)&lt;br /&gt;
	if not a or a &amp;gt; 0 then&lt;br /&gt;
		return self:concat(0, a, b)&lt;br /&gt;
	end&lt;br /&gt;
	local layer = self:layer(a)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for i = signed_index(layer, b) or 1, signed_index(layer, c) or #layer do&lt;br /&gt;
		insert(ret, tostring(layer[i]))&lt;br /&gt;
	end&lt;br /&gt;
	return concat(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:emitted(delta)&lt;br /&gt;
	delta = delta or -1&lt;br /&gt;
	local i = 0&lt;br /&gt;
	while true do&lt;br /&gt;
		local layer = self:layer(i)&lt;br /&gt;
		if not layer then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		local layer_len = #layer&lt;br /&gt;
		if -delta &amp;lt;= layer_len then&lt;br /&gt;
			return rawget(layer, layer_len + delta + 1)&lt;br /&gt;
		end&lt;br /&gt;
		delta = delta + layer_len&lt;br /&gt;
		i = i - 1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:push(route)&lt;br /&gt;
	local layer = {&lt;br /&gt;
		head = self.head,&lt;br /&gt;
		route = route&lt;br /&gt;
	}&lt;br /&gt;
	self[#self + 1] = layer&lt;br /&gt;
	self[-1] = layer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:push_sublayer(handler, inherit)&lt;br /&gt;
	local sublayer = {&lt;br /&gt;
		handler = handler,&lt;br /&gt;
		sublayer = true&lt;br /&gt;
	}&lt;br /&gt;
	if inherit then&lt;br /&gt;
		local layer = self[-1]&lt;br /&gt;
		setmetatable(sublayer, inherit_metamethods({&lt;br /&gt;
			__index = layer,&lt;br /&gt;
			__newindex = layer&lt;br /&gt;
		}, getmetatable(layer)))&lt;br /&gt;
	end&lt;br /&gt;
	self[#self + 1] = sublayer&lt;br /&gt;
	self[-1] = sublayer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:pop()&lt;br /&gt;
	local len, layer = #self&lt;br /&gt;
	while true do&lt;br /&gt;
		layer = self[len]&lt;br /&gt;
		self[len] = nil&lt;br /&gt;
		len = len - 1&lt;br /&gt;
		self[-1] = self[len] or self&lt;br /&gt;
		if not layer.sublayer then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		self:emit_tokens(layer)&lt;br /&gt;
	end&lt;br /&gt;
	return layer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:pop_sublayer()&lt;br /&gt;
	local len, layer = #self, self[-1]&lt;br /&gt;
	self[len] = nil&lt;br /&gt;
	self[-1] = self[len - 1] or self&lt;br /&gt;
	return setmetatable(layer, nil)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:get(route, ...)&lt;br /&gt;
	local failed_route = get_nested(self.failed_routes, self.head, route)&lt;br /&gt;
	if failed_route then&lt;br /&gt;
		return false, failed_route&lt;br /&gt;
	end&lt;br /&gt;
	self:push(route)&lt;br /&gt;
	local layer = self[route](self, ...)&lt;br /&gt;
	if layer == nil then&lt;br /&gt;
		layer = self:traverse()&lt;br /&gt;
	end&lt;br /&gt;
	if layer.fail then&lt;br /&gt;
		return false, layer&lt;br /&gt;
	end&lt;br /&gt;
	return true, layer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:consume(this, ...)&lt;br /&gt;
	local layer = self[-1]&lt;br /&gt;
	return (layer.override or layer.handler)(self, this or self:read(), ...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:fail_route()&lt;br /&gt;
	local layer = self:pop()&lt;br /&gt;
	layer.fail = true&lt;br /&gt;
	set_nested(self, &amp;quot;failed_routes&amp;quot;, layer.head, layer.route, layer)&lt;br /&gt;
	self.head = layer.head&lt;br /&gt;
	return layer&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:traverse()&lt;br /&gt;
	while true do&lt;br /&gt;
		local layer = self:consume()&lt;br /&gt;
		if layer then&lt;br /&gt;
			return layer&lt;br /&gt;
		end&lt;br /&gt;
		self:advance()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Converts a handler into a switch table the first time it&amp;#039;s called, which avoids creating unnecessary objects, and prevents any scoping issues caused by parser methods being assigned to table keys before they&amp;#039;ve been declared.&lt;br /&gt;
-- false is used as the default key.&lt;br /&gt;
do&lt;br /&gt;
	local Switch = {}&lt;br /&gt;
	&lt;br /&gt;
	function Switch:__call(parser, this)&lt;br /&gt;
		return (self[this] or self[false])(parser, this)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function Parser:switch(func, t)&lt;br /&gt;
		local layer = self[-1]&lt;br /&gt;
		-- Point handler to the new switch table if the calling function is the current handler.&lt;br /&gt;
		if layer.handler == func then&lt;br /&gt;
			layer.handler = t&lt;br /&gt;
		end&lt;br /&gt;
		return setmetatable(t, Switch)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Generate a new parser class object, which is used as the template for any parser objects. These should be customized with additional/modified methods as needed.&lt;br /&gt;
function Parser:new_class()&lt;br /&gt;
	local t = inherit_metamethods({}, self)&lt;br /&gt;
	t.__index = t&lt;br /&gt;
	return setmetatable(t, self)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Generate a new parser object, which is used for a specific parse.&lt;br /&gt;
function Parser:new(text)&lt;br /&gt;
	return setmetatable({&lt;br /&gt;
		text = text,&lt;br /&gt;
		head = 1&lt;br /&gt;
	}, self)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Parser:parse(data)&lt;br /&gt;
	local parser = self:new(data.text)&lt;br /&gt;
	local success, tokens = parser:get(unpack(data.route))&lt;br /&gt;
	if #parser &amp;gt; 0 then&lt;br /&gt;
		-- This shouldn&amp;#039;t happen.&lt;br /&gt;
		error(&amp;quot;Parser exited with non-empty stack.&amp;quot;)&lt;br /&gt;
	elseif success then&lt;br /&gt;
		local node = data.node&lt;br /&gt;
		return true, node[1]:new(tokens, unpack(node, 2)), parser&lt;br /&gt;
	elseif data.allow_fail then&lt;br /&gt;
		return false, nil, parser&lt;br /&gt;
	end&lt;br /&gt;
	error(&amp;quot;Parser exited with bad route.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local export = {}&lt;br /&gt;
&lt;br /&gt;
export.is_node = is_node&lt;br /&gt;
export.tostring = tostring&lt;br /&gt;
export.type_or_class = type_or_class&lt;br /&gt;
&lt;br /&gt;
function export.new()&lt;br /&gt;
	return Parser:new_class(), Node:new_class(&amp;quot;node&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>