<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.noethoumy.fr/index.php?action=history&amp;feed=atom&amp;title=Module%3AFParser</id>
	<title>Module:FParser - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.noethoumy.fr/index.php?action=history&amp;feed=atom&amp;title=Module%3AFParser"/>
	<link rel="alternate" type="text/html" href="https://wiki.noethoumy.fr/index.php?title=Module:FParser&amp;action=history"/>
	<updated>2026-04-27T18:19:34Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.noethoumy.fr/index.php?title=Module:FParser&amp;diff=353&amp;oldid=prev</id>
		<title>Jaggerwock : Page créée avec « local lexer = {} local parser = {}  --[[ These parser functions are generic functions to build a parser. It works with &quot;Lexing&quot; and &quot;Parsing&quot; functions.  The parser is initialized by the &quot;parse&quot; function, who generates a &quot;state&quot; object that must be a parameter of each parsing functions,                                          and eventually returns the main node of the AST if everything goes well * Lexing functions have one parameter, the state of the parser, an... »</title>
		<link rel="alternate" type="text/html" href="https://wiki.noethoumy.fr/index.php?title=Module:FParser&amp;diff=353&amp;oldid=prev"/>
		<updated>2024-09-20T14:27:36Z</updated>

		<summary type="html">&lt;p&gt;Page créée avec « local lexer = {} local parser = {}  --[[ These parser functions are generic functions to build a parser. It works with &amp;quot;Lexing&amp;quot; and &amp;quot;Parsing&amp;quot; functions.  The parser is initialized by the &amp;quot;parse&amp;quot; function, who generates a &amp;quot;state&amp;quot; object that must be a parameter of each parsing functions,                                          and eventually returns the main node of the AST if everything goes well * Lexing functions have one parameter, the state of the parser, an... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local lexer = {}&lt;br /&gt;
local parser = {}&lt;br /&gt;
&lt;br /&gt;
--[[ These parser functions are generic functions to build a parser.&lt;br /&gt;
It works with &amp;quot;Lexing&amp;quot; and &amp;quot;Parsing&amp;quot; functions. &lt;br /&gt;
The parser is initialized by the &amp;quot;parse&amp;quot; function, who generates a &amp;quot;state&amp;quot; object that must be a parameter of each parsing functions,&lt;br /&gt;
                                         and eventually returns the main node of the AST if everything goes well&lt;br /&gt;
* Lexing functions have one parameter, the state of the parser, and returns a modified state &lt;br /&gt;
  if they could find the terminals they are supposed to recognize and  or nothing if the parse fails. &lt;br /&gt;
* Parsing functions always have a state as unique parameter. &lt;br /&gt;
  They can be divided into&lt;br /&gt;
  * Generic one, written in this module that corresponds that helps to build a parser &lt;br /&gt;
    but don&amp;#039;t generate nodes of the AST themselves, like &amp;quot;alternative&amp;quot;, &amp;quot;chain&amp;quot;, &amp;quot;star&amp;quot; or &amp;quot;plus&amp;quot;  &lt;br /&gt;
    * &amp;quot;chain&amp;quot; corresponds to the concatenation operation in a grammar. for example a function that parses the EBNF rule&lt;br /&gt;
            twelve  = &amp;quot;1&amp;quot;, &amp;quot;2&amp;quot; ;&lt;br /&gt;
      will be generated by chain{lex_char(&amp;quot;1&amp;quot;), lex_char(&amp;quot;2&amp;quot;)}&lt;br /&gt;
    * &amp;quot;alternative&amp;quot; corresponds to the alternative operation in a grammar, for example a function that parses the EBNF rule &lt;br /&gt;
            digit_excluding_zero = &amp;quot;1&amp;quot; | &amp;quot;2&amp;quot; | &amp;quot;3&amp;quot; | &amp;quot;4&amp;quot; | &amp;quot;5&amp;quot; | &amp;quot;6&amp;quot; | &amp;quot;7&amp;quot; | &amp;quot;8&amp;quot; | &amp;quot;9&amp;quot; ;&lt;br /&gt;
       will be written alternative{lex_char(&amp;quot;1&amp;quot;), lex_char(&amp;quot;2&amp;quot;), lex_char(&amp;quot;3&amp;quot;), lex_char(&amp;quot;4&amp;quot;), lex_char(&amp;quot;5&amp;quot;), lex_char(&amp;quot;6&amp;quot;), &lt;br /&gt;
                                   lex_char(&amp;quot;7&amp;quot;), lex_char(&amp;quot;8&amp;quot;), lex_char(&amp;quot;9&amp;quot;)}&lt;br /&gt;
  * User written one, that are functions that must generate a node of the AST as a &amp;quot;node&amp;quot; attribute of the &amp;quot;state&amp;quot; object.&lt;br /&gt;
    To do that they must use attributes of the state object filled by the generic one like &lt;br /&gt;
    * &amp;quot;parsed&amp;quot;, the string parsed by the last lexing function,&lt;br /&gt;
    * &amp;quot;acc&amp;quot;, the list of nodes that are generated by the function that are passed to function that iterates their call namely &amp;quot;star&amp;quot; and &amp;quot;plus&amp;quot; &lt;br /&gt;
    They return nothing if the parse fails, or the state of the last state returned by a lexer function called if they don&amp;#039;t.&lt;br /&gt;
&lt;br /&gt;
Other functions are&lt;br /&gt;
* maybe : a function to avoid checking if the state is nil every time : if the state is in a fail state, &lt;br /&gt;
  it does not apply the parsing or lexing function. Maybe allows to chain the application of lexing and parsing function easily.&lt;br /&gt;
  attribute of the &amp;quot;newstate&amp;quot; object to be able to access the &amp;quot;acc&amp;quot; or &amp;quot;node&amp;quot; of the previous object in a chain, for example.&lt;br /&gt;
* idop : a function that takes a function as parameter that is used to compute an action on the current state in a chain of parsing function, &lt;br /&gt;
  mainly modifying variables in the closure. Functions passed to idop returns nothing. Usable for example for logging.&lt;br /&gt;
* statemodop : a function that takes a function as parameter ; who computes a node in the AST from the state and the variables of the closure and typically adding &lt;br /&gt;
               it to the state.&lt;br /&gt;
               Those functions have the same signatures than parsing functions, but typically they do not parse anything.&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- lexer&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function lex_regex(state, regex)&lt;br /&gt;
&lt;br /&gt;
	local res = string.match(state.newstate.str, &amp;quot;^&amp;quot; .. regex)&lt;br /&gt;
	if res then&lt;br /&gt;
		local newstate = {}&lt;br /&gt;
		local len = string.len(res)&lt;br /&gt;
		newstate.str = state.newstate.str:sub(len + 1)&lt;br /&gt;
		newstate.pos = state.newstate.pos + len&lt;br /&gt;
		return {&lt;br /&gt;
			[&amp;#039;lexed&amp;#039;] = res, &lt;br /&gt;
			[&amp;quot;newstate&amp;quot;] = newstate,&lt;br /&gt;
			[&amp;quot;node&amp;quot;] = state.node -- forwarding node in case it&amp;#039;s not consumed &lt;br /&gt;
                                              -- case of lexing a closing parenthesis after the node creation.&lt;br /&gt;
                                              -- this is to avoid to have to create a closure variable&lt;br /&gt;
		}&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
lexer.lex_regex = lex_regex&lt;br /&gt;
&lt;br /&gt;
local function lex_epsilon(state)&lt;br /&gt;
	return lex_regex(state, &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Tests: p.parse(&amp;quot;a&amp;quot;, p.chain{p.lexer.lex_epsilon, p.lex_char(&amp;quot;a&amp;quot;),p.lexer.lex_epsilon})&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
lexer.lex_epsilon = lex_epsilon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local lex_char = function(char)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		return lex_regex(state, char)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- tested with &amp;quot;p.parse(&amp;quot;/&amp;quot;, p.lex_char(&amp;#039;/&amp;#039;))&amp;quot;&lt;br /&gt;
lexer.lex_char = lex_char&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function lexer.open_parenthesis(state)&lt;br /&gt;
	return lex_regex(state, &amp;quot;[(]&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function lexer.close_parenthesis(state)&lt;br /&gt;
	return lex_regex(state, &amp;quot;[)]&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function lexer.lex_integer(state)&lt;br /&gt;
	return lex_regex(state, &amp;quot;[0-9]+&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function lexer.eat_blanks(state)&lt;br /&gt;
	return lex_regex(state,&amp;#039; *&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.lexer = lexer&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------&lt;br /&gt;
-- generic parser property&lt;br /&gt;
----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function maybe(func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		if state then&lt;br /&gt;
			return func(state)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.maybe = maybe&lt;br /&gt;
&lt;br /&gt;
local function accumulate(aggregate_func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		return {&lt;br /&gt;
			[&amp;quot;newstate&amp;quot;]=state.newstate, &lt;br /&gt;
			[&amp;quot;node&amp;quot;]= aggregate_func(state.acc)&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.accumulate = accumulate&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function map_node(map_func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		if state then&lt;br /&gt;
			return {&lt;br /&gt;
				[&amp;quot;newstate&amp;quot;] = state.newstate, &lt;br /&gt;
				[&amp;quot;node&amp;quot;] = map_func(state.node)&lt;br /&gt;
			}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.map_node = map_node&lt;br /&gt;
&lt;br /&gt;
local function idop(func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		if state then&lt;br /&gt;
			func(state)&lt;br /&gt;
			return state&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.idop = idop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- logs&lt;br /&gt;
local show = function (string) return idop(function(state) mw.log(string) end) end&lt;br /&gt;
parser.log = show&lt;br /&gt;
parser.show = show&lt;br /&gt;
&lt;br /&gt;
local dump_state =  idop(function(state) mw.logObject(state) end)&lt;br /&gt;
parser.dump_state = dump_state&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- this allows avoiding to pass the state beetween each functions if they were called by hand&lt;br /&gt;
local function chain(funcs)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		local i = 1&lt;br /&gt;
		local res = funcs[1](state)&lt;br /&gt;
		&lt;br /&gt;
		while i &amp;lt; #funcs and res do&lt;br /&gt;
			i = i+1&lt;br /&gt;
			if funcs[i] == nil then&lt;br /&gt;
				error(&amp;quot;a nil func in chain&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
			res = funcs[i](res)&lt;br /&gt;
		end&lt;br /&gt;
		return res&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Tests : &lt;br /&gt;
p.parse(&amp;quot;aba&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;), p.lex_char(&amp;#039;a&amp;#039;)}) =&amp;gt; yes&lt;br /&gt;
p.parse(&amp;quot;aba&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;)}) =&amp;gt; nope&lt;br /&gt;
p.parse(&amp;quot;aba&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;), p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;a&amp;#039;)}) =&amp;gt; nope&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
parser.chain = chain&lt;br /&gt;
&lt;br /&gt;
-- higher order function that can parse an alternative between several non terminals.&lt;br /&gt;
-- returns the state of the first match&lt;br /&gt;
local function alternative(funcs)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		local i = 1&lt;br /&gt;
		while i &amp;lt;= #funcs do&lt;br /&gt;
			local res = funcs[i](state)&lt;br /&gt;
			if res then &lt;br /&gt;
				return res &lt;br /&gt;
			end&lt;br /&gt;
			i=i+1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Tests : &lt;br /&gt;
p.parse(&amp;quot;a&amp;quot;, p.alternative{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;)}) =&amp;gt; yes&lt;br /&gt;
p.parse(&amp;quot;b&amp;quot;, p.alternative{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;)}) =&amp;gt; yes&lt;br /&gt;
p.parse(&amp;quot;c&amp;quot;, p.alternative{p.lex_char(&amp;#039;a&amp;#039;), p.lex_char(&amp;#039;b&amp;#039;)}) =&amp;gt; nope&lt;br /&gt;
&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
parser.alternative = alternative&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function star(parsing_func)&lt;br /&gt;
	local function star_rec(state, acc, i)&lt;br /&gt;
&lt;br /&gt;
		local res = chain{&lt;br /&gt;
			parsing_func,&lt;br /&gt;
			idop(&lt;br /&gt;
				function (stat)&lt;br /&gt;
					table.insert(acc, stat.node)&lt;br /&gt;
				end&lt;br /&gt;
			),&lt;br /&gt;
		}(state)&lt;br /&gt;
	&lt;br /&gt;
		if res then&lt;br /&gt;
			return star_rec(res, acc, i + 1)&lt;br /&gt;
		else&lt;br /&gt;
			return state, acc&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return function(state)&lt;br /&gt;
		if state then&lt;br /&gt;
			local acc = {}&lt;br /&gt;
			local result, acc2 = star_rec(state, acc, 1)&lt;br /&gt;
			result.acc = acc2&lt;br /&gt;
			return result&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Tests: p.parse(&amp;quot;aaab&amp;quot;, p.chain{p.star(p.lex_char(&amp;quot;a&amp;quot;)), p.lex_char(&amp;quot;b&amp;quot;)}) =&amp;gt; yes&lt;br /&gt;
p.parse(&amp;quot;b&amp;quot;, p.chain{p.star(p.lex_char(&amp;quot;a&amp;quot;)), p.lex_char(&amp;quot;b&amp;quot;)}) =&amp;gt; yes&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
parser.star = star&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function plus(parsing_func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		local firstnode&lt;br /&gt;
		local acc&lt;br /&gt;
		&lt;br /&gt;
		return chain{&lt;br /&gt;
			parsing_func,&lt;br /&gt;
			idop(&lt;br /&gt;
				function(state)&lt;br /&gt;
					firstnode = state.node&lt;br /&gt;
				end&lt;br /&gt;
			),&lt;br /&gt;
			star(parsing_func),&lt;br /&gt;
			function(state)&lt;br /&gt;
				acc = state.acc&lt;br /&gt;
				table.insert(acc, 1, firstnode)&lt;br /&gt;
				state.acc = acc&lt;br /&gt;
				return state&lt;br /&gt;
			end&lt;br /&gt;
		}(state)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
res = p.parse(&amp;quot;aaab&amp;quot;, &lt;br /&gt;
              p.chain{&lt;br /&gt;
                    p.plus(&lt;br /&gt;
                        p.chain{ &lt;br /&gt;
                              p.lex_char(&amp;quot;a&amp;quot;), &lt;br /&gt;
                              p.statemodop(function(res) res.node=&amp;quot;a&amp;quot; ;  return res; end)&lt;br /&gt;
                        }&lt;br /&gt;
                    ), &lt;br /&gt;
                    p.lex_char(&amp;quot;b&amp;quot;)&lt;br /&gt;
              }&lt;br /&gt;
             )&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
parser.plus = plus&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Tests : &lt;br /&gt;
p.parse(&amp;quot;a&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.idop(function (state) end )}) =&amp;gt; yes&lt;br /&gt;
p.parse(&amp;quot;ab&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.idop(function (state) end), p.lex_char(&amp;#039;b&amp;#039;) }) =&amp;gt; nope&lt;br /&gt;
p.parse(&amp;quot;ab&amp;quot;, p.chain{p.lex_char(&amp;#039;a&amp;#039;), p.idop(function (state) end), p.lex_char(&amp;#039;a&amp;#039;) }) =&amp;gt; nope&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function questionmark(parsing_func)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		local node = nil&lt;br /&gt;
		local res=alternative{&lt;br /&gt;
			chain{&lt;br /&gt;
				parsing_func,&lt;br /&gt;
				idop(function (stat) node = stat.node end)&lt;br /&gt;
			},&lt;br /&gt;
			lex_epsilon&lt;br /&gt;
		}(state)&lt;br /&gt;
		res.node = node&lt;br /&gt;
		return res&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.questionmark = questionmark&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- main function that launches the parsing&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
parser.parse = function (string, base_parsing_function)&lt;br /&gt;
	local state = {}&lt;br /&gt;
	&lt;br /&gt;
	state.newstate = {}&lt;br /&gt;
	state.newstate.str = string&lt;br /&gt;
	state.newstate.pos = 1&lt;br /&gt;
	&lt;br /&gt;
	local res_node = nil&lt;br /&gt;
		&lt;br /&gt;
	local res = chain{&lt;br /&gt;
		base_parsing_function,&lt;br /&gt;
		idop(function(stat) res_node = stat.node end),&lt;br /&gt;
		lexer.eat_blanks&lt;br /&gt;
	}(state)&lt;br /&gt;
&lt;br /&gt;
	if res and res.newstate.str==&amp;quot;&amp;quot; then&lt;br /&gt;
		return res_node&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- a function to create an AST node which represents an nary operator. Could parse an expression on the form « 1 + 2 + 3 + 4 » and return a « sum » AST node wich have a list of nodes for operands sum([number(1), number(2), number(3) number(4) ) in our example&lt;br /&gt;
&lt;br /&gt;
local function nary_op_parser (&lt;br /&gt;
	first_node_parser,      -- a parser that parses only the first element of the operation (« 1 »)&lt;br /&gt;
	next_nodes_parser,      -- a parser that parses the infix operation and one node ( « + 2 » and the subsequent)&lt;br /&gt;
	acc_result_node_creator,-- a function that takes the lists of the node generated by the previous parser and generates the final node&lt;br /&gt;
	single_creator          -- optional, a function corner case when the expression has no actual operator one element like « 1 » (one might just want to get a « number(1) » AST node instead of « sum([number(1)]) »&lt;br /&gt;
	                        -- if that’s not the wanted behavior, provide a function to build a node specific for that case. Takes a node, the result of the first_node_parser .&lt;br /&gt;
)&lt;br /&gt;
	return function(state)&lt;br /&gt;
		local res&lt;br /&gt;
		local firstNode&lt;br /&gt;
		&lt;br /&gt;
		res = chain{&lt;br /&gt;
			first_node_parser,&lt;br /&gt;
			idop(&lt;br /&gt;
				function(state)&lt;br /&gt;
					firstNode = state.node &lt;br /&gt;
				end&lt;br /&gt;
			),&lt;br /&gt;
			star(&lt;br /&gt;
				next_nodes_parser&lt;br /&gt;
			)&lt;br /&gt;
		}(state)&lt;br /&gt;
		&lt;br /&gt;
		if res then &lt;br /&gt;
			if res.acc and #(res.acc) &amp;gt; 0 then &lt;br /&gt;
				local acc = res.acc&lt;br /&gt;
				table.insert(acc, 1, firstNode)&lt;br /&gt;
				res.node = acc_result_node_creator(acc)&lt;br /&gt;
			else&lt;br /&gt;
				single_creator = single_creator or function(node) return node end&lt;br /&gt;
				res.node = single_creator(firstNode)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			res.acc = nil&lt;br /&gt;
			return res&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
parser.nary_op_parser = nary_op_parser&lt;br /&gt;
&lt;br /&gt;
return parser&lt;/div&gt;</summary>
		<author><name>Jaggerwock</name></author>
	</entry>
</feed>