Skip to content

Commit

Permalink
REFACTOR pegcore: empty-parser prototype-change; unused EMP in create…
Browse files Browse the repository at this point in the history
…_core_parser now should work correctly; added a debug utility.
  • Loading branch information
pocomane committed Jun 22, 2019
1 parent e3bffdf commit d2b98e8
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 25 deletions.
32 changes: 24 additions & 8 deletions documentation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6281,10 +6281,22 @@ assert( ast[3][3][4][1] == 'shark' )
------------
-- TODO : CLEAN UP ! -- THIS IS A DRAFT ! --
local debug = false
LOG = function(...)
if not debug then return end
io.write("#")
local vp = require'valueprint'
for _, s in pairs({...}) do
io.write(" ",vp(s):gsub('\n','\n# '),'')
end
io.write("\n")
end
local function peg_pattern_matcher( pattern )
-- TODO : memo ?
pattern = '^(' .. pattern .. ')'
result = function( DATA, CURR )
LOG('trying pattern ', pattern, ' at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local d = DATA:sub( CURR )
local ast = { d:match( pattern ) }
Expand All @@ -6306,6 +6318,7 @@ local function peg_alternation( alternatives )
local np = #alternatives
for p = 1, np do local P = alternatives[p] end
return function( DATA, CURR )
LOG('trying alternation at',DATA:sub(CURR or 1),'...')
for p = 1, np do
local X, r = alternatives[p]( DATA, CURR )
if nil ~= r then
Expand All @@ -6321,6 +6334,7 @@ local function peg_sequence( sequence )
local np = #sequence
for p = 1, np do local P = sequence[p] end
return function( DATA, CURR )
LOG('trying sequence at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "s" }
for p = 1, np do
Expand All @@ -6337,6 +6351,7 @@ end
local function peg_not( child_parser )
return function( DATA, CURR )
LOG('trying not-operator at',DATA:sub(CURR or 1),'...')
local ast = { tag = "n" }
local X, r = child_parser( DATA, CURR )
if nil == r then
Expand All @@ -6346,16 +6361,16 @@ local function peg_not( child_parser )
end
end
local function peg_empty( )
return function( DATA, CURR )
local ast = { tag = "e" }
return 0, ast
end
local function peg_empty( DATA, CURR )
LOG('trying empty at',DATA:sub(CURR or 1),'...')
local ast = { tag = "e" }
return 0, ast
end
local function peg_non_terminal( match_handler, grammar, rule )
-- TODO : memo
return function( data, curr )
LOG('trying non-terminal', rule, 'at',data:sub(curr or 1),'...')
local p
if 'function' == type(grammar) then
p = grammar(rule)
Expand All @@ -6381,9 +6396,10 @@ end
local function peg_zero_or_more( child_parser )
-- local rec
-- local function REC(...) return rec(...) end
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty()})
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty})
-- return rec
return function( DATA, CURR )
LOG('trying zero-or-more at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "z" }
while true do
Expand Down Expand Up @@ -6476,7 +6492,7 @@ local function create_compiler( match_handler )
function T.suffix(x)
local o = x[3][1]
if o == '*' then return peg_zero_or_more( x[1].func )
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty() }
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty }
elseif o == '' then return x[1].func
elseif o == '+' then return function(...)
local y, z = (peg_sequence{ x[1].func, peg_zero_or_more( x[1].func ) })(...)
Expand All @@ -6491,7 +6507,7 @@ local function create_compiler( match_handler )
end
end
end
function T.empty(x) return peg_empty() end
function T.empty(x) return peg_empty end
function T.expression(x) return x[3].func end

function T.primary(x) return x[1].func end
Expand Down
32 changes: 24 additions & 8 deletions src/pegcore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,22 @@ assert( ast[3][3][4][1] == 'shark' )

-- TODO : CLEAN UP ! -- THIS IS A DRAFT ! --

local debug = false
LOG = function(...)
if not debug then return end
io.write("#")
local vp = require'valueprint'
for _, s in pairs({...}) do
io.write(" ",vp(s):gsub('\n','\n# '),'')
end
io.write("\n")
end

local function peg_pattern_matcher( pattern )
-- TODO : memo ?
pattern = '^(' .. pattern .. ')'
result = function( DATA, CURR )
LOG('trying pattern ', pattern, ' at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local d = DATA:sub( CURR )
local ast = { d:match( pattern ) }
Expand All @@ -250,6 +262,7 @@ local function peg_alternation( alternatives )
local np = #alternatives
for p = 1, np do local P = alternatives[p] end
return function( DATA, CURR )
LOG('trying alternation at',DATA:sub(CURR or 1),'...')
for p = 1, np do
local X, r = alternatives[p]( DATA, CURR )
if nil ~= r then
Expand All @@ -265,6 +278,7 @@ local function peg_sequence( sequence )
local np = #sequence
for p = 1, np do local P = sequence[p] end
return function( DATA, CURR )
LOG('trying sequence at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "s" }
for p = 1, np do
Expand All @@ -281,6 +295,7 @@ end

local function peg_not( child_parser )
return function( DATA, CURR )
LOG('trying not-operator at',DATA:sub(CURR or 1),'...')
local ast = { tag = "n" }
local X, r = child_parser( DATA, CURR )
if nil == r then
Expand All @@ -290,16 +305,16 @@ local function peg_not( child_parser )
end
end

local function peg_empty( )
return function( DATA, CURR )
local ast = { tag = "e" }
return 0, ast
end
local function peg_empty( DATA, CURR )
LOG('trying empty at',DATA:sub(CURR or 1),'...')
local ast = { tag = "e" }
return 0, ast
end

local function peg_non_terminal( match_handler, grammar, rule )
-- TODO : memo
return function( data, curr )
LOG('trying non-terminal', rule, 'at',data:sub(curr or 1),'...')
local p
if 'function' == type(grammar) then
p = grammar(rule)
Expand All @@ -325,9 +340,10 @@ end
local function peg_zero_or_more( child_parser )
-- local rec
-- local function REC(...) return rec(...) end
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty()})
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty})
-- return rec
return function( DATA, CURR )
LOG('trying zero-or-more at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "z" }
while true do
Expand Down Expand Up @@ -420,7 +436,7 @@ local function create_compiler( match_handler )
function T.suffix(x)
local o = x[3][1]
if o == '*' then return peg_zero_or_more( x[1].func )
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty() }
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty }
elseif o == '' then return x[1].func
elseif o == '+' then return function(...)
local y, z = (peg_sequence{ x[1].func, peg_zero_or_more( x[1].func ) })(...)
Expand All @@ -435,7 +451,7 @@ local function create_compiler( match_handler )
end
end
end
function T.empty(x) return peg_empty() end
function T.empty(x) return peg_empty end
function T.expression(x) return x[3].func end

function T.primary(x) return x[1].func end
Expand Down
32 changes: 24 additions & 8 deletions tool/luasnip.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3296,10 +3296,22 @@ pegcore = (function()

-- TODO : CLEAN UP ! -- THIS IS A DRAFT ! --

local debug = false
LOG = function(...)
if not debug then return end
io.write("#")
local vp = require'valueprint'
for _, s in pairs({...}) do
io.write(" ",vp(s):gsub('\n','\n# '),'')
end
io.write("\n")
end

local function peg_pattern_matcher( pattern )
-- TODO : memo ?
pattern = '^(' .. pattern .. ')'
result = function( DATA, CURR )
LOG('trying pattern ', pattern, ' at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local d = DATA:sub( CURR )
local ast = { d:match( pattern ) }
Expand All @@ -3321,6 +3333,7 @@ local function peg_alternation( alternatives )
local np = #alternatives
for p = 1, np do local P = alternatives[p] end
return function( DATA, CURR )
LOG('trying alternation at',DATA:sub(CURR or 1),'...')
for p = 1, np do
local X, r = alternatives[p]( DATA, CURR )
if nil ~= r then
Expand All @@ -3336,6 +3349,7 @@ local function peg_sequence( sequence )
local np = #sequence
for p = 1, np do local P = sequence[p] end
return function( DATA, CURR )
LOG('trying sequence at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "s" }
for p = 1, np do
Expand All @@ -3352,6 +3366,7 @@ end

local function peg_not( child_parser )
return function( DATA, CURR )
LOG('trying not-operator at',DATA:sub(CURR or 1),'...')
local ast = { tag = "n" }
local X, r = child_parser( DATA, CURR )
if nil == r then
Expand All @@ -3361,16 +3376,16 @@ local function peg_not( child_parser )
end
end

local function peg_empty( )
return function( DATA, CURR )
local ast = { tag = "e" }
return 0, ast
end
local function peg_empty( DATA, CURR )
LOG('trying empty at',DATA:sub(CURR or 1),'...')
local ast = { tag = "e" }
return 0, ast
end

local function peg_non_terminal( match_handler, grammar, rule )
-- TODO : memo
return function( data, curr )
LOG('trying non-terminal', rule, 'at',data:sub(curr or 1),'...')
local p
if 'function' == type(grammar) then
p = grammar(rule)
Expand All @@ -3396,9 +3411,10 @@ end
local function peg_zero_or_more( child_parser )
-- local rec
-- local function REC(...) return rec(...) end
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty()})
-- rec = peg_alternation({peg_sequence({x,REC}),peg_empty})
-- return rec
return function( DATA, CURR )
LOG('trying zero-or-more at',DATA:sub(CURR or 1),'...')
CURR = CURR or 1
local OLD, ast = CURR, { tag = "z" }
while true do
Expand Down Expand Up @@ -3491,7 +3507,7 @@ local function create_compiler( match_handler )
function T.suffix(x)
local o = x[3][1]
if o == '*' then return peg_zero_or_more( x[1].func )
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty() }
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty }
elseif o == '' then return x[1].func
elseif o == '+' then return function(...)
local y, z = (peg_sequence{ x[1].func, peg_zero_or_more( x[1].func ) })(...)
Expand All @@ -3506,7 +3522,7 @@ local function create_compiler( match_handler )
end
end
end
function T.empty(x) return peg_empty() end
function T.empty(x) return peg_empty end
function T.expression(x) return x[3].func end

function T.primary(x) return x[1].func end
Expand Down
12 changes: 11 additions & 1 deletion tool/playground.html
Original file line number Diff line number Diff line change
Expand Up @@ -3699,9 +3699,19 @@
function T.suffix(x)
local o = x[3][1]
if o == '*' then return peg_zero_or_more( x[1].func )
elseif o == '+' then return peg_sequence{ x[1].func, peg_zero_or_more( x[1].func ) }
elseif o == '?' then return peg_alternation{ x[1].func, peg_empty() }
elseif o == '' then return x[1].func
elseif o == '+' then return function(...)
local y, z = (peg_sequence{ x[1].func, peg_zero_or_more( x[1].func ) })(...)
if not z then return y, z end
local w = {}
w.tag = 'o'
w[1] = z[1]
for _, k in ipairs(z[2]) do
w[1+#w] = k
end
return y, w
end
end
end
function T.empty(x) return peg_empty() end
Expand Down

0 comments on commit d2b98e8

Please sign in to comment.