这是我最近使用 lua 写的 LR 分析程序,程序运行的前提是已经得到了 LR 分析表。
由于四种 LR 分析的过程都是相同的,区别只在于分析表的构建。
所以读者也可以将代码中的 LR 分析表和文法替换成自己的。
lua版本是 lua-5.4.2
--goodLuck
sta={0} sym={'#'} ccl=1 action='' go='' step=1 str='abbaab#'
G={['r0']={'S', 'E'},['r1']={'BB', 'S'},['r2']={'aB', 'B'},['r3']={'b', 'B'}}
lrT={
[0]={['a']='3', ['b']='4', ['#']=nil, ['S']=1, ['B']=2 },
[1]={['a']=nil, ['b']=nil, ['#']='s', ['S']=nil, ['B']=nil},
[2]={['a']='6', ['b']='7', ['#']=nil, ['S']=nil, ['B']=5 },
[3]={['a']='3', ['b']='4', ['#']=nil, ['S']=nil, ['B']=8 },
[4]={['a']='r3', ['b']='r3', ['#']=nil, ['S']=nil, ['B']=nil},
[5]={['a']=nil, ['b']=nil, ['#']='r1', ['S']=nil, ['B']=nil},
[6]={['a']='6', ['b']='7', ['#']=nil, ['S']=nil, ['B']=9 },
[7]={['a']=nil, ['b']=nil, ['#']='r3', ['S']=nil, ['B']=nil},
[8]={['a']='r2', ['b']='r2', ['#']=nil, ['S']=nil, ['B']=nil},
[9]={['a']=nil, ['b']=nil, ['#']='r2', ['S']=nil, ['B']=nil} }
function getcc(a, b)
cc=string.sub(str, ccl, ccl)
ccl=ccl+1
end
function connect()
local temp=''
res=''..string.format('%-5s', step)
for i=1, #sta do
temp=temp..sta[i]
end
res=res..string.format('%-10s',temp)
temp=''
for i=1, #sym do
temp=temp..sym[i]
end
res=res..string.format('%-10s',temp)..string.format('%-8s', string.sub(str, ccl-1))
end
function pf()
res=res..string.format('%-7s', action)..string.format('%-4s', go)
print(res)
action='' go='' res=nil step=step+1
end
print('step '..'state '..'symbol '..'str '..'action '..'goto')
::began::
getcc()
::ngetcc::
r=lrT[sta[#sta]][cc] connect()
if(r) then
if(type(r)=='string') then
local n=tonumber(r)
if(n) then
sta[(#sta)+1]=n
sym[(#sym)+1]=cc
action='S'..n
pf()
goto began
else
if(r~='s') then
for i=1, #G[r][1] do
table.remove(sta)
table.remove(sym)
end
local A=G[r][2]
sym[(#sym)+1]=A
sta[(#sta)+1]=lrT[sta[#sta]][A]
action=r
go=sta[#sta]
pf()
goto ngetcc
else
action=string.format('%-6s', 'accept')
pf()
end
end
else
action='error'
pf()
end
else
action='error'
pf()
end