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