Parser complete

lua
Zef Hemel 2024-09-12 13:40:43 +02:00
parent 8725655b9d
commit 00501690cf
5 changed files with 320 additions and 28 deletions

View File

@ -43,7 +43,7 @@ statement[@isGroup=Statement] {
IfStatement {
kw<"if"> exp kw<"then"> Block
(kw<"elseif"> exp kw<"then"> Block)*
(kw<"else"> Block)
(kw<"else"> Block)?
kw<"end">
}
@ -63,9 +63,11 @@ list<term> { term ("," term)* }
NameList { list<Name> }
ExpList { list<exp> }
VarList { list<var> }
ArgList { list<var | "..."> }
ArgList { (list<var | "...">)? }
AttNameList { list<Name Attrib> }
AttNameList { list<AttName> }
AttName { Name Attrib }
Attrib { ( "<" Name ">" )? }
exp {

View File

@ -0,0 +1,22 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
import {LRParser} from "@lezer/lr"
const spec_identifier = {__proto__:null,break:16, goto:20, do:24, end:26, while:30, nil:32, true:34, false:36, or:80, and:82, not:104, function:112, repeat:120, until:122, if:126, then:128, elseif:130, else:132, for:136, in:144, local:154, return:170}
export const parser = LRParser.deserialize({
version: 14,
states: ">YO!ZQPOOOOQO'#Cc'#CcO!UQPO'#CaO!bQPOOOOQO'#Eh'#EhO!vQQO'#CwO$YQPO'#EgOOQO'#Eg'#EgO$dQPO'#EgOOQO'#D}'#D}O%sQPO'#D|OOQO'#Ec'#EcOOQO'#EU'#EUO%xQPO'#C_OOQO'#C_'#C_QOQPOOO!UQPO'#CeO&]QPO'#CgO!vQQO'#CjO&dQPO'#DiO!vQQO'#DlO!UQPO'#DqO!UQPO'#DxO&kQPO'#EOO&sQQO'#ESO'ZQPO,58{OOQO'#Cq'#CqO!UQPO,59^O!vQQO,59`O(aQQO'#C|O(hQQO'#EmOOQO'#Ei'#EiOOQO,59f,59fO!UQPO,59fO(oQPO'#EeO,_QPO,59cOOQO'#Dc'#DcOOQO'#Dd'#DdO!vQQO'#DaOOQO'#Ee'#EeO,fQPO'#DeO,kQPO'#E]O,sQPO,5;iO!vQQO,5:hOOQO-E8S-E8SOOQO,58y,58yOOQO,59P,59PO,{QPO,59RO-QQPO,59UO-XQPO,5:TO-^QPO,5:WO-eQPO'#E|OOQO'#Du'#DuO-pQPO'#DtO-uQPO,5:]O-zQPO'#DyO,fQPO,5:dO.VQQO'#EQO/mQPO'#FOOOQO'#EP'#EPO!UQPO,5:fO1QQPO,5:jO2bQPO,5:nOOQO,5:n,5:nOOQO1G.g1G.gOOQO1G.x1G.xO2xQPO1G.zO3PQSO'#EeO4]QSO'#EhO!vQQO'#DOO7QQSO'#DQOOQO'#Ej'#EjOOQO,59h,59hO7[QSO,59hO7dQPO'#EnOOQO,5;X,5;XO8yQPO,5;XO9OQPO1G/QOOQO1G.}1G.}OOQO'#DX'#DXOOQO'#DY'#DYOOQO'#DZ'#DZOOQO'#D['#D[OOQO'#D^'#D^OOQO'#D_'#D_OOQO'#D`'#D`O!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO!vQQO,59oO:_QPO,59{O;zQQO'#DgOOQO,5:P,5:PO<YQPO,5:wOOQO-E8Z-E8ZOOQO'#Dw'#DwOOQO1G0S1G0SOOQO1G.m1G.mO&]QPO1G.pO!vQQO1G/oO<dQPO1G/rO!vQQO,5:_O!UQPO'#EZO<qQPO,5;hO!vQQO,5:`O&]QPO1G/wO!UQPO'#E[O<yQPO,5:eO!UQPO,5:eOOQO1G0O1G0OO!UQPO'#EROOQO,5:l,5:lO!UQPO'#E^O=UQPO,5;jO,fQPO1G0QO!vQQO1G0UOOQO1G0Y1G0YOOQO7+$f7+$fO>iQQO,59kO?gQPO,59jO?nQQO1G/SO?uQSO1G/SOOQO1G/S1G/SO?}QSO,59{O!vQQO'#EWO@XQPO,5;YOOQO1G0s1G0sOOQO7+$l7+$lODUQPO1G/ZOD]QPO1G/ZOF|QPO1G/ZOGTQPO1G/ZOInQPO1G/ZOI{QPO1G/ZOK|QPO1G/ZO! cQPO1G/ZO! jQPO1G/ZO! qQPO'#EgO! {QPO'#E{OOQO'#Dh'#DhO!!TQPO,5:RO!!YQPO7+$[O!!_QPO7+%ZO!#nQPO7+%^O!#yQPO1G/yOOQO,5:u,5:uOOQO-E8X-E8XOOQO1G/z1G/zO!$QQPO7+%cOOQO,5:v,5:vOOQO-E8Y-E8YO!UQPO1G0POOQO1G0P1G0PO!$VQQO,5:mOOQO,5:x,5:xOOQO-E8[-E8[OOQO7+%l7+%lOOQO7+%p7+%pO!$[QSO1G/VO!$fQPO1G/UO!%rQSO1G/ZO!%yQSO1G/ZO!'XQSO1G/ZO!'`QSO1G/ZO!(hQSO1G/ZO!(uQSO1G/ZO!)eQSO1G/ZO!+iQSO1G/ZO!+pQSO1G/ZOOQO,5:q,5:qOOQO7+$n7+$nO!+wQQO7+$nOOQO-E8T-E8TO!,OQPO,5:rOOQO-E8U-E8UO!-eQQO'#EXO!-pQPO,5;gO&]QPO1G/mOOQO<<Gv<<GvO!-xQPO<<HxO!vQQO'#EYOOQO<<Hx<<HxO&]QPO<<HxO!vQQO7+%eOOQO<<H}<<H}OOQO7+%k7+%kOOQO1G0X1G0XO>iQQO7+$pOOQO<<HY<<HYP'`QQO'#EVO!.TQPO,5:sOOQO,5:s,5:sOOQO-E8V-E8VO!._QPO7+%XOOQO-E8W-E8WOOQOAN>dAN>dO&]QPOAN>dO!.dQPO,5:tO!.kQPOAN>dO!.pQPO<<IPO!.zQSO<<H[OOQO<<Hs<<HsO!/UQPOG24OO<dQPO1G0`OOQOG24OG24OO!vQQOAN>kOOQOLD)jLD)jOOQO7+%z7+%zO!/ZQPOG24VO>iQQO'#DaO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59oO>iQQO,59o",
stateData: "!/e~O#TOS#UOSPOS~OSZOUQOWZOY`O[aO_bOlTO!YfO!^cO!adO!feO!ogO!whO#WPO~O#RRP~P]OgkOilOlnOoqOqmO#YjO~O`wOawObwOcwOdwOlTOqmO!UvO!YxO#WPO#YjO#euO#htO#itO~Og#ZXi#ZXl#ZXo#ZXq#ZX#Y#ZX~OvyO#_#qX~P#tOS#VXU#VXW#VXY#VX[#VX_#VXl#VX!Y#VX!^#VX!a#VX!f#VX!o#VX!w#VX#R#VX#W#VX]#VX!_#VX!c#VX!d#VX~P#tO#_{O~O#RRX]RX!_RX!cRX!dRX~P]O]RP~P]O!_RP~P]O!Y!^O#WPO~OS!aO#R!vX]!vX!_!vX!c!vX!d!vX~P!vOU!bO~O`wOawObwOcwOdwOi!gOlTOqmO!U%nO!YxO#WPO#YjO#euO#htO#itO~Ou!jO~P'`Om!mO~P!vOm#XXx#XXy#XXz#XX!P#XX#c#XX#d#XX#e#XX#f#XX#g#XX#h#XX#i#XX#j#XX#k#XX#l#XX#m#XX#n#XX[#XX!b#XXS#XX#R#XXj#XXv#XXU#XXW#XXY#XX_#XX!Y#XX!^#XX!a#XX!f#XX!o#XX!w#XX#W#XX]#XX!_#XX!c#XX!d#XX~P!bOx#POy#QOz!xO!P!|O#c!qO#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wO~Om!pO~P+ZOl#SO~OlTO#WPO~OvyO#_#qa~O]#YO~O[#ZO~P+ZO!_#[O~O!b#]O~P+ZOv#_O#_#^O!j#pX~O!j#aO~O[#bO~Og#cOo#eOl!mX~O#s#gOS!uPU!uPW!uPY!uP[!uP_!uPl!uPv!uP!Y!uP!^!uP!a!uP!f!uP!o!uP!w!uP#R!uP#W!uP#_!uP]!uP!_!uP!c!uP!d!uP~Ov#iOS#rXU#rXW#rXY#rX[#rX_#rXl#rX!Y#rX!^#rX!a#rX!f#rX!o#rX!w#rX#R#rX#W#rX#_#rX]#rX!_#rX!c#rX!d#rX~O#_#lOS!raU!raW!raY!ra[!ra_!ral!ra!Y!ra!^!ra!a!ra!f!ra!o!ra!w!ra#R!ra#W!ra]!ra!_!ra!c!ra!d!ra~OS#mO#R!va]!va!_!va!c!va!d!va~P+ZOj#nO~P+ZOu#XXx#XXy#XXz#XX!P#XX#`#XX#c#XX#d#XX#e#XX#f#XX#g#XX#h#XX#i#XX#j#XX#k#XX#l#XX#m#XX#n#XX~P!bO#_#oOg#[Xi#[Xl#[Xo#[Xq#[Xu#[Xx#[Xy#[Xz#[X!P#[X#Y#[X#`#[X#c#[X#d#[X#e#[X#f#[X#g#[X#h#[X#i#[X#j#[X#k#[X#l#[X#m#[X#n#[X~Ox%vOy%wOz%oO!P%sO#c!qO#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wO~OutX#`tX~P5|Ou#sO#`#qO~Ov#uOm#bXS#bXU#bXW#bXY#bX[#bX_#bXl#bX!Y#bX!^#bX!a#bX!f#bX!o#bX!w#bX#R#bX#W#bX]#bX!_#bX!c#bX!d#bX~P+ZOm#wO~OlnOqmO#YjO~O#n!wOx!Tay!Taz!Ta!P!Ta#c!Ta#d!Ta#e!Ta#f!Ta#g!Ta#h!Ta#i!Ta#j!Ta#k!Ta#l!Ta#m!Ta~Om!Ta[!Ta!b!TaS!Ta#R!Taj!Tav!TaU!TaW!TaY!Ta_!Tal!Ta!Y!Ta!^!Ta!a!Ta!f!Ta!o!Ta!w!Ta#W!Ta]!Ta!_!Ta!c!Ta!d!Ta~P9ZOc$TOlTO#WPOm![P~Ov#Pa#_#Pa~P#tO]RP!cRP!dRP~P]Ov#_O!j#pa~Og#cOo$bOl!ma~Ov#iOS#raU#raW#raY#ra[#ra_#ral#ra!Y#ra!^#ra!a#ra!f#ra!o#ra!w#ra#R#ra#W#ra#_#ra]#ra!_#ra!c#ra!d#ra~O`wOawObwOcwOdwOlTOqmO!U%nO!YxO#WPO#YjO#euO#htO#itO~Oj$jO~P+ZOu$uO~P'`Ou$uO#`$vO~Ou!Ta#`!Ta~P9ZOv#uOm#baS#baU#baW#baY#ba[#ba_#bal#ba!Y#ba!^#ba!a#ba!f#ba!o#ba!w#ba#R#ba#W#ba]#ba!_#ba!c#ba!d#ba~O!P!|O#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOmwixwiywizwi[wi!bwiSwi#RwijwivwiUwiWwiYwi_wilwi!Ywi!^wi!awi!fwi!owi!wwi#Wwi]wi!_wi!cwi!dwi~O#c!qO~PAlO#cwi~PAlO!P!|O#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOmwixwiywizwi#cwi#ewi[wi!bwiSwi#RwijwivwiUwiWwiYwi_wilwi!Ywi!^wi!awi!fwi!owi!wwi#Wwi]wi!_wi!cwi!dwi~O#dwi~PDdO#d!rO~PDdO#j!vO#k!vO#l!vO#m!vO#n!wOmwixwiywizwi#cwi#dwi#ewi#fwi#gwi[wi!bwiSwi#RwijwivwiUwiWwiYwi_wilwi!Ywi!^wi!awi!fwi!owi!wwi#Wwi]wi!_wi!cwi!dwi~O!P!|O#h!uO#i!uO~PG[O!Pwi#hwi#iwi~PG[O#n!wOmwixwiywi[wi!bwiSwi#RwijwivwiUwiWwiYwi_wilwi!Ywi!^wi!awi!fwi!owi!wwi#Wwi]wi!_wi!cwi!dwi~Ozwi!Pwi#cwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi~PJYOz!xO!P!|O#c!qO#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOmwixwi[wi!bwiSwi#RwijwivwiUwiWwiYwi_wilwi!Ywi!^wi!awi!fwi!owi!wwi#Wwi]wi!_wi!cwi!dwi~Oy#QO~PLyOywi~PLyOv$zOm#oX~P#tOv$zOm#oX~Om$|O~O]$}O~OS!]qU!]qW!]qY!]q[!]q_!]ql!]q!Y!]q!^!]q!a!]q!f!]q!o!]q!w!]q#R!]q#W!]q]!]q!_!]q!c!]q!d!]q~P+ZO]%QO!c%PO!d%RO~Ov%SO~P+ZO]%TO~O#t%VO~Ousi#`si~P5|O#_%WO~O!P%sO#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOuwixwiywizwi#`wi~O#c!qO~P!$kO#cwi~P!$kO!P%sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOuwixwiywizwi#`wi#cwi#ewi~O#dwi~P!&QO#d!rO~P!&QO#j!vO#k!vO#l!vO#m!vO#n!wOuwixwiywizwi#`wi#cwi#dwi#ewi#fwi#gwi~O!P%sO#h!uO#i!uO~P!'gO!Pwi#hwi#iwi~P!'gO#n!wOuwixwiywi#`wi~Ozwi!Pwi#cwi#dwi#ewi#fwi#gwi#hwi#iwi#jwi#kwi#lwi#mwi~P!)SOz%oO!P%sO#c!qO#d!rO#e!sO#f!tO#g!tO#h!uO#i!uO#j!vO#k!vO#l!vO#m!vO#n!wOuwixwi#`wi~Oy%wO~P!*bOywi~P!*bOu%XO~P'`Om!zav!zaS!zaU!zaW!zaY!za[!za_!zal!za!Y!za!^!za!a!za!f!za!o!za!w!za#R!za#W!za]!za!_!za!c!za!d!za~P+ZOc%[OlTO#WPO~Ov$zOm#oa~O]%`O!c%PO!d%aO~Om!{av!{a~P#tO]%fO~O!b%hO~P+ZO]%iO~Ov%jO[!gy~P+ZOury#`ry~P5|O]%kO~O[!g!Z~P+ZOP#i~",
goto: ";d#sPPP#tP$dP$qP$dP$dPP$dPPPPPP&y'}P'}PP)ZPP*gP&yP+u+u+uPP'PPPP+{,g-V-sP.e/X/}'PP0w0w'PP1w2Q$dPP$dPPPP$dP2T2T2WP2Z$d2d$dP$d2g$d2t2w2}3QP3a3p3v3|4T4Z4a4g4mPPPP4sP5QP7h8x:^:fPP:n:tPPPPPPPPPPPP:|;P;S;aQ_OQ!PaQ!RcQ$W#ZQ$Y#]Q$_#bQ%^$|Q%c%RQ%g%aR%l%hgZO]ac#Z#]#b$|%R%a%h#[SOT]abcdhlnvy{!g!x!y!z!{!|!}#O#P#Q#S#Z#[#]#^#a#b#l#o#u$z$|%P%R%S%W%a%h%j%n%o%p%q%r%s%t%u%v%wQiQQ!O`Q!TeQ!XfS!Zg#iQ!ckW!fm#q$v%YQ!oqQ#k!^Q$[#_Q$`#cQ$c#eQ$d#gR%U$bWoRr!e!o!wwTbdhlmnv{!g!x!y!z!{!|!}#O#P#Q#[#^#a#l#o#q#u$v%P%S%W%Y%j%n%o%p%q%r%s%t%u%v%w#eSOT]abcdhlmnvy{!g!x!y!z!{!|!}#O#P#Q#S#Z#[#]#^#a#b#l#o#q#u$v$z$|%P%R%S%W%Y%a%h%j%n%o%p%q%r%s%t%u%v%w#eVOT]abcdhlmnvy{!g!x!y!z!{!|!}#O#P#Q#S#Z#[#]#^#a#b#l#o#q#u$v$z$|%P%R%S%W%Y%a%h%j%n%o%p%q%r%s%t%u%v%w!|VTbdhlmnvy{!g!x!y!z!{!|!}#O#P#Q#S#[#^#a#l#o#q#u$v$z%P%S%W%Y%j%n%o%p%q%r%s%t%u%v%wgWO]ac#Z#]#b$|%R%a%hX!im#q$v%Yp!ys!Q!S!`!d!l#p#y$Q$R$X$Z$x%b%d%m]%p!h$i$k$r$s%et!zs!Q!S!`!d!l#p#y#z#|$Q$R$X$Z$x%b%d%ma%q!h$i$k$l$n$r$s%er!{s!Q!S!`!d!l#p#y#z$Q$R$X$Z$x%b%d%m_%r!h$i$k$l$r$s%ev!|s!Q!S!`!d!l#p#y#z#{#|$Q$R$X$Z$x%b%d%mc%s!h$i$k$l$m$n$r$s%ex!}s!Q!S!`!d!l#p#y#z#{#|#}$Q$R$X$Z$x%b%d%me%t!h$i$k$l$m$n$o$r$s%ez#Os!Q!S!`!d!l#p#y#z#{#|#}$O$Q$R$X$Z$x%b%d%mg%u!h$i$k$l$m$n$o$p$r$s%e!O#Os!Q!S!`!d!l#R#p#y#z#{#|#}$O$P$Q$R$X$Z$x%b%d%mk%u!h#t$i$k$l$m$n$o$p$q$r$s%e!UvTbdhlnv{!g!x!y!z!{!|!}#O#P#Q#[#^#a#l#u%P%S%jq%nm#o#q$v%W%Y%n%o%p%q%r%s%t%u%v%wQ#TxQ#f!YR$g#kR$V#SR!WeR!VeQ#X{Q$^#aR$h#lR!YfgYO]ac#Z#]#b$|%R%a%hR!_gQ![gR$e#iR#h!Zd^Oac#Z#]#b$|%R%a%hR}]d]Oac#Z#]#b$|%R%a%hR|]Q#r!kR$w#rQ#v!lR$y#vS${$S$TR%]${Q%O$YR%_%OQ#`!TR$]#`Q#d!XR$a#dQzUR#VzQ#j![R$f#jg[O]ac#Z#]#b$|%R%a%hQsTQ!QbQ!SdQ!`hQ!dlW!hm#q$v%YW!ln{#a#lQ#RvQ#p!gQ#t%nQ#y!xQ#z!yQ#{!zQ#|!{Q#}!|Q$O!}Q$P#OQ$Q#PQ$R#QQ$X#[Q$Z#^Q$i#oQ$k%oQ$l%pQ$m%qQ$n%rQ$o%sQ$p%tQ$q%uQ$r%vQ$s%wQ$x#uQ%b%PQ%d%SQ%e%WR%m%jlRO]acy#S#Z#]#b$z$|%R%a%h!UrTbdhlnv{!g!x!y!z!{!|!}#O#P#Q#[#^#a#l#u%P%S%jq!em#o#q$v%W%Y%n%o%p%q%r%s%t%u%v%wfUO]ac#Z#]#b$|%R%a%h!vVTbdhlmnv{!g!x!y!z!{!|!}#O#P#Q#[#^#a#l#o#q#u$v%P%S%W%Y%j%n%o%p%q%r%s%t%u%v%wQ#UyQ$S#SR%Z$zUpRr!eR#x!oQ!kmV$t#q$v%YXoRr!e!oQ!nnV#W{#a#lR$U#SR!UegXO]ac#Z#]#b$|%R%a%hR!]g",
nodeNames: "⚠ Comment Chunk Block ; Label :: Name break Goto goto Scope do end WhileStatement while nil true false Ellipsis Number LiteralString Property . MemberExpression [ ] Parens ( ) FunctionCall : TableConstructor { FieldDynamic FieldProp FieldExp } , BinaryExpression or and CompareOp BitOp BitOp BitOp BitOp Concat ArithOp ArithOp ArithOp UnaryExpression not ArithOp BitOp FunctionDef function FuncBody ArgList RepeatStatement repeat until IfStatement if then elseif else ForStatement for ForNumeric ForGeneric NameList in ExpList Function FuncName LocalFunction local Assign VarList Local AttNameList AttName Attrib ReturnStatement return",
maxTerm: 128,
nodeProps: [
["group", -14,4,5,8,9,11,14,30,59,62,67,74,76,78,80,"Statement",-3,34,35,36,"Field"]
],
skippedNodes: [0,1],
repeatNodeCount: 9,
tokenData: "6v~RrXY#]YZ#w[]#]]^$Upq#]rs$^uv)avw)fwx)kxy.iyz.nz{.s{|.x|}.}}!O/U!O!P/x!P!Q0_!Q!R0t!R![2Y![!]4^!]!^4k!^!_4r!_!`5U!`!a5^!c!}5p!}#O6O#O#P#n#P#Q6T#Q#R6Y#T#o5p#o#p6_#p#q6d#q#r6i#r#s6n~#bS#U~XY#][]#]pq#]#O#P#n~#qQYZ#]]^#]~#|P#T~]^$P~$UO#T~~$ZP#T~YZ$P~$aWOY$yZ]$y^r$ys#O$y#O#P%n#P;'S$y;'S;=`(O<%lO$y~$|XOY$yZ]$y^r$yrs%is#O$y#O#P%n#P;'S$y;'S;=`(O<%lO$y~%nO#Y~~%qZrs$ywx$y!Q![&d#O#P$y#T#U$y#U#V$y#Y#Z$y#b#c$y#i#j(U#l#m(w#n#o$y~&gZOY$yZ]$y^r$yrs%is!Q$y!Q!['Y![#O$y#O#P%n#P;'S$y;'S;=`(O<%lO$y~']ZOY$yZ]$y^r$yrs%is!Q$y!Q![$y![#O$y#O#P%n#P;'S$y;'S;=`(O<%lO$y~(RP;=`<%l$y~(XP#o#p([~(_R!Q![(h!c!i(h#T#Z(h~(kS!Q![(h!c!i(h#T#Z(h#q#r$y~(zR!Q![)T!c!i)T#T#Z)T~)WR!Q![$y!c!i$y#T#Z$y~)fO#l~~)kO#d~~)nWOY*WZ]*W^w*Wx#O*W#O#P*v#P;'S*W;'S;=`-W<%lO*W~*ZXOY*WZ]*W^w*Wwx%ix#O*W#O#P*v#P;'S*W;'S;=`-W<%lO*W~*yZrs*Wwx*W!Q![+l#O#P*W#T#U*W#U#V*W#Y#Z*W#b#c*W#i#j-^#l#m.P#n#o*W~+oZOY*WZ]*W^w*Wwx%ix!Q*W!Q![,b![#O*W#O#P*v#P;'S*W;'S;=`-W<%lO*W~,eZOY*WZ]*W^w*Wwx%ix!Q*W!Q![*W![#O*W#O#P*v#P;'S*W;'S;=`-W<%lO*W~-ZP;=`<%l*W~-aP#o#p-d~-gR!Q![-p!c!i-p#T#Z-p~-sS!Q![-p!c!i-p#T#Z-p#q#r*W~.SR!Q![.]!c!i.]#T#Z.]~.`R!Q![*W!c!i*W#T#Z*W~.nOl~~.sOm~~.xO#j~~.}O#h~V/UOvR#`S~/ZP#i~}!O/^~/cTP~OY/^Z]/^^;'S/^;'S;=`/r<%lO/^~/uP;=`<%l/^V/}PgT!O!P0QV0VP!PT!O!P0YQ0_OcQ~0dQ#k~!P!Q0j!_!`0o~0oO#m~T0tOzT~0yUd~!O!P1]!Q![2Y!g!h1q!z!{2k#X#Y1q#l#m2k~1`P!Q![1c~1hRd~!Q![1c!g!h1q#X#Y1q~1tQ{|1z}!O1z~1}P!Q![2Q~2VPd~!Q![2Q~2_Sd~!O!P1]!Q![2Y!g!h1q#X#Y1q~2nR!Q![2w!c!i2w#T#Z2w~2|Ud~!O!P3`!Q![2w!c!i2w!r!s4Q#T#Z2w#d#e4Q~3cR!Q![3l!c!i3l#T#Z3l~3qTd~!Q![3l!c!i3l!r!s4Q#T#Z3l#d#e4Q~4TR{|1z}!O1z!P!Q1z~4cPo~![!]4f~4kOU~V4rOSR#`SV4yQ#sQzT!^!_5P!_!`0oT5UO#fT~5ZP#_~!_!`0oV5eQ#tQzT!_!`0o!`!a5kT5pO#gT~5uR#W~!Q![5p!c!}5p#T#o5p~6TOi~~6YOj~~6_O#n~~6dOq~~6iO#c~~6nOu~~6sP#e~!_!`0o",
tokenizers: [0, 1, 2],
topRules: {"Chunk":[0,2]},
dynamicPrecedences: {"109":1},
specialized: [{term: 100, get: (value) => spec_identifier[value] || -1}],
tokenPrec: 2778
})

View File

@ -0,0 +1,28 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
export const
Comment = 1,
Chunk = 2,
Block = 3,
Label = 5,
Name = 7,
Number = 20,
LiteralString = 21,
FunctionCall = 30,
TableConstructor = 32,
BinaryExpression = 39,
CompareOp = 42,
UnaryExpression = 51,
FuncBody = 57,
ArgList = 58,
IfStatement = 62,
ForStatement = 67,
ForNumeric = 69,
ForGeneric = 70,
NameList = 71,
ExpList = 73,
FuncName = 75,
VarList = 79,
AttNameList = 81,
AttName = 82,
Attrib = 83,
ReturnStatement = 84

View File

@ -34,9 +34,50 @@ Deno.test("Test Lua parser", () => {
parse(`e(func(), func(1, 2, 3), a.b(), a.b.c:hello(), (a.b)(7))`);
// Function expression
parse(`function sayHi()
print("Hi")
end`);
parse(`e(function(a, b) end)`);
parse(`e(function(a, b) test() end)`);
parse(`e(function(a, b, ...) end)`);
// Statements
parse(`do end`);
parse(`do print() end`);
parse(`::hello::
goto hello`);
parse(`while true do print() end`);
parse(`repeat print() until false`);
parse(
`if 1 == 2 then print() elseif 1 < 2 then print2() else print3() end`,
);
parse(`if true then print() end`);
parse(`if true then print() else print2() end`);
parse(`if true then print() elseif false then print2() end`);
// For loops
parse(`for i = 1, 10, 1 do print(i) end`);
parse(`for i = 1, 10 do print(i) end`);
parse(`for el in each({1, 2, 3}) do print(i) end`);
parse(`for i, l in 1, pairs() do print(i) end`);
// Function statements
parse(`function a() end`);
parse(`function a:b() end`);
parse(`function a.b.c:d() end`);
parse(`function a.b.c() end`);
parse(`function hello(a, b) end`);
parse(`function hello(a, b, ...) end`);
parse(`local function hello() end`);
// Assignments, local variables etc.
parse(`a = 1`);
parse(`a, b = 1, 2`);
parse(`a.b.c = 1`);
parse(`a["name"] = 1`);
parse(`local a, b<const>`);
parse(`local a = 1`);
parse(`local a<const> = 4`);
parse(`local a, b = 1, 2`);
// Function calls
parse(`a(1, 2, 3)`);
parse(`print "Sup"`);
parse(`e(1 + print "8")`);
});

View File

@ -52,7 +52,7 @@ export type LuaStatement =
| LuaFunctionStatement
| LuaLocalFunctionStatement
| LuaAssignmentStatement
| LuaLocalAssignmentStatement
| LuaLocalStatement
| LuaFunctionCallStatement;
export type LuaSemicolonStatement = {
@ -121,7 +121,6 @@ export type LuaLocalFunctionStatement = {
export type LuaFunctionName = {
type: "FunctionName";
name: string;
propNames?: string[];
colonName?: string;
};
@ -134,20 +133,30 @@ export type LuaFunctionBody = {
export type LuaAssignmentStatement = {
type: "Assignment";
variables: LuaExpression[];
variables: LuaLValue[];
expressions: LuaExpression[];
};
export type LuaLocalAssignmentStatement = {
type: "LocalAssignment";
names: string[];
expressions: LuaExpression[];
export type LuaLValue =
| LuaVariable
| LuaPropertyAccessExpression
| LuaTableAccessExpression;
export type LuaLocalStatement = {
type: "Local";
names: LuaAttName[];
expressions?: LuaExpression[];
};
export type LuaAttName = {
type: "AttName";
name: string;
attribute?: string;
};
export type LuaFunctionCallStatement = {
type: "FunctionCallStatement";
name: string;
args: LuaExpression[];
call: LuaFunctionCallExpression;
};
// EXPRESSIONS
@ -290,18 +299,107 @@ function parseStatement(n: CrudeAST): LuaStatement {
case "Semicolon":
return { type: "Semicolon" };
case "Label":
return { type: "Label", name: t[1] as string };
return { type: "Label", name: t[2][1] as string };
case "Break":
return { type: "Break" };
case "Goto":
return { type: "Goto", name: t[1] as string };
return { type: "Goto", name: t[2][1] as string };
case "Scope":
return parseBlock(t[2]);
case ";":
return { type: "Semicolon" };
case "WhileStatement":
return {
type: "While",
condition: parseExpression(t[2]),
block: parseBlock(t[4]),
};
case "RepeatStatement":
return {
type: "Repeat",
block: parseBlock(t[2]),
condition: parseExpression(t[4]),
};
case "IfStatement": {
const conditions: { condition: LuaExpression; block: LuaBlock }[] =
[];
let elseBlock: LuaBlock | undefined = undefined;
for (let i = 1; i < t.length; i += 4) {
console.log("Looking at", t[i]);
if (t[i][0] === "if" || t[i][0] === "elseif") {
conditions.push({
condition: parseExpression(t[i + 1]),
block: parseBlock(t[i + 3]),
});
} else if (t[i][0] === "else") {
elseBlock = parseBlock(t[i + 1]);
} else if (t[i][0] === "end") {
break;
} else {
throw new Error(`Unknown if clause type: ${t[i][0]}`);
}
}
return {
type: "If",
conditions,
elseBlock,
};
}
case "ForStatement":
if (t[2][0] === "ForNumeric") {
const forNumeric = t[2] as [string, ...CrudeAST[]];
return {
type: "For",
name: forNumeric[1][1] as string,
start: parseExpression(forNumeric[3]),
end: parseExpression(forNumeric[5]),
step: forNumeric[6]
? parseExpression(forNumeric[7])
: undefined,
block: parseBlock(t[4]),
};
} else {
const forGeneric = t[2] as [string, ...CrudeAST[]];
return {
type: "ForIn",
names: parseNameList(forGeneric[1]),
expressions: parseExpList(forGeneric[3]),
block: parseBlock(t[4]),
};
}
case "Function":
return {
type: "Function",
name: parseFunctionName(t[2]),
body: parseFunctionBody(t[3]),
};
case "LocalFunction":
return {
type: "LocalFunction",
name: t[3][1] as string,
body: parseFunctionBody(t[4]),
};
case "FunctionCall":
return {
type: "FunctionCallStatement",
name: t[1][1] as string,
args: t.slice(2, -1).filter((t) =>
![",", "(", ")"].includes(t[1] as string)
).map(parseExpression),
call: parseExpression([
"FunctionCall",
...t.slice(1),
]) as LuaFunctionCallExpression,
};
case "Assign":
return {
type: "Assignment",
variables: (t[1].slice(1) as CrudeAST[]).filter((t) =>
t[0] != ","
).map(parseLValue),
expressions: parseExpList(t[3]),
};
case "Local":
return {
type: "Local",
names: parseAttNames(t[2]),
expressions: t[4] ? parseExpList(t[4]) : [],
};
default:
console.error(t);
@ -309,6 +407,82 @@ function parseStatement(n: CrudeAST): LuaStatement {
}
}
function parseAttNames(n: CrudeAST): LuaAttName[] {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "AttNameList") {
throw new Error(`Expected AttNameList, got ${t[0]}`);
}
return t.slice(1).filter((t) => t[0] !== ",").map(parseAttName);
}
function parseAttName(n: CrudeAST): LuaAttName {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "AttName") {
throw new Error(`Expected AttName, got ${t[0]}`);
}
return {
type: "AttName",
name: t[1][1] as string,
attribute: t[2][2] ? t[2][2][1] as string : undefined,
};
}
function parseLValue(n: CrudeAST): LuaLValue {
const t = n as [string, ...CrudeAST[]];
switch (t[0]) {
case "Name":
return { type: "Variable", name: t[1] as string };
case "Property":
return {
type: "PropertyAccess",
object: parsePrefixExpression(t[1]),
property: t[3][1] as string,
};
case "MemberExpression":
return {
type: "TableAccess",
object: parsePrefixExpression(t[1]),
key: parseExpression(t[3]),
};
default:
console.error(t);
throw new Error(`Unknown lvalue type: ${t[0]}`);
}
}
function parseFunctionName(n: CrudeAST): LuaFunctionName {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "FuncName") {
throw new Error(`Expected FunctionName, got ${t[0]}`);
}
const propNames: string[] = [];
let colonName: string | undefined = undefined;
for (let i = 1; i < t.length; i += 2) {
propNames.push(t[i][1] as string);
if (t[i + 1] && t[i + 1][0] === ":") {
colonName = t[i + 2][1] as string;
break;
}
}
return { type: "FunctionName", propNames, colonName };
}
function parseNameList(n: CrudeAST): string[] {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "NameList") {
throw new Error(`Expected NameList, got ${t[0]}`);
}
return t.slice(1).filter((t) => t[0] === "Name").map((t) => t[1] as string);
}
function parseExpList(n: CrudeAST): LuaExpression[] {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "ExpList") {
throw new Error(`Expected ExpList, got ${t[0]}`);
}
return t.slice(1).filter((t) => t[0] !== ",").map(parseExpression);
}
function parseExpression(n: CrudeAST): LuaExpression {
const t = n as [string, ...CrudeAST[]];
switch (t[0]) {
@ -348,17 +522,20 @@ function parseExpression(n: CrudeAST): LuaExpression {
type: "FunctionCall",
prefix: parsePrefixExpression(t[1]),
name: t[3][1] as string,
args: t.slice(4, -1).filter((t) =>
![",", "(", ")"].includes(t[1] as string)
).map(parseExpression),
args: parseFunctionArgs(t.slice(4)),
};
}
return {
type: "FunctionCall",
prefix: parsePrefixExpression(t[1]),
args: t.slice(3, -1).filter((t) =>
![",", "(", ")"].includes(t[1] as string)
).map(parseExpression),
args: parseFunctionArgs(t.slice(2)),
};
}
case "FunctionDef": {
const body = parseFunctionBody(t[2]);
return {
type: "FunctionDefinition",
body,
};
}
case "Name":
@ -385,6 +562,28 @@ function parseExpression(n: CrudeAST): LuaExpression {
}
}
function parseFunctionArgs(n: CrudeAST[]): LuaExpression[] {
console.log("Parsing function args", n);
return n.filter((t) => ![",", "(", ")"].includes(t[0])).map(
parseExpression,
);
}
function parseFunctionBody(n: CrudeAST): LuaFunctionBody {
const t = n as [string, ...CrudeAST[]];
if (t[0] !== "FuncBody") {
throw new Error(`Expected FunctionBody, got ${t[0]}`);
}
return {
type: "FunctionBody",
parameters: (t[2] as CrudeAST[]).slice(1).filter((t) =>
["Name", "Ellipsis"].includes(t[0])
)
.map((t) => t[1] as string),
block: parseBlock(t[4]),
};
}
function parsePrefixExpression(n: CrudeAST): LuaPrefixExpression {
const t = n as [string, ...CrudeAST[]];
switch (t[0]) {