FOR qj:
CARDINAL
IN [0..qI)
DO
top ← top-q[qj].tag.pLength+1;
SELECT prodData[q[qj].transition].rule FROM
0 =>
-- TABLE: PGSParseData TYPE: ParseTable EXPORTS: SELF
GOAL: grammar
TERMINALS:
symbol num '? '| "::=" 'C "||TABLE1" "||TABLE2" "||TABLE3"
"||TABLE4" "||INPUT" "||CHAIN" "||LISTS" "||PRINTLR"
"||PRINTLALR" "||FIRST" "||IDS" "GOAL"
ALIASES: symbol tokenID num tokenNUM '? tokenQUERY
"||TABLE3" tokenTAB3 "||TABLE4" tokenTAB4 '? initialSymbol
PRODUCTIONS:
grammar ::= '? head ruleset
BEGIN FixLastProd[]; numProd ← prix-1; numRhsChars ← chix-1; i ← 1;
IF flags[echo] THEN outeol[1];
IF numProd > pssLim OR totalTokens > pssLim THEN Error[check+6,0,InputLoc[]];
scratch.FREE[@hashChain];
WHILE symInfo[i].used
AND i<=totalTokens
DO
IF i>eofMark AND tokenInfo[i-eofMark].index = 0 THEN EXIT; i ← i+1;
ENDLOOP;
IF i <= totalTokens
THEN {
defflag: BOOL ← FALSE;
lineWidth ← 0; Error[warning+3,0,InputLoc[]]; seterrstream[];
FOR i
IN [i..totalTokens]
DO
j ← 0; IF ~symInfo[i].used THEN j ← j+1;
IF i > eofMark AND tokenInfo[i-eofMark].index = 0 THEN j ← j+2;
IF j # 0
THEN {
IF (lineWidth ← lineWidth+(k←(11+j)/2)) > outbufLim
THEN {
outeol[1]; lineWidth ← k};
outnum[i,5];
IF j#2 THEN outchar['U,1] ELSE defflag ← TRUE;
IF j>1 THEN outchar['D,1]};
ENDLOOP;
outeol[1]; resetoutstream[];
IF defflag
THEN
Error[check+3,-2,InputLoc[]]}; -- nonterminal used but not defined
FOR i
IN [1..numProd]
DO
IF prodInfo[i].chain
THEN
IF prodInfo[i].count # 1
OR rhsChar[prodInfo[i].index] <= eofMark
THEN {
Error[warning+2, -(i+specErrorCases), InputLoc[]];
prodInfo[i].chain ← FALSE};
ENDLOOP;
FinishInput[];
END;
1 =>
-- head ::= directives terminals nonterminals "||TABLE4"
head ::= directives terminals nonterminals aliases "||TABLE4"
BEGIN totalTokens ← lastSymbol; PrintTableHead['4];
tokenInfo ←
LOOPHOLE[
MakeArray[totalTokens-eofMark+1,PGSTypes.TokenEntry.SIZE]];
numRules ← 0;
prodInfo ← LOOPHOLE[MakeArray[maxProd+1,PGSTypes.ProdEntry.SIZE]];
rhsChar ← LOOPHOLE[MakeArray[maxRhsSymbols+1,CARDINAL.SIZE]];
FOR i
IN [0..totalTokens-eofMark]
DO
tokenInfo[i] ← [count:0, empty:FALSE, index:0] ENDLOOP;
prodInfo[0] ← [count:2, rule:0, chain:FALSE, lhs:0, index:0];
FOR i
IN [1..maxProd]
DO
prodInfo[i] ← [count:0, rule:0, chain:FALSE, lhs:0, index:0] ENDLOOP;
IF flags[echo]
THEN {
outeol[1]; outchar[' ,20]; outstring["GOAL ::= "];
[] ← OutToken[eofMark+1]; outchar[' ,1]; [] ← OutToken[eofMark]};
rhsChar[0] ← eofMark+1; rhsChar[1] ← eofMark;
symInfo[eofMark+1].used ← symInfo[eofMark].used ← TRUE;
prix ← 1; chix ← 2; lhsDef ← 0; rhsFlag ← FALSE;
END;
2 =>
-- directives ::=
{flags ← ALL[FALSE]; l[top] ← InputLoc[]};
3 =>
-- directive ::= "||INPUT"
{flags[echo] ← TRUE; setoutstream[".echo"]};
4 =>
-- directive ::= "||CHAIN"
flags[chain] ← TRUE;
5 =>
-- directive ::= "||LISTS"
flags[lists] ← TRUE;
6 =>
-- directive ::= "||PRINTLR"
flags[printLR] ← TRUE;
7 =>
-- directive ::= "||PRINTLALR"
flags[printLALR] ← TRUE;
8 =>
-- directive ::= "||FIRST"
flags[first] ← TRUE;
9 =>
-- directive ::= "||IDS"
flags[ids] ← TRUE;
10 =>
-- terminals ::= "||TABLE1"
BEGIN
IF flags[echo]
THEN {
outeol[1];
FOR opt: PGSTypes.Options
IN PGSTypes.Options
DO
IF flags[opt]
THEN outstring[
SELECT opt
FROM
echo => "||INPUT ",
chain => "||CHAIN ",
lists => "||LISTS ",
printLR => "||PRINTLR ",
printLALR => "||PRINTLALR ",
first => "||FIRST ",
ENDCASE => "||IDS "];
ENDLOOP};
PrintTableHead['1];
END;
11 =>
-- terminals ::= terminals discard symbol
nonterminals ::= nonterminals discard symbol
BEGIN lastSymbol ← v[top+2].s;
IF flags[echo]
THEN {
outnum[lastSymbol, 3]; outchar[' , 2];
[] ← OutToken[lastSymbol];
outeol[1]};
END;
12 =>
-- nonterminals ::= "||TABLE2"
BEGIN PrintTableHead['2]; eofMark ← lastSymbol;
nextAlias ← 0; -- assert TABLE3 empty in case it is omitted
aliases ← NIL;
END;
13 =>
-- aliases ::= "||TABLE3"
BEGIN PrintTableHead['3];
aliases ← LOOPHOLE[MakeArray[64,PGSTypes.AliasEntry.SIZE]];
END;
14 =>
-- aliases ::= aliases symbol symbol
BEGIN IF v[top+1].s>eofMark THEN Error[check+7,v[top+1].s,InputLoc[]];
IF v[top+2].s<=eofMark THEN Error[check+8,v[top+2].s,InputLoc[]];
IF nextAlias=aliases.
LENGTH
THEN
aliases ← LOOPHOLE[Expand[aliases,PGSTypes.AliasEntry.SIZE,aliases.LENGTH/8]];
aliases[nextAlias] ← [v[top+1].s,v[top+2].s]; nextAlias ← nextAlias+1;
IF flags[echo]
THEN {
outchar[' ,tokenSize+1-OutToken[v[top+1].s]]; outchar[' ,1];
j ← v[top+2].s*tokenSize;
FOR i IN [j..j+tokenSize) WHILE symTab[i]#0C DO outchar[symTab[i],1] ENDLOOP;
outeol[1]};
END;
15 =>
-- discard ::=
l[top] ← InputLoc[]; -- keep the parser error recovery happy
16 =>
-- rulegroup ::= symbol "::="
{SetRuleChain[prix, FALSE]; LhsSymbol[v[top].s]};
17 =>
-- rulegroup ::= prefix symbol "::="
LhsSymbol[v[top+1].s];
18 =>
-- rulegroup ::= rulegroup symbol "::="
{SetRuleChain[prix, FALSE]; LhsSymbol[v[top+1].s]};
19 =>
-- rulegroup ::= rulegroup prefix symbol "::="
LhsSymbol[v[top+2].s];
20 =>
-- rulegroup ::= rulegroup '|
{SetRuleChain[prix, FALSE]; ProdHeader[FALSE]};
21 =>
-- rulegroup ::= rulegroup prefix '|
ProdHeader[FALSE];
22 =>
-- rulegroup ::= rulegroup symbol
BEGIN i ← v[top+1].s; symInfo[i].used ← TRUE;
IF i=eofMark OR i=eofMark+1 THEN Error[check+9,0,InputLoc[]]; --goal symbols
IF flags[echo]
THEN {
IF lineWidth<symInfo[i].length
THEN {
outeol[1]; outchar[' ,tokenSize+18]; lineWidth ← outbufLim - tokenSize-18};
IF (lineWidth ← (lineWidth-OutToken[i]-1)) > 0 THEN outchar[' , 1]};
IF chix=rhsChar.
LENGTH
THEN
rhsChar ← LOOPHOLE[Expand[rhsChar,CARDINAL.SIZE,rhsChar.LENGTH/8]];
rhsChar[chix]←i; chix ← chix +1;
IF prodInfo[prix-1].count = rhsLim
THEN {
prodInfo[prix-1].count ← 1; rhsFlag ← TRUE};
prodInfo[prix-1].count ← prodInfo[prix-1].count+1;
END;
23 =>
-- prefix ::= num
SetRuleChain[v[top].s, FALSE];
24 =>
-- prefix ::= num num
prefix ::= '? num
SetRuleChain[v[top+1].s, FALSE];
25 =>
-- prefix ::= discard 'C
SetRuleChain[prix, TRUE];
26 =>
-- prefix ::= discard 'C num
SetRuleChain[v[top+2].s, TRUE];
27 =>
-- prefix ::= '?
SetRuleChain[prix, FALSE];
28 =>
-- directives ::= directives directive
discard ::= num
discard ::= '?
ruleset ::=C rulegroup
ruleset ::= goalrule rulegroup
goalrule ::= "GOAL" "::=" symbol symbol
NULL;
ENDCASE => ERROR;
ENDLOOP};