<<>> <> <> DIRECTORY CCTypes USING[CCError], CedarParseSupport USING[], IO USING[STREAM], PPP1 USING[Parse], PPTree USING[Link, Node, NodeName, Null], PPTreeOps USING[Finalize, Initialize, PopTree], Rope USING[Cat, ROPE]; CedarParseSupportImpl: CEDAR MONITOR IMPORTS CCTypes, PPP1, PPTreeOps, Rope EXPORTS CedarParseSupport = BEGIN <<>> <<>> <> <<>> <> <<>> Tree: TYPE = PPTree.Link; ParseCedarExpression: PUBLIC PROC[expr: Rope.ROPE, errout: IO.STREAM _ NIL] RETURNS[Tree] = BEGIN progTree: PPTree.Link; assignment: PPTree.Link; progTree _ Parse[Rope.Cat["Expr: PROGRAM = { x _ ", expr, "\n}."], errout]; IF progTree = NIL THEN CCTypes.CCError[syntax, NIL]; assignment _ GetFirstAssign[progTree]; IF assignment = NIL THEN CCTypes.CCError[syntax, NIL]; WITH assignment SELECT FROM node: REF PPTree.Node => BEGIN kind: PPTree.NodeName _ node.name; nsons: CARDINAL = node.sonLimit - 1; IF kind # assign THEN CCTypes.CCError[syntax, NIL]; RETURN [node[2]]; END; ENDCASE => CCTypes.CCError[syntax, NIL]; END; <> Parse: ENTRY PROC [program: Rope.ROPE, errout: IO.STREAM] RETURNS [root: Tree _ NIL] = TRUSTED { <> ENABLE UNWIND => NULL; complete: BOOL; nErrors: CARDINAL; PPTreeOps.Initialize[]; [complete, , nErrors] _ PPP1.Parse[program, errout]; root _ IF complete AND nErrors = 0 THEN PPTreeOps.PopTree[] ELSE PPTree.Null; PPTreeOps.Finalize[]; }; GetFirstAssign: PROC [tree: Tree] RETURNS [Tree] = { <> WITH tree SELECT FROM node: REF PPTree.Node => { kind: PPTree.NodeName _ node.name; nsons: CARDINAL = node.sonLimit - 1; IF kind = assign THEN RETURN [node]; FOR i: CARDINAL IN [1..nsons] DO nt: Tree _ GetFirstAssign[node[i]]; IF nt # NIL THEN RETURN [nt] ENDLOOP} ENDCASE; RETURN [NIL] }; <<>> <<>> <<>> <<>> END..