Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LUA/Re-infix.lua.html
--   http://angg.twu.net/LUA/Re-infix.lua
--           (find-angg "LUA/Re-infix.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>

-- Some very old attempts to use the class Re to parse expressions
-- with infix operators using the right precedence.
-- Superseded by:
--   (find-angg "LUA/ELpeg1.lua")
--   (find-angg "LUA/Re2.lua")

-- https://en.wikipedia.org/wiki/Associative_property#Notation_for_non-associative_operations

-- «.leftassoc-rightassoc»	(to "leftassoc-rightassoc")
-- «.preproc_infix»		(to "preproc_infix")
-- «.preproc_infix-tests»	(to "preproc_infix-tests")


Path.prepend("path", "~/LUA/?.lua")
require "re"
require "Rect"
require "Re"




-- «leftassoc-rightassoc»  (to ".leftassoc-rightassoc")
-- https://en.wikipedia.org/wiki/Operator_associativity
-- Consider the expression a~b~c.
-- If the operator ~ has left  associativity, then a~b~c = (a~b)~c.
-- If the operator ~ has right associativity, then a~b~c = a~(b~c).

f_leftassoc = function (...)
    local A = {...}
    local a = A[1]                -- start from the left
    for i=3,#A,2 do               -- and go right
      local op, b = A[i-1], A[i]
      a = {[0]=op, a, b}
    end
    return a
  end

f_rightassoc = function (...)
    local A = {...}
    local b = A[#A]                -- start from the right
    for i=#A-2,1,-2 do             -- and go left
      local a, op = A[i], A[i+1]
      b = {[0]=op, a, b}
    end
    return b
  end

--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Re-infix.lua"
= SynTree.from(f_leftassoc (1, "-", 2, "+", 3))   --> (1-2)+3
= SynTree.from(f_rightassoc(2, "^", 3, "^", 4))   --> 2^(3^4)

--]]





-- «preproc_infix»  (to ".preproc_infix")
-- Based on: (find-angg "LUA/lua50init.lua" "re_expand_INFIX")
--
preproc_infix1 = function (parenstr)
    local components = split(parenstr:sub(2, -2))
    local e     = table.remove(components, 1)
    local sep   = table.remove(components, 1)
    local ops   = components
    local quote = function (str) return '"'..str..'"' end
    local oneop = function (ops) return mapconcat(quote, ops, " / ") end
    local tbl   = {E=e, SEP=sep, OP=oneop(ops)}
    local re    = string.gsub("(E s ({OP} SEP E)*)", "[A-Z]+", tbl)
    return re
  end
preproc_infix = function (gram)
    return (string.gsub(gram, "INFIX(%b())", preproc_infix1))
  end

math_grammar_0 = [[
     e75 <- INFIX( e70 s   |                ) -> f_nonassoc
     e70 <- INFIX( e65 s   ,                ) -> f_nary
     e65 <- INFIX( e60 s   <-               ) -> f_nonassoc
     e60 <- INFIX( e55 s   ->               ) -> f_nonassoc
     e55 <- INFIX( e50 s   or               ) -> f_left
     e50 <- INFIX( e40 s   &                ) -> f_left
     e40 <- INFIX( e35 s   in               ) -> f_nonassoc
     e35 <- INFIX( e30 s   <= < == != >= >  ) -> f_nary
     e30 <- INFIX( e25 s   + -              ) -> f_left
     e25 <- INFIX( e20 s   // / *           ) -> f_left
     e20 <- INFIX( e15 s   ^                ) -> f_right
]]

-- «preproc_infix-tests»  (to ".preproc_infix-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Re-infix.lua"

= preproc_infix(math_grammar_0)


--]]