|
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)
--]]