MODULEsymbol table; IMPORT SynParse, SynLocation, SynScan, SynWr, MetaParser, Text; TYPE ClauseExtends = SynParse.Tree BRANDED OBJECT extend, iter, iterPosPresent: BOOLEAN; iterPos: INTEGER; END; StringAction = SynParse.Action BRANDED OBJECT text: TEXT; END; IntegerAction = SynParse.Action BRANDED OBJECT int: INTEGER; END; ProcAction = SynParse.Action BRANDED OBJECT proc: SynParse.Action; END; REVEAL GramInfo = GramInfoBase BRANDED OBJECT clauseList: MetaParser.ClauseList; oldKeySet, newKeySet: SynScan.KeywordSet; END; Builder
TYPE H = MetaParser.ActionProcEntry ; VAR (* Sample Action Table *) sourceTable := ARRAY [0..27] OF MetaParser.ActionProcEntry { H { "ClauseList" , ClauseList }, H { "ClauseExtendsIterNoPos", ClauseExtendsIterNoPos }, H { "ClauseExtendsIterPos" , ClauseExtendsIterPos }, H { "ClauseExtendsIter" , ClauseExtendsIter }, H { "ClauseExtendsIter" , ClauseExtendsIter }, H { "ClauseExtendsChoice" , ClauseExtendsChoice }, H { "ClauseExtendsYes" , ClauseExtendsYes }, H { "ClauseExtendsNo" , ClauseExtendsNo }, H { "Storage" , Storage }, H { "Ide" , Ide2 }, H { "Name" , Name2 }, H { "GramIde" , GramIde2 }, H { "GramString" , GramString2 }, H { "GramKeyIde" , GramKeyIde2 }, H { "GramKeyName" , GramKeyName2 }, H { "GramKeyInt" , GramKeyInt2 }, H { "GramKeyEof" , GramKeyEof2 }, H { "GramKeyReal" , GramKeyReal2 }, H { "GramKeyChar" , GramKeyChar2 }, H { "GramKeyString" , GramKeyString2 }, H { "GramExpSequence" , GramExpSequence }, H { "GramExpChoice" , GramExpChoice }, H { "GramExpIterPos" , GramExpIterPos }, H { "GramExpIterNoPos" , GramExpIterNoPos }, H { "GramExpIter" , GramExpIter }, H { "GramExpBase" , GramExpBase }, H { "GramExpParens" , GramExpParens }, H { "GramList" , GramList } }; PROCEDUREerror printing routineLinkIn (table : MetaParser.ActionTable ) = BEGIN MetaParser.TableFromArray(sourceTable,table); END LinkIn;
getter
routines
PROCEDUREGClauseList (p: SynParse.T; loc: INTEGER): MetaParser.ClauseList RAISES {SynParse.Fail}= BEGIN TYPECASE p.stack[loc] OF | MetaParser.ClauseList(node) => RETURN node ; ELSE END; MetaParser.TypeError("clause-list", p.stack[loc]); <*ASSERT FALSE*> END GClauseList; PROCEDUREGClauseExtends (p: SynParse.T; loc: INTEGER): ClauseExtends RAISES {SynParse.Fail}= BEGIN TYPECASE p.stack[loc] OF | NULL=> | ClauseExtends(node) => RETURN node ; ELSE END; MetaParser.TypeError("clause-extends", p.stack[loc]); <*ASSERT FALSE*> END GClauseExtends; PROCEDUREGIdeNode (p: SynParse.T; loc: INTEGER): MetaParser.TextNode RAISES {SynParse.Fail}= BEGIN TYPECASE p.stack[loc] OF | NULL=> | MetaParser.TextNode(node) => RETURN node ; ELSE END; MetaParser.TypeError("n ide-node", p.stack[loc]); <*ASSERT FALSE*> END GIdeNode; PROCEDUREGGrammar (p: SynParse.T; loc: INTEGER): SynParse.Grammar RAISES {SynParse.Fail}= BEGIN TYPECASE p.stack[loc] OF | NULL=> | SynParse.Grammar(node) => RETURN node ; ELSE END; MetaParser.TypeError("grammar",p.stack[loc]); <*ASSERT FALSE*> END GGrammar; PROCEDUREGGramList (p: SynParse.T; loc: INTEGER): SynParse.GrammarList RAISES {SynParse.Fail}= BEGIN TYPECASE p.stack[loc] OF | SynParse.GrammarList(node) => RETURN node ; ELSE END; MetaParser.TypeError("grammar list",p.stack[loc]); <*ASSERT FALSE*> END GGramList; PROCEDUREGArgs (p: SynParse.T; loc: INTEGER):SynParse.Args RAISES {SynParse.Fail}= VAR n: INTEGER; args: SynParse.Tree; ret: SynParse.Args; BEGIN n:= 0; args := p.stack[loc]; LOOP TYPECASE args OF | NULL=> EXIT | Params(node) => INC(n); args:=node.rest; ELSE <*ASSERT FALSE*> END; END; ret := NEW(SynParse.Args,n); args := p.stack[loc]; FOR i := 0 TO n-1 DO TYPECASE args OF | NULL => | Params(node) => ret^[i] := MetaParser.XInt(node.first); args:=node.rest; ELSE <*ASSERT FALSE*> END; END; RETURN ret; END GArgs; PROCEDUREIde (<*UNUSED*>self: SynParse.Identifier; <*UNUSED*>p: SynParse.T; name: TEXT; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(MetaParser.TextNode, text:=name); END Ide; PROCEDUREIde2 (<*UNUSED*> self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail}= BEGIN RETURN Ide(NIL, p, MetaParser.GText(p, base+1), info); END Ide2; PROCEDUREName (<*UNUSED*>self: SynParse.Name; <*UNUSED*>p: SynParse.T; name: TEXT; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(MetaParser.TextNode, text:=name); END Name; PROCEDUREName2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail}= BEGIN RETURN Name(NIL, p, MetaParser.GText(p, base+1), info); END Name2; PROCEDUREGrammar (<*UNUSED*>self:SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info) : SynParse.Tree RAISES {SynParse.Fail} = BEGIN (* -- check that names in list are unique, whether extensions or not. *) RETURN GClauseList(p, base+1); END Grammar; PROCEDUREClauseList (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = VAR clauseExtends: ClauseExtends; BEGIN clauseExtends:=GClauseExtends(p, base+2); RETURN NEW(MetaParser.ClauseList, location:=SynLocation.NewLineLocation(info), ide:=GIdeNode(p, base+1), args:= GArgs(p, base+5), extend:=clauseExtends.extend, extendIter:=clauseExtends.iter, iterPosPresent:=clauseExtends.iterPosPresent, iterPos:=clauseExtends.iterPos, gram:=GGrammar(p, base+3), rest:=GClauseList(p, base+4)); END ClauseList; PROCEDUREClauseExtendsChoice (<*UNUSED*>self: SynParse.Action; <*UNUSED*>p: SynParse.T; <*UNUSED*>base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(ClauseExtends, extend:=TRUE, iter:=FALSE, iterPosPresent:=FALSE, iterPos:=0); END ClauseExtendsChoice; PROCEDUREClauseExtendsIterPos (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(ClauseExtends, extend:=TRUE, iter:=TRUE, iterPosPresent:=TRUE, iterPos:=MetaParser.GInt(p, base+3)); END ClauseExtendsIterPos; PROCEDUREClauseExtendsIterNoPos (<*UNUSED*>self: SynParse.Action; <*UNUSED*>p: SynParse.T; <*UNUSED*>base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(ClauseExtends, extend:=TRUE, iter:=TRUE, iterPosPresent:=FALSE, iterPos:=0); END ClauseExtendsIterNoPos; PROCEDUREClauseExtendsIter (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+2]; END ClauseExtendsIter; PROCEDUREClauseExtendsNo (<*UNUSED*>self: SynParse.Action; <*UNUSED*>p: SynParse.T; <*UNUSED*>base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(ClauseExtends, extend:=FALSE, iter:=FALSE); END ClauseExtendsNo; PROCEDUREClauseExtendsYes (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+1]; END ClauseExtendsYes; (* ****************************** *) (* teminals of client grammar *) (* ****************************** *) PROCEDUREGramIdeCm (name: TEXT;args: SynParse.Args; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.NonTerminal, location:=SynLocation.NewLineLocation(info), args:=args, name:=name); END GramIdeCm; PROCEDUREGramIde2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN GramIdeCm(MetaParser.GText(p, base+1),GArgs(p, base+2),info); END GramIde2; PROCEDUREGramString (<*UNUSED*>self: SynParse.QuotedString; p: SynParse.T; string: TEXT; READONLY info: SynLocation.Info) : SynParse.Tree RAISES {SynParse.Fail} = VAR name: TEXT; BEGIN IF Text.Length(string)=0 THEN SynParse.Fault(p, "Invalid token: \"\"") END; IF (Text.Length(string)=1) AND SynScan.IsDelimiter(p.Scanner(), Text.GetChar(string,0)) THEN RETURN NEW(SynParse.GivenDelimiter, location:=SynLocation.NewLineLocation(info), delim:=Text.GetChar(string,0)); ELSIF (Text.Length(string)>1) AND (Text.GetChar(string,0)='~') THEN name := Text.Sub(string, 1, Text.Length(string)-1); IF SynScan.IsIdentifier(p.Scanner(), name) THEN RETURN NEW(SynParse.GivenName, location:=SynLocation.NewLineLocation(info), text:=name); ELSE SynParse.Fault(p, "Invalid token: "& string); <*ASSERT FALSE*> END; ELSIF SynScan.IsIdentifier(p.Scanner(), string) THEN RETURN NEW(SynParse.GivenKeyword, location:=SynLocation.NewLineLocation(info), key:=string); ELSE SynParse.Fault(p, "Invalid token: "& string); <*ASSERT FALSE*> END; END GramString;
PROCEDURE GramString(self: SynParse.QuotedString;
p: SynParse.T; string: String.T;
READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} =
BEGIN
IF String.Length(string)=0 THEN
SynParse.Fault(p, Invalid token: \
\)
END;
IF (String.Length(string)=1) AND SynScan.IsDelimiter(p.sc, string[0]) THEN
RETURN
NEW(SynParse.GivenDelimiter, location:=SynLocation.NewLineLocation(info),
delim:=string[0]);
(* don't initialise build, take default action ( i.e. put
NIL onto stack )
ELSIF SynScan.IsIdentifier(p.sc, string) THEN RETURN (* Fill the key field later; store it in ide for now. *) NEW(GivenNamedKeyword, location:=SynLocation.NewLineLocation(info), ide:=String.ToText(string), key:=NIL); (* don't initialise build, take default action ( i.e. put NIL onto stack *) ELSE SynParse.Fault(p, "Invalid token: "&String.ToText(string)); END; END GramString; *) PROCEDUREGramString2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN GramString(NIL,p, MetaParser.GText(p, base+1),info); END GramString2; PROCEDUREGramKeyIde (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.Identifier, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.IdentifierToTree); END GramKeyIde; PROCEDUREGramKeyIde2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyIde(NIL, p, info); END GramKeyIde2 ; PROCEDUREGramKeyName (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.Name, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.NameToTree); END GramKeyName; PROCEDUREGramKeyName2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyName(NIL, p, info); END GramKeyName2 ; PROCEDUREGramKeyInt (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.Integer, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.IntegerToTree); END GramKeyInt; PROCEDUREGramKeyInt2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyInt(NIL, p, info); END GramKeyInt2 ; PROCEDUREGramKeyReal (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.Real, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.RealToTree); END GramKeyReal; PROCEDUREGramKeyReal2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyReal(NIL, p, info); END GramKeyReal2 ; PROCEDUREGramKeyChar (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.QuotedChar, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.CharToTree); END GramKeyChar; PROCEDUREGramKeyChar2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyChar(NIL, p, info); END GramKeyChar2 ; PROCEDUREGramKeyString (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.QuotedString, location:=SynLocation.NewLineLocation(info), Build:=MetaParser.StringToTree); END GramKeyString; PROCEDUREGramKeyString2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyString(NIL, p, info); END GramKeyString2 ; PROCEDUREGramKeyEof (<*UNUSED*>self: SynParse.GivenKeyword; <*UNUSED*>p: SynParse.T; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN NEW(SynParse.Eof, location:=SynLocation.NewLineLocation(info)); END GramKeyEof; PROCEDUREGramKeyEof2 (<*UNUSED*>self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN GramKeyEof(NIL, p, info); END GramKeyEof2 ; (* ************************************ *) PROCEDUREGramActionString (self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info) :SynParse.Tree= BEGIN RETURN MetaParser.TextToTree(NIL, p, NARROW(self,StringAction).text,info); END GramActionString; PROCEDUREGramActionProc (self: SynParse.Action; <*UNUSED*>p: SynParse.T; <*UNUSED*>base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info) :SynParse.Tree = BEGIN RETURN NARROW(self,ProcAction).proc; END GramActionProc; PROCEDUREGramActionInteger (self: SynParse.Action; p: SynParse.T; <*UNUSED*>base: INTEGER; READONLY info: SynLocation.Info) :SynParse.Tree= BEGIN RETURN MetaParser.IntegerToTree(NIL, p, NARROW(self,IntegerAction).int,info); END GramActionInteger; (* **************************** *) PROCEDUREGramList (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.GrammarList, location:=SynLocation.NewLineLocation(info), first:=p.stack[base+1], rest:=GGramList(p, base+2)); END GramList; PROCEDUREStorage (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Storage, location:=SynLocation.NewLineLocation(info), position:=MetaParser.GInt(p, base+3), item:=GGrammar(p, base+1)); END Storage; PROCEDUREGramExpSequence (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Sequence, location:=SynLocation.NewLineLocation(info), items:=GGramList(p, base+1)); END GramExpSequence; PROCEDUREGramExpChoice (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Choice, location:=SynLocation.NewLineLocation(info), choice:=GGramList(p, base+1)); END GramExpChoice; PROCEDUREGramExpParens (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+6]; END GramExpParens; PROCEDUREGramExpBase (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+1]; END GramExpBase; PROCEDUREGramExpIter (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+5]; END GramExpIter; PROCEDUREGramExpIterNoPos (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Iter, location:=SynLocation.NewLineLocation(info), base:=GGrammar(p, base+1), iter:=GGrammar(p, base+3), accum:=FALSE, accumPosition:=0); END GramExpIterNoPos; PROCEDUREGramExpIterPos (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Iter, location:=SynLocation.NewLineLocation(info), base:= GGrammar(p, base+1), iter:= GGrammar(p, base+3), accum:=TRUE, accumPosition:=MetaParser.GInt(p, base+4)); END GramExpIterPos; (* added following procedure for generating constant strings *) PROCEDUREActionString (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(StringAction, location := SynLocation.NewLineLocation(info), grammar := GGrammar(p, base+1), text := MetaParser.GText(p, base+3), Build := GramActionString); END ActionString; (* added following procedure for generating constant integers *) PROCEDUREActionInteger (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(IntegerAction, location := SynLocation.NewLineLocation(info), grammar := GGrammar(p, base+1), int := MetaParser.GInt(p, base+3), Build := GramActionInteger); END ActionInteger; PROCEDURELookupAction (p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): ActionProc RAISES {SynParse.Fail}= VAR name : TEXT ; ref: REFANY; BEGIN (* AK look up action NEW *) name := MetaParser.GText(p, base+3); IF actionTable.get(name,ref) THEN TYPECASE ref OF | REF ActionProc(node) => RETURN node^; ELSE SynWr.Text(SynWr.out, "Not an action: "&name&" ", loud:=TRUE); SynLocation.PrintLocation(SynWr.out, SynLocation.NewLineLocation(info)); SynWr.Text(SynWr.out, "\n", loud:=TRUE); SynWr.Flush(SynWr.out, loud:=TRUE); RAISE SynParse.Fail; END; ELSE SynWr.Text(SynWr.out, "Unknown action: "&name&" ", loud:=TRUE); SynLocation.PrintLocation(SynWr.out, SynLocation.NewLineLocation(info)); SynWr.Text(SynWr.out, "\n", loud:=TRUE); SynWr.Flush(SynWr.out, loud:=TRUE); RAISE SynParse.Fail; END; END LookupAction; PROCEDUREAntiquotedAction (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(ProcAction, location := SynLocation.NewLineLocation(info), grammar:= GGrammar(p, base+1), proc := NEW(SynParse.Action, location := NIL, grammar := NIL, Build := LookupAction(p, base,info)), Build := GramActionProc); END AntiquotedAction; (* following procedure for generating actions *) PROCEDUREAction (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree RAISES {SynParse.Fail} = BEGIN RETURN NEW(SynParse.Action, location := SynLocation.NewLineLocation(info), grammar:= GGrammar(p, base+1), Build := LookupAction(p, base, info)); END Action; PROCEDURESingle (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+1]; END Single; PROCEDUREGramExp (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; <*UNUSED*>READONLY info: SynLocation.Info): SynParse.Tree = BEGIN RETURN p.stack[base+2]; END GramExp; PROCEDUREConsParam (<*UNUSED*>self: SynParse.Action; p: SynParse.T; base: INTEGER; READONLY info: SynLocation.Info): SynParse.Tree= BEGIN RETURN NEW(Params, location := SynLocation.NewLineLocation(info), first:=p.stack[base+1], rest:=p.stack[base+2]); END ConsParam; BEGIN END Builder.