<<>> <> <> <> <> DIRECTORY CCTypes USING [CCError], CedarParseSupport USING [], IO USING [STREAM], MPP1 USING [Parse], MPTree USING [Link, Node, NodeName, Null], MPTreeOps USING [Finalize, Initialize, PopTree], Rope USING [Cat, ROPE]; CedarParseSupportImpl: CEDAR MONITOR IMPORTS CCTypes, MPP1, MPTreeOps, Rope EXPORTS CedarParseSupport = BEGIN <<>> <<>> <> <<>> <> <<>> Tree: TYPE = MPTree.Link; ParseCedarExpression: PUBLIC PROC[expr: Rope.ROPE, errout: IO.STREAM ¬ NIL] RETURNS[Tree] = BEGIN progTree: MPTree.Link; assignment: MPTree.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 MPTree.Node => BEGIN kind: MPTree.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; MPTreeOps.Initialize[]; [complete, , nErrors] ¬ MPP1.Parse[program, errout]; root ¬ IF complete AND nErrors = 0 THEN MPTreeOps.PopTree[] ELSE MPTree.Null; MPTreeOps.Finalize[]; }; GetFirstAssign: PROC [tree: Tree] RETURNS [Tree] = { <> WITH tree SELECT FROM node: REF MPTree.Node => { kind: MPTree.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..