ParseIt.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
David Goldberg December 6, 1989 10:24:33 pm PST
Peter B. Kessler, January 10, 1990 10:39:41 am PST
Willie-s, May 5, 1992 2:29 pm PDT
DIRECTORY
Basics USING [CompareInt],
BasicTime USING [GMT, Now],
Commander USING [CommandProc, Register],
CommanderOps USING [ParseToList],
IO USING [GetLine, PutF1, PutRope, rope, time],
List USING [CompareProc, LORA, Sort],
RefText USING [New],
Rope USING [Fetch, FromRefText, Length, Replace, ROPE, SkipTo],
TimeParse;
ParseIt: CEDAR PROGRAM
IMPORTS Basics, BasicTime, Commander, CommanderOps, IO, List, RefText, Rope, TimeParse
= BEGIN
buffer: REF TEXT ¬ RefText.New[1000];
alNumRope: Rope.ROPE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Compare: List.CompareProc = {
PROC[ref1: REF ANY, ref2: REF ANY] RETURNS [Comparison];
p1, p2: REF TimeParse.PieceType;
p1 ¬ NARROW[ref1];
p2 ¬ NARROW[ref2];
RETURN[Basics.CompareInt[p1.start, p2.start]];
};
CmdParse: Commander.CommandProc = {
PROC [cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL];
str: Rope.ROPE;
cnt, len: INT;
time: BasicTime.GMT;
inputList: LIST OF Rope.ROPE;
pieces: TimeParse.PiecesType;
piece: REF TimeParse.PieceType;
piecesLora: List.LORA;
dir: TimeParse.DirectionType ¬ heuristic;
insistTime, insistDay: BOOLEAN ¬ TRUE;
ListToLora: PROC[ls: TimeParse.PiecesType] RETURNS [lr: List.LORA ¬ NIL] = {
WHILE ls # NIL DO
lr ¬ CONS[ls.first, lr];
ls ¬ ls.rest;
ENDLOOP;
};
inputList ¬ CommanderOps.ParseToList[cmd: cmd
! CommanderOps.Failed => {log.PutRope["invalid input format\n"]; GO TO quit}
].list;
WHILE inputList # NIL DO
str ¬ inputList.first;
IF Rope.Length[str] > 1 AND Rope.Fetch[str] = '- THEN {
SELECT Rope.Fetch[str, 1] FROM
'b => dir ¬ backward;
'f => dir ¬ forward;
'h => dir ¬ heuristic;
'd => insistDay ¬ FALSE;
't => insistTime ¬ FALSE;
ENDCASE => {IO.PutRope[cmd.out, "Usage: parse -[bfhtd]\n"]; RETURN;};
};
inputList ¬ inputList.rest;
ENDLOOP;
WHILE TRUE DO
ENABLE TimeParse.ParseError => {
SELECT errorType FROM
noTime => IO.PutRope[cmd.out, "No time specified\n"];
yearOrMonthButNoDay => IO.PutRope[cmd.out, "Doesn't make sense to have year/month but no day\n"];
yearButNoMonth => IO.PutRope[cmd.out, "Doesn't make sense to have year but no month\n"];
dayWeekdayMismatch => IO.PutRope[cmd.out, "Mismatch between weekday and date\n"];
badYearInSlash => IO.PutRope[cmd.out, "mm/dd/yy has invalid value for year\n"];
twoYears => IO.PutRope[cmd.out, "The year is specified in two different ways\n"];
ENDCASE => NULL;
LOOP;
};
str ¬ Rope.FromRefText[IO.GetLine[cmd.in, buffer]];
[time, pieces] ¬ TimeParse.Parse[str, BasicTime.Now[], dir, insistTime, insistDay];
IO.PutF1[cmd.out, "%g\n", IO.time[time]];
cnt ¬ 0;
piecesLora ¬ List.Sort[ListToLora[pieces], Compare];
WHILE piecesLora # NIL DO
piece ¬ NARROW[piecesLora.first];
len ¬ piece.len;
if there is only punctuation between two pieces, remove the punctuation
IF piecesLora.rest # NIL AND Rope.SkipTo[str, piece.start - cnt + len, alNumRope] >= NARROW[piecesLora.rest.first, REF TimeParse.PieceType].start - cnt THEN
len ¬ NARROW[piecesLora.rest.first, REF TimeParse.PieceType].start - piece.start;
str ¬ Rope.Replace[str, piece.start - cnt, len];
cnt ¬ cnt + len;
piecesLora ¬ piecesLora.rest;
ENDLOOP;
IO.PutF1[cmd.out, " Revised String: %g\n", IO.rope[str]];
ENDLOOP;
};
Commander.Register[
key: "parseit",
proc: CmdParse,
doc: "Parse a time value\n -b backward\n -f forward\n -h heuristic\n -d don't insist on Day\n -t don't insist on Time" ];
END.