local a=string.find;local b=string.sub;local c=table.insert;local function d(e,f,g)if type(f)~=g then error("argument "..e.." must be "..g,2)end end;local h={}local i='^[%+%-]?%d+%.?%d*[eE][%+%-]?%d+'local j='^[%+%-]?%d*%.%d+[eE][%+%-]?%d+'local k='^[%+%-]?%d+%.?%d*'local l='^[%+%-]?%d*%.%d+'local m='^0x[%da-fA-F]+'local n='^%d+%.?%d*[eE][%+%-]?%d+'local o='^%d*%.%d+[eE][%+%-]?%d+'local p='^%d+%.?%d*'local q='^%d*%.%d+'local r='^[%a_][%w_]*'local s='^%s+'local t="^(['\"])%1"local u=[[^(['"])(\*)%2%1]]local v=[[^(['"]).-[^\](\*)%2%1]]local w="^''"local x=[[^'(\*)%1']]local y=[[^'.-[^\](\*)%1']]local z='^#.-[^\\]\n'local A,B,C,D,E;local function F(G)return G,G end;local function H(G,I)if I and I.number then G=tonumber(G)end;return"number",G end;local function J(G,I)if I and I.string then G=G:sub(2,-2)end;return"string",G end;local function K(G,I,L)if I and I.string then local M=3;if L[3]then M=M+L[3]:len()end;G=G:sub(M,-M)if G:sub(1,1)=="\n"then G=G:sub(2)end end;return"string",G end;local function N(G,I)if I and I.string then G=G:sub(2,-2)end;return"char",G end;local function O(G)return"comment",G end;local function P(G)return"space",G end;local function Q(G)return"prepro",G end;local function R(G)return"iden",G end;local function S(G)if D[G]then return"keyword",G else return"iden",G end end;local function T(G)if E[G]then return"keyword",G else return"iden",G end end;function h.scan(U,V,W,I)local X=type(U)~='string'and U;W=W or{space=true}I=I or{number=true,string=true}if W then if W.space then W[P]=true end;if W.comments then W[O]=true end end;if not V then if not A then A={{s,P},{m,H},{r,R},{i,H},{j,H},{k,H},{l,H},{t,J},{u,J},{v,J},{'^.',F}}end;V=A end;local Y=0;local Z=X and X:read()local _=X and 0 or#U;local e=1;local a0;local a1;local a2=true;local function a3(a4)local g=type(a4)if a1 then local a5=a1[a0]if a5 then a0=a0+1;return a5[1],a5[2]else a1=nil end end;if g=='string'then local a6,a7=a(U,a4,e)if a6 then local G=b(U,a6,a7)e=a7+1;return'',G else e=_+1;return'',''end elseif g=='table'then a0=1;a1=a4;return'',''elseif g~='nil'then return Y,e else if a2 then if not X then Y=1 end;a2=false end;if e>_ then if X then if not Z then return end;U=Z;Y=Y+1;Z=X:read()if Z then U=U..'\n'end;e,_=1,#U else return end end;for a8,a9 in ipairs(V)do local aa=a9[1]local ab=a9[2]local L={a(U,aa,e)}local a6,a7=L[1],L[2]if a6 then local G=b(U,a6,a7)e=a7+1;local ac,ad;if not(W and W[ab])then h.finished=e>_;ac,ad=ab(G,I,L)end;if not X and G:find("\n")then local a8,ae=G:gsub("\n",{})Y=Y+ae end;if ac then return ac,ad else return a3()end end end end end;return a3 end;local function af(U)return type(U)=='string'end;function h.insert(G,ag,ah)if not ag then return end;local ai;if af(ag)and af(ah)then ai={{ag,ah}}elseif type(ag)=='function'then ai={}for aj,ak in ag()do c(ai,{aj,ak})end else ai=ag end;G(ai)end;function h.getline(G)local a8,ak=G('.-\n')return ak end;function h.lineno(G)return G(0)end;function h.getrest(G)local a8,ak=G('.+')return ak end;function h.get_keywords()if not D then D={["and"]=true,["break"]=true,["do"]=true,["else"]=true,["elseif"]=true,["end"]=true,["false"]=true,["for"]=true,["function"]=true,["if"]=true,["in"]=true,["local"]=true,["nil"]=true,["not"]=true,["or"]=true,["repeat"]=true,["return"]=true,["then"]=true,["true"]=true,["until"]=true,["while"]=true}end;return D end;function h.lua(U,W,I)W=W or{space=true,comments=true}h.get_keywords()if not B then B={{s,P},{m,H},{r,S},{n,H},{o,H},{p,H},{q,H},{t,J},{u,J},{v,J},{'^%-%-%[(=*)%[.-%]%1%]',O},{'^%-%-.-\n',O},{'^%[(=*)%[.-%]%1%]',K},{'^==',F},{'^~=',F},{'^<=',F},{'^>=',F},{'^%.%.%.',F},{'^%.%.',F},{'^.',F}}end;return h.scan(U,B,W,I)end;function h.cpp(U,W,I)W=W or{space=true,comments=true}if not E then E={["class"]=true,["break"]=true,["do"]=true,["sizeof"]=true,["else"]=true,["continue"]=true,["struct"]=true,["false"]=true,["for"]=true,["public"]=true,["void"]=true,["private"]=true,["protected"]=true,["goto"]=true,["if"]=true,["static"]=true,["const"]=true,["typedef"]=true,["enum"]=true,["char"]=true,["int"]=true,["bool"]=true,["long"]=true,["float"]=true,["true"]=true,["delete"]=true,["double"]=true,["while"]=true,["new"]=true,["namespace"]=true,["try"]=true,["catch"]=true,["switch"]=true,["case"]=true,["extern"]=true,["return"]=true,["default"]=true,['unsigned']=true,['signed']=true,["union"]=true,["volatile"]=true,["register"]=true,["short"]=true}end;if not C then C={{s,P},{z,Q},{m,H},{r,T},{n,H},{o,H},{p,H},{q,H},{w,N},{x,N},{y,N},{t,J},{u,J},{v,J},{'^//.-\n',O},{'^/%*.-%*/',O},{'^==',F},{'^!=',F},{'^<=',F},{'^>=',F},{'^->',F},{'^&&',F},{'^||',F},{'^%+%+',F},{'^%-%-',F},{'^%+=',F},{'^%-=',F},{'^%*=',F},{'^/=',F},{'^|=',F},{'^%^=',F},{'^::',F},{'^.',F}}end;return h.scan(U,C,W,I)end;function h.get_separated_list(G,al,am)al=al or')'am=am or','local an={}local ao=1;local ap={}local function aq(ap,aj,f)f=f or aj;c(ap,{aj,f})end;local ar;if al=='\n'then ar=function(aj,f)return aj=='space'and f:find'\n'end else ar=function(aj)return aj==al end end;local as,at;while true do as,at=G()if not as then return nil,'EOS'end;if ar(as,at)and ao==1 then c(an,ap)break elseif as=='('then ao=ao+1;aq(ap,'(')elseif as==')'then ao=ao-1;if ao==0 then c(an,ap)break else aq(ap,')')end elseif as==am and ao==1 then c(an,ap)ap={}else aq(ap,as,at)end end;return an,{as,at}end;function h.skipws(G)local aj,ak=G()while aj=='space'do aj,ak=G()end;return aj,ak end;local au=h.skipws;function h.expecting(G,av,aw)d(1,G,'function')d(2,av,'string')local aj,ak;if aw then aj,ak=G()else aj,ak=au(G)end;if aj~=av then error("expecting "..av,2)end;return ak end;return h