commit 578600a1a721250792f3b70326d787323f8e9648
parent 2e5fdc2bd1ac20831c9f22b1c48ff68796d4c2a4
Author: erai <erai@omiltem.net>
Date: Sun, 20 Apr 2025 10:36:30 -0400
compute lalr lookahead
Diffstat:
M | cc0.c | | | 772 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
M | lalr.om | | | 496 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 1205 insertions(+), 63 deletions(-)
diff --git a/cc0.c b/cc0.c
@@ -146,16 +146,22 @@ u zirreset();
u zirreturn();
u ziruseop();
u zlabels_to_ir();
+u zlalr_add_first();
+u zlalr_addlook();
u zlalr_alt();
u zlalr_alt_nonterminal();
u zlalr_alt_terminal();
u zlalr_assoc();
u zlalr_compiler();
+u zlalr_finditem();
+u zlalr_findout();
+u zlalr_first();
u zlalr_goto();
u zlalr_itemcmp();
u zlalr_items();
u zlalr_itemsetcmp();
u zlalr_linkout();
+u zlalr_lookahead();
u zlalr_lookup();
u zlalr_memoset();
u zlalr_mkalt();
@@ -166,6 +172,8 @@ u zlalr_pointcmp();
u zlalr_primary();
u zlalr_rules();
u zlalr_suffix();
+u zlalr_union_first();
+u zlalr_unionlook();
u zlayout_struct();
u zlayout_union();
u zleave();
@@ -26203,6 +26211,124 @@ b34: goto b7;
b5: v4 = 1UL;
goto b6;
}
+u zlalr_add_first(u vlc, u vout, u vsym) {
+ u vp = 0;
+ u vlink = 0;
+ u vd = 0;
+ u vdir = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ u v10 = 0;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ u v18 = 0;
+ u v19 = 0;
+ u v20 = 0;
+ u v21 = 0;
+ vp = 0UL;
+ vlink = vout;
+b1: vd = *(u*)vlink;
+ if (!vd) goto b7;
+ v7 = 0UL;
+b8: if (!v7) goto b5;
+ v12 = (u)zalloc;
+ v13 = *(u*)(vlc + 0UL);
+ v14 = 64UL;
+ v15 = ((u(*)())v12)(v13, v14);
+ vd = v15;
+ *(u*)(vd + 32UL) = *(u*)(vsym + 32UL);
+ *(u*)(vd + 40UL) = *(u*)(vsym + 40UL);
+ *(u*)(vd + 48UL) = *(u*)(vsym + 48UL);
+ v16 = (u)zrb_link;
+ v17 = vout;
+ v18 = vlink;
+ v19 = vp;
+ v20 = vd + 0UL;
+ v21 = ((u(*)())v16)(v17, v18, v19, v20);
+ v21;
+ return 1UL;
+b5: v8 = (u)zlalr_pointcmp;
+ v9 = vsym;
+ v10 = vd;
+ v11 = ((u(*)())v8)(v9, v10);
+ vdir = v11;
+ if ((s)vdir >= (s)0UL) goto b12;
+ vlink = vd + 0UL + 16UL;
+ vp = vd + 0UL;
+b10: goto b1;
+b12: if ((s)vdir <= (s)0UL) goto b14;
+ vlink = vd + 0UL + 24UL;
+ vp = vd + 0UL;
+ goto b10;
+b14: return 0UL;
+b7: v7 = 1UL;
+ goto b8;
+}
+u zlalr_addlook(u vlc, u vout, u vsym) {
+ u vp = 0;
+ u vlink = 0;
+ u vd = 0;
+ u vdir = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ u v10 = 0;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ u v18 = 0;
+ u v19 = 0;
+ u v20 = 0;
+ u v21 = 0;
+ vp = 0UL;
+ vlink = vout;
+b1: vd = *(u*)vlink;
+ if (!vd) goto b7;
+ v7 = 0UL;
+b8: if (!v7) goto b5;
+ v12 = (u)zalloc;
+ v13 = *(u*)(vlc + 0UL);
+ v14 = 64UL;
+ v15 = ((u(*)())v12)(v13, v14);
+ vd = v15;
+ *(u*)(vd + 32UL) = *(u*)(vsym + 32UL);
+ *(u*)(vd + 40UL) = *(u*)(vsym + 40UL);
+ *(u*)(vd + 48UL) = *(u*)(vsym + 48UL);
+ v16 = (u)zrb_link;
+ v17 = vout;
+ v18 = vlink;
+ v19 = vp;
+ v20 = vd + 0UL;
+ v21 = ((u(*)())v16)(v17, v18, v19, v20);
+ v21;
+ return 1UL;
+b5: v8 = (u)zlalr_pointcmp;
+ v9 = vsym;
+ v10 = vd;
+ v11 = ((u(*)())v8)(v9, v10);
+ vdir = v11;
+ if ((s)vdir >= (s)0UL) goto b12;
+ vlink = vd + 0UL + 16UL;
+ vp = vd + 0UL;
+b10: goto b1;
+b12: if ((s)vdir <= (s)0UL) goto b14;
+ vlink = vd + 0UL + 24UL;
+ vp = vd + 0UL;
+ goto b10;
+b14: return 0UL;
+b7: v7 = 1UL;
+ goto b8;
+}
u zlalr_alt(u vlc, u va, u vpn) {
u v3 = 0;
u v4 = 0;
@@ -26227,27 +26353,42 @@ b7: v3 = 1UL;
goto b8;
}
u zlalr_alt_nonterminal(u vlc, u va, u vs) {
+ u vuse[9] = {0};
u vi = 0;
- u v4 = 0;
u v5 = 0;
u v6 = 0;
u v7 = 0;
u v8 = 0;
u v9 = 0;
u v10 = 0;
- v4 = (u)zensure_arr;
- v5 = *(u*)(vlc + 0UL);
- v6 = va + 0UL;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ v5 = (u)zensure_arr;
+ v6 = *(u*)(vlc + 0UL);
v7 = va + 16UL;
- v8 = *(u*)(va + 8UL) + 1UL;
- v9 = 64UL;
- v10 = ((u(*)())v4)(v5, v6, v7, v8, v9);
- v10;
- vi = *(u*)(va + 8UL);
- *(u*)(va + 8UL) = *(u*)(va + 8UL) + 1UL;
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 32UL) = 0UL;
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 40UL) = *(u*)(vs + 32UL);
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 48UL) = *(u*)(vs + 40UL);
+ v8 = va + 32UL;
+ v9 = *(u*)(va + 24UL) + 1UL;
+ v10 = 64UL;
+ v11 = ((u(*)())v5)(v6, v7, v8, v9, v10);
+ v11;
+ vi = *(u*)(va + 24UL);
+ *(u*)(va + 24UL) = *(u*)(va + 24UL) + 1UL;
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 32UL) = 0UL;
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 40UL) = *(u*)(vs + 32UL);
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 48UL) = *(u*)(vs + 40UL);
+ *(u*)((u)vuse + 40UL) = *(u*)(va + 0UL);
+ *(u*)((u)vuse + 48UL) = 0UL;
+ *(u*)((u)vuse + 56UL) = 0UL;
+ v12 = (u)zlalr_assoc;
+ v13 = vlc;
+ v14 = *(u*)(vs + 48UL);
+ v15 = (u)vuse;
+ v16 = ((u(*)())v12)(v13, v14, v15);
+ v16;
return 0UL;
}
u zlalr_alt_terminal(u vlc, u va, u vname, u vid) {
@@ -26261,17 +26402,17 @@ u zlalr_alt_terminal(u vlc, u va, u vname, u vid) {
u v11 = 0;
v5 = (u)zensure_arr;
v6 = *(u*)(vlc + 0UL);
- v7 = va + 0UL;
- v8 = va + 16UL;
- v9 = *(u*)(va + 8UL) + 1UL;
+ v7 = va + 16UL;
+ v8 = va + 32UL;
+ v9 = *(u*)(va + 24UL) + 1UL;
v10 = 64UL;
v11 = ((u(*)())v5)(v6, v7, v8, v9, v10);
v11;
- vi = *(u*)(va + 8UL);
- *(u*)(va + 8UL) = *(u*)(va + 8UL) + 1UL;
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 32UL) = 1UL;
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 40UL) = vid;
- *(u*)(*(u*)(va + 0UL) + vi * 64UL + 48UL) = vname;
+ vi = *(u*)(va + 24UL);
+ *(u*)(va + 24UL) = *(u*)(va + 24UL) + 1UL;
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 32UL) = 1UL;
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 40UL) = vid;
+ *(u*)(*(u*)(va + 16UL) + vi * 64UL + 48UL) = vname;
return 0UL;
}
u zlalr_assoc(u vlc, u vi, u vt) {
@@ -26302,7 +26443,7 @@ b1: vd = *(u*)vlink;
b8: if (!v7) goto b5;
v12 = (u)zalloc;
v13 = *(u*)(vlc + 0UL);
- v14 = 64UL;
+ v14 = 72UL;
v15 = ((u(*)())v12)(v13, v14);
vd = v15;
*(u*)(vd + 40UL) = *(u*)(vt + 40UL);
@@ -26334,7 +26475,7 @@ b7: v7 = 1UL;
goto b8;
}
u zlalr_compiler(u vc, u vpn, u verr) {
- u v_lc[11] = {0};
+ u v_lc[12] = {0};
u vlc = 0;
u v5 = 0;
u v6 = 0;
@@ -26343,6 +26484,12 @@ u zlalr_compiler(u vc, u vpn, u verr) {
u v9 = 0;
u v10 = 0;
u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
vlc = (u)v_lc;
*(u*)(vlc + 0UL) = *(u*)(vc + 0UL);
*(u*)(vlc + 8UL) = vc;
@@ -26356,8 +26503,224 @@ u zlalr_compiler(u vc, u vpn, u verr) {
v10 = vlc;
v11 = ((u(*)())v9)(v10);
v11;
+ v12 = (u)zlalr_first;
+ v13 = vlc;
+ v14 = ((u(*)())v12)(v13);
+ v14;
+ v15 = (u)zlalr_lookahead;
+ v16 = vlc;
+ v17 = ((u(*)())v15)(v16);
+ v17;
+ return 0UL;
+}
+u zlalr_finditem(u vlc, u vitemset, u vitem) {
+ u vt = 0;
+ u vdir = 0;
+ u v5 = 0;
+ u v6 = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ vt = *(u*)(vitemset + 32UL);
+b1: if (!vt) goto b7;
+ v5 = 0UL;
+b8: if (!v5) goto b5;
+ return 0UL;
+b5: v6 = (u)zlalr_itemcmp;
+ v7 = vitem;
+ v8 = vt;
+ v9 = ((u(*)())v6)(v7, v8);
+ vdir = v9;
+ if ((s)vdir >= (s)0UL) goto b12;
+ vt = *(u*)(vt + 0UL + 16UL);
+b10: goto b1;
+b12: if ((s)vdir <= (s)0UL) goto b14;
+ vt = *(u*)(vt + 0UL + 24UL);
+ goto b10;
+b14: return vt;
+b7: v5 = 1UL;
+ goto b8;
+}
+u zlalr_findout(u vlc, u vw, u vsym) {
+ u vd = 0;
+ u vr[9] = {0};
+ u vdir = 0;
+ u v6 = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ vd = *(u*)(*(u*)(vw + 80UL) + 48UL);
+b1: v6 = (u)zlalr_pointcmp;
+ v7 = vsym;
+ v8 = vd;
+ v9 = ((u(*)())v6)(v7, v8);
+ vdir = v9;
+ if ((s)vdir >= (s)0UL) goto b6;
+ vd = *(u*)(vd + 0UL + 16UL);
+b4: goto b1;
+b6: if ((s)vdir <= (s)0UL) goto b8;
+ vd = *(u*)(vd + 0UL + 24UL);
+ goto b4;
+b8: *(u*)(vw + 80UL) = *(u*)(vd + 56UL);
+ *(u*)(vw + 8UL + 56UL) = *(u*)(vw + 8UL + 56UL) + 1UL;
return 0UL;
}
+u zlalr_first(u vlc) {
+ u vuse = 0;
+ u vp = 0;
+ u vqueue = 0;
+ u vprod = 0;
+ u valt = 0;
+ u vsym = 0;
+ u vref = 0;
+ u vi = 0;
+ u vj = 0;
+ u vk = 0;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ u v18 = 0;
+ u v19 = 0;
+ u v20 = 0;
+ u v21 = 0;
+ u v22 = 0;
+ u v23 = 0;
+ u v24 = 0;
+ u v25 = 0;
+ u v26 = 0;
+ u v27 = 0;
+ u v28 = 0;
+ u v29 = 0;
+ u v30 = 0;
+ u v31 = 0;
+ u v32 = 0;
+ u v33 = 0;
+ u v34 = 0;
+ u v35 = 0;
+ u v36 = 0;
+ u v37 = 0;
+ u v38 = 0;
+ vi = 0UL;
+b1: if (vi != *(u*)(vlc + 40UL)) goto b5;
+b18: vp = vqueue;
+ if (!vp) goto b24;
+ v16 = 0UL;
+b25: if (!v16) goto b22;
+ return 0UL;
+b22: *(u*)(vp + 72UL) = 0UL;
+ vqueue = *(u*)(vp + 80UL);
+ v17 = (u)zrb_first;
+ v18 = *(u*)(*(u*)(vp + 48UL) + 32UL);
+ v19 = ((u(*)())v17)(v18);
+ vuse = v19;
+b27: if (!vuse) goto b33;
+ v20 = 0UL;
+b34: if (!v20) goto b31;
+ goto b18;
+b31: vi = *(u*)(vuse + 40UL);
+ vprod = *(u*)(*(u*)(vlc + 32UL) + vi * 8UL);
+ vj = 0UL;
+b35: if (vj != *(u*)(vprod + 96UL)) goto b39;
+ v36 = (u)zrb_next;
+ v37 = vuse + 0UL;
+ v38 = ((u(*)())v36)(v37);
+ vuse = v38;
+ goto b27;
+b39: valt = *(u*)(*(u*)(vprod + 88UL) + vj * 8UL);
+ vk = 0UL;
+b40: if (vk != *(u*)(valt + 24UL)) goto b44;
+ if (!*(u*)(vprod + 56UL)) goto b49;
+ v21 = 0UL;
+b50: if (!v21) goto b47;
+ *(u*)(vprod + 56UL) = 1UL;
+ if (!*(u*)(vprod + 72UL)) goto b55;
+ v22 = 0UL;
+b56: if (!v22) goto b53;
+ *(u*)(vprod + 72UL) = 1UL;
+ *(u*)(vprod + 80UL) = vqueue;
+ vqueue = vprod;
+b51:b45:b41: vj = vj + 1UL;
+ goto b35;
+b53: goto b51;
+b55: v22 = 1UL;
+ goto b56;
+b47: goto b45;
+b49: v21 = 1UL;
+ goto b50;
+b44: vsym = *(u*)(valt + 16UL) + vk * 64UL;
+ if (!*(u*)(vsym + 32UL)) goto b59;
+ v23 = (u)zlalr_add_first;
+ v24 = vlc;
+ v25 = vprod + 64UL;
+ v26 = vsym;
+ v27 = ((u(*)())v23)(v24, v25, v26);
+ if (!v27) goto b62;
+ if (!*(u*)(vprod + 72UL)) goto b68;
+ v28 = 0UL;
+b69: if (!v28) goto b66;
+ *(u*)(vprod + 72UL) = 1UL;
+ *(u*)(vprod + 80UL) = vqueue;
+ vqueue = vprod;
+b64:b60: goto b41;
+b66: goto b64;
+b68: v28 = 1UL;
+ goto b69;
+b62: goto b60;
+b59: vref = *(u*)(*(u*)(vlc + 32UL) + *(u*)(vsym + 40UL) * 8UL);
+ v29 = (u)zlalr_union_first;
+ v30 = vlc;
+ v31 = vprod + 64UL;
+ v32 = *(u*)(vref + 64UL);
+ v33 = ((u(*)())v29)(v30, v31, v32);
+ if (!v33) goto b72;
+ if (!*(u*)(vprod + 72UL)) goto b78;
+ v34 = 0UL;
+b79: if (!v34) goto b76;
+ *(u*)(vprod + 72UL) = 1UL;
+ *(u*)(vprod + 80UL) = vqueue;
+ vqueue = vprod;
+b74:b70: if (!*(u*)(vref + 56UL)) goto b84;
+ v35 = 0UL;
+b85: if (!v35) goto b82;
+ goto b41;
+b82: vk = vk + 1UL;
+ goto b40;
+b84: v35 = 1UL;
+ goto b85;
+b76: goto b74;
+b78: v34 = 1UL;
+ goto b79;
+b72: goto b70;
+b33: v20 = 1UL;
+ goto b34;
+b24: v16 = 1UL;
+ goto b25;
+b5: vj = 0UL;
+b6: if (vj != *(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 96UL)) goto b10;
+ *(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 72UL) = 1UL;
+ *(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 80UL) = vqueue;
+ vqueue = *(u*)(*(u*)(vlc + 32UL) + vi * 8UL);
+ vi = vi + 1UL;
+ goto b1;
+b10: if (*(u*)(*(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 88UL) + vj * 8UL) + 24UL) != 0UL) goto b13;
+ *(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 56UL) = 1UL;
+ vj = vj + 1UL;
+ goto b6;
+b13: if (!*(u*)(*(u*)(*(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 88UL) + vj * 8UL) + 16UL) + 0UL * 64UL + 32UL)) goto b16;
+ v11 = (u)zlalr_addlook;
+ v12 = vlc;
+ v13 = *(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 64UL;
+ v14 = *(u*)(*(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + vi * 8UL) + 88UL) + vj * 8UL) + 16UL) + 0UL * 64UL;
+ v15 = ((u(*)())v11)(v12, v13, v14);
+ v15;
+b14: vj = vj + 1UL;
+ goto b6;
+b16: goto b14;
+}
u zlalr_goto(u vlc, u vi) {
u vt = 0;
u va = 0;
@@ -26366,7 +26729,7 @@ u zlalr_goto(u vlc, u vi) {
u vprod = 0;
u valt = 0;
u vsym = 0;
- u vr[8] = {0};
+ u vr[9] = {0};
u vj = 0;
u v11 = 0;
u v12 = 0;
@@ -26447,10 +26810,10 @@ b46: v47 = (u)zlalr_memoset;
b48: v46 = 1UL;
goto b49;
b20: vqueue = *(u*)(vt + 32UL);
- valt = *(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + *(u*)(vt + 40UL) * 8UL) + 48UL) + *(u*)(vt + 48UL) * 8UL);
- if (*(u*)(vt + 56UL) != *(u*)(valt + 8UL)) goto b26;
+ valt = *(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + *(u*)(vt + 40UL) * 8UL) + 88UL) + *(u*)(vt + 48UL) * 8UL);
+ if (*(u*)(vt + 56UL) != *(u*)(valt + 24UL)) goto b26;
goto b16;
-b26: vsym = *(u*)(valt + 0UL) + *(u*)(vt + 56UL) * 64UL;
+b26: vsym = *(u*)(valt + 16UL) + *(u*)(vt + 56UL) * 64UL;
*(u*)((u)vr + 40UL) = *(u*)(vt + 40UL);
*(u*)((u)vr + 48UL) = *(u*)(vt + 48UL);
*(u*)((u)vr + 56UL) = *(u*)(vt + 56UL) + 1UL;
@@ -26471,7 +26834,7 @@ b26: vsym = *(u*)(valt + 0UL) + *(u*)(vt + 56UL) * 64UL;
goto b16;
b31: vprod = *(u*)(*(u*)(vlc + 32UL) + *(u*)(vsym + 40UL) * 8UL);
vj = 0UL;
-b32: if (vj != *(u*)(vprod + 56UL)) goto b36;
+b32: if (vj != *(u*)(vprod + 96UL)) goto b36;
goto b16;
b36: *(u*)((u)vr + 40UL) = *(u*)(vsym + 40UL);
*(u*)((u)vr + 48UL) = vj;
@@ -26525,7 +26888,7 @@ b13: return 0UL;
}
u zlalr_items(u vlc) {
u vi = 0;
- u vinit_state[8] = {0};
+ u vinit_state[9] = {0};
u v3 = 0;
u v4 = 0;
u v5 = 0;
@@ -26557,13 +26920,13 @@ u zlalr_items(u vlc) {
v12 = vlc;
v13 = vi;
v14 = ((u(*)())v11)(v12, v13);
- *(u*)(vlc + 64UL) = v14;
-b4: vi = *(u*)(vlc + 72UL);
+ *(u*)(vlc + 72UL) = v14;
+b4: vi = *(u*)(vlc + 80UL);
if (!vi) goto b10;
v15 = 0UL;
b11: if (!v15) goto b8;
return 0UL;
-b8: *(u*)(vlc + 72UL) = *(u*)(vi + 40UL);
+b8: *(u*)(vlc + 80UL) = *(u*)(vi + 40UL);
v16 = (u)zlalr_goto;
v17 = vlc;
v18 = vi;
@@ -26678,37 +27041,42 @@ u zlalr_linkout(u vlc, u vout, u vsym, u vt) {
u v28 = 0;
u v29 = 0;
u v30 = 0;
+ u v31 = 0;
+ u v32 = 0;
+ u v33 = 0;
+ u v34 = 0;
+ u v35 = 0;
vp = 0UL;
vlink = vout;
b1: vd = *(u*)vlink;
if (!vd) goto b7;
v8 = 0UL;
b8: if (!v8) goto b5;
- v13 = (u)zalloc;
- v14 = *(u*)(vlc + 0UL);
- v15 = 64UL;
- v16 = ((u(*)())v13)(v14, v15);
- vd = v16;
+ v18 = (u)zalloc;
+ v19 = *(u*)(vlc + 0UL);
+ v20 = 64UL;
+ v21 = ((u(*)())v18)(v19, v20);
+ vd = v21;
*(u*)(vd + 32UL) = *(u*)(vsym + 32UL);
*(u*)(vd + 40UL) = *(u*)(vsym + 40UL);
*(u*)(vd + 48UL) = *(u*)(vsym + 48UL);
- v17 = (u)zlalr_mkitemset;
- v18 = vlc;
- v19 = ((u(*)())v17)(v18);
- *(u*)(vd + 56UL) = v19;
- v20 = (u)zrb_link;
- v21 = vout;
- v22 = vlink;
- v23 = vp;
- v24 = vd + 0UL;
- v25 = ((u(*)())v20)(v21, v22, v23, v24);
- v25;
- v26 = (u)zlalr_assoc;
- v27 = vlc;
- v28 = *(u*)(vd + 56UL);
- v29 = vt;
- v30 = ((u(*)())v26)(v27, v28, v29);
+ v22 = (u)zlalr_mkitemset;
+ v23 = vlc;
+ v24 = ((u(*)())v22)(v23);
+ *(u*)(vd + 56UL) = v24;
+ v25 = (u)zrb_link;
+ v26 = vout;
+ v27 = vlink;
+ v28 = vp;
+ v29 = vd + 0UL;
+ v30 = ((u(*)())v25)(v26, v27, v28, v29);
v30;
+ v31 = (u)zlalr_assoc;
+ v32 = vlc;
+ v33 = *(u*)(vd + 56UL);
+ v34 = vt;
+ v35 = ((u(*)())v31)(v32, v33, v34);
+ v35;
return 0UL;
b5: v9 = (u)zlalr_pointcmp;
v10 = vsym;
@@ -26723,10 +27091,179 @@ b12: if ((s)vdir <= (s)0UL) goto b14;
vlink = vd + 0UL + 24UL;
vp = vd + 0UL;
goto b10;
-b14: return 0UL;
+b14: v13 = (u)zlalr_assoc;
+ v14 = vlc;
+ v15 = *(u*)(vd + 56UL);
+ v16 = vt;
+ v17 = ((u(*)())v13)(v14, v15, v16);
+ v17;
+ return 0UL;
b7: v8 = 1UL;
goto b8;
}
+u zlalr_lookahead(u vlc) {
+ u vqueue = 0;
+ u vw = 0;
+ u vq = 0;
+ u vr[8] = {0};
+ u vsym = 0;
+ u vrest_sym = 0;
+ u valt = 0;
+ u vprod = 0;
+ u vrest_prod = 0;
+ u vi = 0;
+ u vj = 0;
+ u vk = 0;
+ u vepsilon = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ u v18 = 0;
+ u v19 = 0;
+ u v20 = 0;
+ u v21 = 0;
+ u v22 = 0;
+ u v23 = 0;
+ u v24 = 0;
+ u v25 = 0;
+ u v26 = 0;
+ u v27 = 0;
+ u v28 = 0;
+ u v29 = 0;
+ u v30 = 0;
+ u v31 = 0;
+ u v32 = 0;
+ u v33 = 0;
+ u v34 = 0;
+ u v35 = 0;
+ u v36 = 0;
+ u v37 = 0;
+ u v38 = 0;
+ u v39 = 0;
+ u v40 = 0;
+ u v41 = 0;
+ u v42 = 0;
+ *(u*)((u)vr + 32UL) = 1UL;
+ *(u*)((u)vr + 40UL) = -1UL;
+ *(u*)((u)vr + 48UL) = (u)"$";
+ v14 = (u)zalloc;
+ v15 = *(u*)(vlc + 0UL);
+ v16 = 104UL;
+ v17 = ((u(*)())v14)(v15, v16);
+ vw = v17;
+ *(u*)(vw + 8UL + 40UL) = 0UL;
+ *(u*)(vw + 8UL + 48UL) = 0UL;
+ *(u*)(vw + 8UL + 56UL) = 0UL;
+ *(u*)(vw + 80UL) = *(u*)(vlc + 72UL);
+ *(u*)(vw + 88UL) = vw + 96UL;
+ *(u*)(vw + 96UL) = (u)vr + 0UL;
+ vqueue = vw;
+b2: vw = vqueue;
+ if (!vw) goto b8;
+ v18 = 0UL;
+b9: if (!v18) goto b6;
+ return 0UL;
+b6: v20 = (u)zlalr_unionlook;
+ v21 = vlc;
+ v22 = vw;
+ v23 = ((u(*)())v20)(v21, v22);
+ if (!v23) goto b14;
+ v19 = 0UL;
+b15: if (!v19) goto b12;
+ vqueue = *(u*)(vw + 0UL);
+ goto b2;
+b12: valt = *(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + *(u*)(vw + 8UL + 40UL) * 8UL) + 88UL) + *(u*)(vw + 8UL + 48UL) * 8UL);
+ if (*(u*)(vw + 8UL + 56UL) != *(u*)(valt + 24UL)) goto b19;
+ vqueue = *(u*)(vw + 0UL);
+ goto b2;
+b19: vi = *(u*)(vw + 80UL);
+ vsym = *(u*)(valt + 16UL) + *(u*)(vw + 8UL + 56UL) * 64UL;
+ v24 = (u)zlalr_findout;
+ v25 = vlc;
+ v26 = vw;
+ v27 = vsym;
+ v28 = ((u(*)())v24)(v25, v26, v27);
+ v28;
+ if (!*(u*)(vsym + 32UL)) goto b23;
+ goto b2;
+b23: vprod = *(u*)(*(u*)(vlc + 32UL) + *(u*)(vsym + 40UL) * 8UL);
+ vepsilon = 1UL;
+ vj = 0UL;
+b24: if (vj != *(u*)(vprod + 96UL)) goto b28;
+ if (!vepsilon) goto b49;
+ v38 = 0UL;
+b50: if (!v38) goto b47;
+ goto b2;
+b47: vj = 0UL;
+b51: if (vj != *(u*)(vprod + 96UL)) goto b55;
+ goto b2;
+b55: valt = *(u*)(*(u*)(vprod + 88UL) + vj * 8UL);
+ v39 = (u)zalloc;
+ v40 = *(u*)(vlc + 0UL);
+ v41 = 104UL;
+ v42 = ((u(*)())v39)(v40, v41);
+ vq = v42;
+ *(u*)(vq + 8UL + 40UL) = *(u*)(vsym + 40UL);
+ *(u*)(vq + 8UL + 48UL) = vj;
+ *(u*)(vq + 8UL + 56UL) = 0UL;
+ *(u*)(vq + 80UL) = vi;
+ *(u*)(vq + 88UL) = *(u*)(vw + 88UL);
+ *(u*)(vq + 0UL) = vqueue;
+ vqueue = vq;
+ vj = vj + 1UL;
+ goto b51;
+b49: v38 = 1UL;
+ goto b50;
+b28: valt = *(u*)(*(u*)(vprod + 88UL) + vj * 8UL);
+ vk = *(u*)(vw + 8UL + 56UL);
+b29: if (vk != *(u*)(*(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + *(u*)(vw + 8UL + 40UL) * 8UL) + 88UL) + *(u*)(vw + 8UL + 48UL) * 8UL) + 24UL)) goto b33;
+b30: vj = vj + 1UL;
+ goto b24;
+b33: vrest_sym = *(u*)(*(u*)(*(u*)(*(u*)(*(u*)(vlc + 32UL) + *(u*)(vw + 8UL + 40UL) * 8UL) + 88UL) + *(u*)(vw + 8UL + 48UL) * 8UL) + 16UL) + vk * 64UL;
+ if (!*(u*)(vrest_sym + 32UL)) goto b36;
+ v29 = (u)zalloc;
+ v30 = *(u*)(vlc + 0UL);
+ v31 = 104UL;
+ v32 = ((u(*)())v29)(v30, v31);
+ vq = v32;
+ *(u*)(vq + 8UL + 40UL) = *(u*)(vsym + 40UL);
+ *(u*)(vq + 8UL + 48UL) = vj;
+ *(u*)(vq + 8UL + 56UL) = 0UL;
+ *(u*)(vq + 80UL) = vi;
+ *(u*)(vq + 88UL) = vq + 96UL;
+ *(u*)(vq + 96UL) = vrest_sym + 0UL;
+ *(u*)(vq + 0UL) = vqueue;
+ vqueue = vq;
+ vepsilon = 0UL;
+ goto b30;
+b36: vrest_prod = *(u*)(*(u*)(vlc + 32UL) + *(u*)(vrest_sym + 40UL) * 8UL);
+ v33 = (u)zalloc;
+ v34 = *(u*)(vlc + 0UL);
+ v35 = 104UL;
+ v36 = ((u(*)())v33)(v34, v35);
+ vq = v36;
+ *(u*)(vq + 8UL + 40UL) = *(u*)(vsym + 40UL);
+ *(u*)(vq + 8UL + 48UL) = vj;
+ *(u*)(vq + 8UL + 56UL) = 0UL;
+ *(u*)(vq + 80UL) = vi;
+ *(u*)(vq + 88UL) = vrest_prod + 64UL;
+ *(u*)(vq + 0UL) = vqueue;
+ vqueue = vq;
+ if (!*(u*)(vrest_prod + 56UL)) goto b43;
+ v37 = 0UL;
+b44: if (!v37) goto b41;
+ vepsilon = 0UL;
+ goto b30;
+b41: vk = vk + 1UL;
+ goto b29;
+b43: v37 = 1UL;
+ goto b44;
+b14: v19 = 1UL;
+ goto b15;
+b8: v18 = 1UL;
+ goto b9;
+}
u zlalr_lookup(u vlc, u vname, u vnew) {
u vp = 0;
u vlink = 0;
@@ -26820,8 +27357,8 @@ b8: if (!v6) goto b5;
v15 = vi + 0UL;
v16 = ((u(*)())v11)(v12, v13, v14, v15);
v16;
- *(u*)(vi + 40UL) = *(u*)(vlc + 72UL);
- *(u*)(vlc + 72UL) = vi;
+ *(u*)(vi + 40UL) = *(u*)(vlc + 80UL);
+ *(u*)(vlc + 80UL) = vi;
return vi;
b5: v7 = (u)zlalr_itemsetcmp;
v8 = vi;
@@ -26855,19 +27392,21 @@ u zlalr_mkalt(u vlc, u vp) {
u v13 = 0;
v3 = (u)zalloc;
v4 = *(u*)(vlc + 0UL);
- v5 = 24UL;
+ v5 = 40UL;
v6 = ((u(*)())v3)(v4, v5);
va = v6;
+ *(u*)(va + 8UL) = *(u*)(vp + 96UL);
+ *(u*)(va + 0UL) = *(u*)(vp + 32UL);
v7 = (u)zensure_arr;
v8 = *(u*)(vlc + 0UL);
- v9 = vp + 48UL;
- v10 = vp + 64UL;
- v11 = *(u*)(vp + 56UL) + 1UL;
+ v9 = vp + 88UL;
+ v10 = vp + 104UL;
+ v11 = *(u*)(vp + 96UL) + 1UL;
v12 = 8UL;
v13 = ((u(*)())v7)(v8, v9, v10, v11, v12);
v13;
- *(u*)(*(u*)(vp + 48UL) + *(u*)(vp + 56UL) * 8UL) = va;
- *(u*)(vp + 56UL) = *(u*)(vp + 56UL) + 1UL;
+ *(u*)(*(u*)(vp + 88UL) + *(u*)(vp + 96UL) * 8UL) = va;
+ *(u*)(vp + 96UL) = *(u*)(vp + 96UL) + 1UL;
return va;
}
u zlalr_mkitemset(u vlc) {
@@ -26896,6 +27435,9 @@ u zlalr_mkprod(u vlc) {
u v10 = 0;
u v11 = 0;
u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
v2 = (u)zensure_arr;
v3 = *(u*)(vlc + 0UL);
v4 = vlc + 32UL;
@@ -26906,10 +27448,14 @@ u zlalr_mkprod(u vlc) {
v8;
v9 = (u)zalloc;
v10 = *(u*)(vlc + 0UL);
- v11 = 72UL;
+ v11 = 112UL;
v12 = ((u(*)())v9)(v10, v11);
vp = v12;
*(u*)(vp + 32UL) = *(u*)(vlc + 40UL);
+ v13 = (u)zlalr_mkitemset;
+ v14 = vlc;
+ v15 = ((u(*)())v13)(v14);
+ *(u*)(vp + 48UL) = v15;
*(u*)(*(u*)(vlc + 32UL) + *(u*)(vlc + 40UL) * 8UL) = vp;
*(u*)(vlc + 40UL) = *(u*)(vlc + 40UL) + 1UL;
return vp;
@@ -27465,6 +28011,106 @@ b15: goto b9;
b7: v9 = 1UL;
goto b8;
}
+u zlalr_union_first(u vlc, u vout, u vsrc) {
+ u vs = 0;
+ u vt = 0;
+ u vret = 0;
+ u v6 = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ u v10 = 0;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ v6 = (u)zrb_first;
+ v7 = vsrc;
+ v8 = ((u(*)())v6)(v7);
+ vs = v8;
+b2: if (!vs) goto b8;
+ v9 = 0UL;
+b9: if (!v9) goto b6;
+ return vret;
+b6: v10 = (u)zlalr_add_first;
+ v11 = vlc;
+ v12 = vout;
+ v13 = vs;
+ v14 = ((u(*)())v10)(v11, v12, v13);
+ if (!v14) goto b12;
+ vret = 1UL;
+b10: v15 = (u)zrb_next;
+ v16 = vs;
+ v17 = ((u(*)())v15)(v16);
+ vs = v17;
+ goto b2;
+b12: goto b10;
+b8: v9 = 1UL;
+ goto b9;
+}
+u zlalr_unionlook(u vlc, u vw) {
+ u vs = 0;
+ u vt = 0;
+ u vret = 0;
+ u v5 = 0;
+ u v6 = 0;
+ u v7 = 0;
+ u v8 = 0;
+ u v9 = 0;
+ u v10 = 0;
+ u v11 = 0;
+ u v12 = 0;
+ u v13 = 0;
+ u v14 = 0;
+ u v15 = 0;
+ u v16 = 0;
+ u v17 = 0;
+ u v18 = 0;
+ u v19 = 0;
+ u v20 = 0;
+ u v21 = 0;
+ u v22 = 0;
+ if (*(u*)(vw + 8UL + 40UL) == 0UL) goto b5;
+ if (*(u*)(vw + 8UL + 56UL) != 0UL) goto b5;
+ v5 = 1UL;
+b7: if (!v5) goto b3;
+ return 1UL;
+b3: v6 = (u)zlalr_finditem;
+ v7 = vlc;
+ v8 = *(u*)(vw + 80UL);
+ v9 = vw + 8UL;
+ v10 = ((u(*)())v6)(v7, v8, v9);
+ vt = v10;
+ v11 = (u)zrb_first;
+ v12 = *(u*)*(u*)(vw + 88UL);
+ v13 = ((u(*)())v11)(v12);
+ vs = v13;
+b10: if (!vs) goto b16;
+ v14 = 0UL;
+b17: if (!v14) goto b14;
+ *(u*)(vw + 88UL) = vt + 64UL;
+ return vret;
+b14: v15 = (u)zlalr_addlook;
+ v16 = vlc;
+ v17 = vt + 64UL;
+ v18 = vs;
+ v19 = ((u(*)())v15)(v16, v17, v18);
+ if (!v19) goto b20;
+ vret = 1UL;
+b18: v20 = (u)zrb_next;
+ v21 = vs;
+ v22 = ((u(*)())v20)(v21);
+ vs = v22;
+ goto b10;
+b20: goto b18;
+b16: v14 = 1UL;
+ goto b17;
+b5: v5 = 0UL;
+ goto b7;
+}
u zlayout_struct(u vc, u vd) {
u vm = 0;
u voffset = 0;
diff --git a/lalr.om b/lalr.om
@@ -6,6 +6,7 @@ struct lalr_item {
prod: int;
alt: int;
point: int;
+ look: *rbnode;
}
struct lalr_itemset {
@@ -25,6 +26,8 @@ struct lalr_point {
}
struct lalr_alt {
+ prod: int;
+ id: int;
point: *lalr_point;
point_len: int;
point_cap: int;
@@ -35,6 +38,13 @@ struct lalr_prod {
id: int;
name: *byte;
+ use: *lalr_itemset;
+ epsilon: int;
+ first: *rbnode;
+
+ in_queue: int;
+ queue_next: *lalr_prod;
+
alt: **lalr_alt;
alt_len: int;
alt_cap: int;
@@ -51,6 +61,7 @@ struct lalr_compiler {
prod_cap: int;
sets: *rbnode;
+ first: *rbnode;
root: *lalr_itemset;
goto_queue: *lalr_itemset;
@@ -66,6 +77,8 @@ func lalr_compiler(c: *compiler, pn: *peg_node, err: *file) {
lc.err = err;
lalr_rules(lc, pn);
lalr_items(lc);
+ lalr_first(lc);
+ lalr_lookahead(lc);
}
func lalr_mkprod(lc: *lalr_compiler): *lalr_prod {
@@ -73,6 +86,7 @@ func lalr_mkprod(lc: *lalr_compiler): *lalr_prod {
ensure_arr(lc.a, (&lc.prod) as **void, &lc.prod_cap, lc.prod_len + 1, sizeof(*lc.prod));
p = alloc(lc.a, sizeof(*p)) as *lalr_prod;
p.id = lc.prod_len;
+ p.use = lalr_mkitemset(lc);
lc.prod[lc.prod_len] = p;
lc.prod_len = lc.prod_len + 1;
return p;
@@ -278,6 +292,8 @@ func lalr_primary(lc: *lalr_compiler, a: *lalr_alt, pn: *peg_node) {
func lalr_mkalt(lc: *lalr_compiler, p: *lalr_prod): *lalr_alt {
var a: *lalr_alt;
a = alloc(lc.a, sizeof(*a)) as *lalr_alt;
+ a.id = p.alt_len;
+ a.prod = p.id;
ensure_arr(lc.a, (&p.alt) as **void, &p.alt_cap, p.alt_len + 1, sizeof(*p.alt));
p.alt[p.alt_len] = a;
p.alt_len = p.alt_len + 1;
@@ -295,6 +311,7 @@ func lalr_alt_terminal(lc: *lalr_compiler, a: *lalr_alt, name: *byte, id: int) {
}
func lalr_alt_nonterminal(lc: *lalr_compiler, a: *lalr_alt, s: *lalr_prod) {
+ var use: lalr_item;
var i: int;
ensure_arr(lc.a, (&a.point) as **void, &a.point_cap, a.point_len + 1, sizeof(*a.point));
i = a.point_len;
@@ -302,6 +319,10 @@ func lalr_alt_nonterminal(lc: *lalr_compiler, a: *lalr_alt, s: *lalr_prod) {
a.point[i].term = 0;
a.point[i].id = s.id;
a.point[i].name = s.name;
+ use.prod = a.prod;
+ use.alt = 0;
+ use.point = 0;
+ lalr_assoc(lc, s.use, &use);
}
func lalr_show(lc: *lalr_compiler) {
@@ -575,6 +596,7 @@ func lalr_linkout(lc: *lalr_compiler, out: **rbnode, sym: *lalr_point, t: *lalr_
link = &d.node.right;
p = &d.node;
} else {
+ lalr_assoc(lc, d.out, t);
return;
}
}
@@ -625,6 +647,7 @@ func lalr_showlr2(lc: *lalr_compiler, i: *lalr_itemset): int {
var sym: *lalr_point;
var prod: *lalr_prod;
var alt: *lalr_alt;
+ var l: *lalr_point;
var j: int;
var out: *file;
var k: int;
@@ -676,6 +699,22 @@ func lalr_showlr2(lc: *lalr_compiler, i: *lalr_itemset): int {
}
fputs(out, "]");
+ if t.point == alt.point_len {
+ fputs(out, "{");
+ l = rb_first(t.look) as *lalr_point;
+ loop {
+ if !l {
+ break;
+ }
+ fputs(out, l.name);
+ l = rb_next(&l.node) as *lalr_point;
+ if l {
+ fputs(out, " ");
+ }
+ }
+ fputs(out, "}");
+ }
+
t = rb_next(&t.node) as *lalr_item;
if t {
@@ -707,3 +746,460 @@ func lalr_showlr2(lc: *lalr_compiler, i: *lalr_itemset): int {
return i.mark;
}
+
+struct lalr_look {
+ next: *lalr_look;
+ item: lalr_item;
+ itemset: *lalr_itemset;
+ look: **rbnode;
+ _look: *rbnode;
+}
+
+func lalr_lookahead(lc: *lalr_compiler) {
+ var queue: *lalr_look;
+ var w: *lalr_look;
+ var q: *lalr_look;
+ var r: lalr_point;
+ var sym: *lalr_point;
+ var rest_sym: *lalr_point;
+ var alt: *lalr_alt;
+ var prod: *lalr_prod;
+ var rest_prod: *lalr_prod;
+ var i: *lalr_itemset;
+ var j: int;
+ var k: int;
+ var epsilon: int;
+
+ r.term = 1;
+ r.id = -1;
+ r.name = "$";
+
+ w = alloc(lc.a, sizeof(*w)) as *lalr_look;
+ w.item.prod = 0;
+ w.item.alt = 0;
+ w.item.point = 0;
+ w.itemset = lc.root;
+ w.look = &w._look;
+ w._look = &r.node;
+ queue = w;
+
+ loop {
+ w = queue;
+ if !w {
+ break;
+ }
+
+ if !lalr_unionlook(lc, w) {
+ queue = w.next;
+ continue;
+ }
+
+ alt = lc.prod[w.item.prod].alt[w.item.alt];
+ if w.item.point == alt.point_len {
+ queue = w.next;
+ continue;
+ }
+
+ i = w.itemset;
+
+ sym = &alt.point[w.item.point];
+ lalr_findout(lc, w, sym);
+ if sym.term {
+ continue;
+ }
+ prod = lc.prod[sym.id];
+
+ epsilon = 1;
+ j = 0;
+ loop {
+ if j == prod.alt_len {
+ break;
+ }
+ alt = prod.alt[j];
+
+ k = w.item.point;
+ loop {
+ if k == lc.prod[w.item.prod].alt[w.item.alt].point_len {
+ break;
+ }
+ rest_sym = &lc.prod[w.item.prod].alt[w.item.alt].point[k];
+
+ if rest_sym.term {
+ q = alloc(lc.a, sizeof(*q)) as *lalr_look;
+ q.item.prod = sym.id;
+ q.item.alt = j;
+ q.item.point = 0;
+ q.itemset = i;
+ q.look = &q._look;
+ q._look = &rest_sym.node;
+ q.next = queue;
+ queue = q;
+ epsilon = 0;
+ break;
+ } else {
+ rest_prod = lc.prod[rest_sym.id];
+ q = alloc(lc.a, sizeof(*q)) as *lalr_look;
+ q.item.prod = sym.id;
+ q.item.alt = j;
+ q.item.point = 0;
+ q.itemset = i;
+ q.look = &rest_prod.first;
+ q.next = queue;
+ queue = q;
+ if !rest_prod.epsilon {
+ epsilon = 0;
+ break;
+ }
+ }
+
+ k = k + 1;
+ }
+
+ j = j + 1;
+ }
+
+ if !epsilon {
+ continue;
+ }
+
+ j = 0;
+ loop {
+ if j == prod.alt_len {
+ break;
+ }
+ alt = prod.alt[j];
+
+ q = alloc(lc.a, sizeof(*q)) as *lalr_look;
+ q.item.prod = sym.id;
+ q.item.alt = j;
+ q.item.point = 0;
+ q.itemset = i;
+ q.look = w.look;
+ q.next = queue;
+ queue = q;
+
+ j = j + 1;
+ }
+ }
+}
+
+func lalr_unionlook(lc: *lalr_compiler, w: *lalr_look): int {
+ var s: *rbnode;
+ var t: *lalr_item;
+ var ret: int;
+
+ if w.item.prod != 0 && w.item.point == 0 {
+ return 1;
+ }
+
+ t = lalr_finditem(lc, w.itemset, &w.item);
+
+ s = rb_first(*w.look);
+ loop {
+ if !s {
+ break;
+ }
+
+ if lalr_addlook(lc, &t.look, s as *lalr_point) {
+ ret = 1;
+ }
+
+ s = rb_next(s);
+ }
+
+ w.look = &t.look;
+ return ret;
+}
+
+func lalr_addlook(lc: *lalr_compiler, out: **rbnode, sym: *lalr_point): int {
+ var p: *rbnode;
+ var link: **rbnode;
+ var d: *lalr_point;
+ var dir: int;
+ p = nil;
+ link = out;
+ loop {
+ d = (*link) as *lalr_point;
+ if !d {
+ break;
+ }
+ dir = lalr_pointcmp(sym, d);
+ if dir < 0 {
+ link = &d.node.left;
+ p = &d.node;
+ } else if dir > 0 {
+ link = &d.node.right;
+ p = &d.node;
+ } else {
+ return 0;
+ }
+ }
+ d = alloc(lc.a, sizeof(*d)) as *lalr_point;
+ d.term = sym.term;
+ d.id = sym.id;
+ d.name = sym.name;
+ rb_link(out, link, p, &d.node);
+ return 1;
+}
+
+func lalr_findout(lc: *lalr_compiler, w: *lalr_look, sym: *lalr_point) {
+ var d: *lalr_point;
+ var r: lalr_item;
+ var dir: int;
+ d = w.itemset.goto_out as *lalr_point;
+ loop {
+ dir = lalr_pointcmp(sym, d);
+ if dir < 0 {
+ d = d.node.left as *lalr_point;
+ } else if dir > 0 {
+ d = d.node.right as *lalr_point;
+ } else {
+ break;
+ }
+ }
+ w.itemset = d.out;
+ w.item.point = w.item.point + 1;
+}
+
+func lalr_finditem(lc: *lalr_compiler, itemset: *lalr_itemset, item: *lalr_item): *lalr_item {
+ var t: *lalr_item;
+ var dir: int;
+ t = (*itemset).items as *lalr_item;
+ loop {
+ if !t {
+ return nil;
+ }
+ dir = lalr_itemcmp(item, t);
+ if dir < 0 {
+ t = t.node.left as *lalr_item;
+ } else if dir > 0 {
+ t = t.node.right as *lalr_item;
+ } else {
+ return t;
+ }
+ }
+}
+
+func lalr_first(lc: *lalr_compiler) {
+ var use: *lalr_item;
+ var p: *lalr_prod;
+ var queue: *lalr_prod;
+ var prod: *lalr_prod;
+ var alt: *lalr_alt;
+ var sym: *lalr_point;
+ var ref: *lalr_prod;
+ var i: int;
+ var j: int;
+ var k: int;
+
+ i = 0;
+ loop {
+ if i == lc.prod_len {
+ break;
+ }
+
+ j = 0;
+ loop {
+ if j == lc.prod[i].alt_len {
+ break;
+ }
+
+ if lc.prod[i].alt[j].point_len == 0 {
+ lc.prod[i].epsilon = 1;
+ j = j + 1;
+ continue;
+ }
+
+ if lc.prod[i].alt[j].point[0].term {
+ lalr_addlook(lc, &lc.prod[i].first, &lc.prod[i].alt[j].point[0]);
+ }
+
+ j = j + 1;
+ }
+
+ lc.prod[i].in_queue = 1;
+ lc.prod[i].queue_next = queue;
+ queue = lc.prod[i];
+
+ i = i + 1;
+ }
+
+ loop {
+ p = queue;
+ if !p {
+ break;
+ }
+ p.in_queue = 0;
+ queue = p.queue_next;
+
+ use = rb_first(p.use.items) as *lalr_item;
+ loop {
+ if !use {
+ break;
+ }
+ i = use.prod;
+ prod = lc.prod[i];
+
+ j = 0;
+ loop {
+ if j == prod.alt_len {
+ break;
+ }
+ alt = prod.alt[j];
+
+ k = 0;
+ loop {
+ if k == alt.point_len {
+ if !prod.epsilon {
+ prod.epsilon = 1;
+ if !prod.in_queue {
+ prod.in_queue = 1;
+ prod.queue_next = queue;
+ queue = prod;
+ }
+ }
+ break;
+ }
+ sym = &alt.point[k];
+
+ if sym.term {
+ if lalr_add_first(lc, &prod.first, sym) {
+ if !prod.in_queue {
+ prod.in_queue = 1;
+ prod.queue_next = queue;
+ queue = prod;
+ }
+ }
+ break;
+ } else {
+ ref = lc.prod[sym.id];
+
+ if lalr_union_first(lc, &prod.first, ref.first) {
+ if !prod.in_queue {
+ prod.in_queue = 1;
+ prod.queue_next = queue;
+ queue = prod;
+ }
+ }
+
+ if !ref.epsilon {
+ break;
+ }
+ }
+
+ k = k + 1;
+ }
+
+ j = j + 1;
+ }
+
+ use = rb_next(&use.node) as *lalr_item;
+ }
+ }
+}
+
+func lalr_add_first(lc: *lalr_compiler, out: **rbnode, sym: *lalr_point): int {
+ var p: *rbnode;
+ var link: **rbnode;
+ var d: *lalr_point;
+ var dir: int;
+ p = nil;
+ link = out;
+ loop {
+ d = (*link) as *lalr_point;
+ if !d {
+ break;
+ }
+ dir = lalr_pointcmp(sym, d);
+ if dir < 0 {
+ link = &d.node.left;
+ p = &d.node;
+ } else if dir > 0 {
+ link = &d.node.right;
+ p = &d.node;
+ } else {
+ return 0;
+ }
+ }
+ d = alloc(lc.a, sizeof(*d)) as *lalr_point;
+ d.term = sym.term;
+ d.id = sym.id;
+ d.name = sym.name;
+ rb_link(out, link, p, &d.node);
+ return 1;
+}
+
+func lalr_union_first(lc: *lalr_compiler, out: **rbnode, src: *rbnode): int {
+ var s: *rbnode;
+ var t: *lalr_item;
+ var ret: int;
+
+ s = rb_first(src);
+ loop {
+ if !s {
+ break;
+ }
+
+ if lalr_add_first(lc, out, s as *lalr_point) {
+ ret = 1;
+ }
+
+ s = rb_next(s);
+ }
+
+ return ret;
+}
+
+func lalr_show_first(lc: *lalr_compiler) {
+ var i: int;
+ var p: *lalr_prod;
+ var d: *lalr_point;
+ var out: *file;
+
+ i = 0;
+ loop {
+ if i == lc.prod_len {
+ break;
+ }
+ p = lc.prod[i];
+
+ if p.name {
+ fputs(out, p.name);
+ } else {
+ fputd(out, i);
+ }
+
+ fputs(out, "->{");
+
+ if p.epsilon {
+ fputs(out, "e");
+
+ if p.first {
+ fputs(out, " ");
+ }
+ }
+
+ d = rb_first(p.first) as *lalr_point;
+ loop {
+ if !d {
+ break;
+ }
+
+ if d.name {
+ fputs(out, d.name);
+ } else {
+ fputd(out, d.id);
+ }
+
+ d = rb_next(&d.node) as *lalr_point;
+
+ if d {
+ fputs(out, " ");
+ }
+ }
+
+ fputs(out, "}\n");
+
+ i = i + 1;
+ }
+}