56 lines
1.2 KiB
Plaintext
56 lines
1.2 KiB
Plaintext
|
# note this does not handle the case where there is a "gap" in tokens.
|
||
|
# E.g., if "x" and "xxx" are legal, but "xx" is not, then the resulting
|
||
|
# code will not handle "xx" correctly.
|
||
|
# (Doesn't happen in C#.)
|
||
|
|
||
|
procedure main()
|
||
|
local s, T, t, V, k, v, i
|
||
|
|
||
|
V := table()
|
||
|
T := table()
|
||
|
while s := read() do {
|
||
|
s ? {
|
||
|
k := tab(upto(' \t'))
|
||
|
tab(many(' \t'))
|
||
|
v := tab(0)
|
||
|
}
|
||
|
t := T
|
||
|
every i := !k do {
|
||
|
/t[i] := table();
|
||
|
t := t[i];
|
||
|
}
|
||
|
V[t] := v;
|
||
|
}
|
||
|
arms(T, V, "", "\t\t")
|
||
|
end
|
||
|
|
||
|
procedure arms(T, V, s, indent)
|
||
|
local i
|
||
|
|
||
|
every i := key(T) do {
|
||
|
write(indent, "case ", image(cset(i)), ":");
|
||
|
switch(T[i], V, s || i, indent || "\t")
|
||
|
}
|
||
|
end
|
||
|
|
||
|
procedure switch(T, V, s, indent)
|
||
|
if *T > 0 then {
|
||
|
write(indent, "if (!nextchar()) {")
|
||
|
dflt(T, V, s, indent || "\t")
|
||
|
write(indent, "}")
|
||
|
write(indent, "switch (ce.Current) {")
|
||
|
arms(T, V, s, indent)
|
||
|
write(indent, "default:")
|
||
|
dflt(T, V, s, indent || "\t")
|
||
|
write(indent, "}")
|
||
|
} else {
|
||
|
write(indent, "nextchar();")
|
||
|
dflt(T, V, s, indent)
|
||
|
}
|
||
|
end
|
||
|
|
||
|
procedure dflt(T, V, s, indent)
|
||
|
\V[T] | runerr(500)
|
||
|
write(indent, "return ret(InputElementTag.", V[T], ", ", image(s), ");")
|
||
|
end
|