language-Modula2-0.1: examples/Dipl/M2/GRAMMARS.MOD
IMPLEMENTATION MODULE Grammars;
(*# call(o_a_copy=>off, o_a_size=>off) *)
FROM Memory IMPORT AddMarker;
FROM Machine IMPORT EmptyClosure, link, HandlePackage, tempDef, AddEnv;
FROM Machine IMPORT MakeDef, MakePrimitive, MakeString, MakePacked;
FROM Machine IMPORT closure, handlerType, Build, MarkClosure;
FROM Library IMPORT wChar, wCharSet, wString, wNumber, wError, wVain;
FROM Library IMPORT wAddProp, wAddValProp, wJoin, wQuote, wCopy, wFind, wDummy;
FROM Library IMPORT wType, wStruct, wProperty, wValue, wDescription;
FROM Names IMPORT DefineWord, AddArgument, AddAtom, DefEntry, wName;
TYPE CharSet=SET OF CHAR;
PROCEDURE ChrDef(ch:CHAR):closure;
VAR
result:closure;
BEGIN
MakePacked(result,wChar,ch);
RETURN result
END ChrDef;
PROCEDURE StrDef(str:ARRAY OF CHAR):closure;
VAR
result:closure;
BEGIN
MakeString(result,wString,ADR(str));
RETURN result
END StrDef;
PROCEDURE Prim(h:handlerType):closure;
VAR
result:closure;
BEGIN
MakePrimitive(result,h);
RETURN result
END Prim;
PROCEDURE Def(root:link):closure;
VAR
result:closure;
BEGIN
MakeDef(result,root);
RETURN result
END Def;
PROCEDURE Obj(str:closure; prop:link; value:closure):closure;
BEGIN
AddEnv(str,prop,value);
RETURN str
END Obj;
PROCEDURE Seq(pp:link; g,n:closure):closure;
BEGIN
RETURN Obj(Obj(Obj(Def(wSequence),
wProperty,Def(pp)),
wGrammar,g),
wNext,n)
END Seq;
PROCEDURE ValSeq(pp:link; g,n:closure):closure;
BEGIN
RETURN Obj(Obj(Obj(Def(wValSequence),
wProperty,Def(pp)),
wGrammar,g),
wNext,n)
END ValSeq;
PROCEDURE EndSeq(root:link):closure;
BEGIN
RETURN Obj(Def(wEndSeq), wStruct, Def(root))
END EndSeq;
PROCEDURE Option(g:closure):closure;
BEGIN
RETURN Obj(Def(wOption), wGrammar, g)
END Option;
PROCEDURE Choose(g,n:closure):closure;
BEGIN
RETURN Obj(Obj(Def(wChoice),
wGrammar,g),
wNext,n)
END Choose;
PROCEDURE MarkFailure;
BEGIN
MarkClosure(Failure);
MarkClosure(Confirmation);
MarkClosure(HoldDummy)
END MarkFailure;
VAR
entry:closure; (* unmarked temporary, used only during initialisation *)
BEGIN
AddAtom(wFail, 'Fail');
MakeDef(Failure,wFail);
AddAtom(wDone, 'Done');
MakeDef(Confirmation,wDone);
MakeDef(HoldDummy,wDummy);
AddMarker(MarkFailure);
AddAtom(wDiscard, 'Discard');
AddAtom(wRaise, 'Raise');
AddArgument(wGrammar, 'Grammar');
AddArgument(wNext, 'Next');
DefineWord(wSeparator, 'Separator', HandlePackage);
MakePacked(tempDef,wCharSet,CharSet{'A'..'Z','a'..'z'});
DefineWord(wFirst, 'First', tempDef);
MakePacked(tempDef,wCharSet,CharSet{'0'..'9','A'..'Z','a'..'z'});
DefineWord(wTail, 'Tail', tempDef);
DefineWord(wFrameGrammar, 'FrameGrammar', Failure);
AddAtom(wCustomGrammar, 'CustomGrammar');
AddAtom(wPackageGrammar, 'PackageGrammar');
AddAtom(wNumGrammar, 'NumGrammar');
AddAtom(wCharSetGrammar, 'CharSetGrammar');
AddAtom(wCharGrammar, 'CharGrammar');
AddAtom(wErrorGrammar, 'ErrorGrammar');
AddAtom(wStrGrammar, 'StrGrammar');
AddAtom(wIdentGrammar, 'IdentGrammar');
DefineWord(wIdentifier, 'Identifier', HandlePackage);
DefineWord(wSpaceChars, 'SpaceChars', EmptyClosure);
LinkPacked(wSpaceChars,wCharSet,CharSet{' ',15C,12C,11C}); (* space,LF,CR,TAB *)
AddAtom(wSpaces, 'Spaces');
DefineWord(wComment, 'Comment', Failure);
MakeDef(tempDef,wVain);
DefineWord(wSequence, 'Seq', tempDef);
DefineWord(wLexSequence, 'LexSeq', tempDef);
DefineWord(wValSequence, 'ValSeq', tempDef);
DefineWord(wLexValSequence, 'LexValSeq', tempDef);
DefineWord(wEndSeq, 'EndSeq', tempDef);
DefineWord(wChoice, 'Choice', tempDef);
DefineWord(wOption, 'Option', tempDef);
MakeDef(tempDef,wCharGrammar);
entry:=DefEntry(wChar);
AddEnv(entry,wCustomGrammar,tempDef);
MakeDef(tempDef,wCharSetGrammar);
entry:=DefEntry(wCharSet);
AddEnv(entry,wCustomGrammar,tempDef);
MakeDef(tempDef,wNumGrammar);
entry:=DefEntry(wNumber);
AddEnv(entry,wCustomGrammar,tempDef);
MakeDef(tempDef,wStrGrammar);
entry:=DefEntry(wString);
AddEnv(entry,wCustomGrammar,tempDef);
MakeDef(tempDef,wErrorGrammar);
entry:=DefEntry(wError);
AddEnv(entry,wCustomGrammar,tempDef);
MakeDef(tempDef,wIdentGrammar);
entry:=DefEntry(wIdentifier);
AddEnv(entry,wCustomGrammar,tempDef);
entry:=DefEntry(wPacked);
MakeDef(tempDef,wPackageGrammar);
AddEnv(entry,wCustomGrammar,tempDef);
DefineWord(wSentence, 'Sentence', EmptyClosure);
DefineWord(wEnvGrammar, 'EnvGrammar', EmptyClosure);
wEnvGrammar^:=
Seq(wProperty,Def(wIdentGrammar),
Seq(wRaise, Choose(
Seq(wDiscard, ChrDef('='),
EndSeq(wAddProp)),
Seq(wDiscard, StrDef(':='),
EndSeq(wAddValProp))),
ValSeq(wValue, Def(wSentence),
ValSeq(wStruct,
Option(
Seq(wDiscard, ChrDef(','),
Seq(wRaise, Def(wEnvGrammar),
EndSeq(wDummy)))),
EndSeq(wDummy)))));
(* StructGrammar::= Join(Struct=IdentGrammar '(' Description:=[EnvGrammar] ')'). *)
DefineWord(wStructGrammar, 'StructGrammar',
Seq(wStruct,Obj(Def(wCopy),wProperty,Def(wType)),
Seq(wDiscard, ChrDef('('),
Seq(wRaise,
Option(
ValSeq(wDescription, Def(wEnvGrammar),
EndSeq(wJoin))),
Seq(wDiscard, ChrDef(')'),
EndSeq(wQuote))))));
(* Sentence::= Custom|Char|CharSet|String|Number. *)
wSentence^:=
Choose(Def(wCustomGrammar),
Choose(Def(wCharGrammar),
Choose(Def(wStrGrammar),
Choose(Def(wCharSetGrammar),
Def(wNumGrammar)))));
tempDef:=EmptyClosure
END Grammars.
(*
EnvGrammar::= Property:=IdentGrammar() Raise=('=' :AddProperty() | ":=" :AddValuedProperty())
Value:=Sentence(), Struct:=[',' Raise=EnvGrammar() :Dummy()]: Dummy().
StructGrammar::= Property:=IdentGrammar() '(' Raise=[Description:=EnvGrammar() :Join()] ')' :Quote().
Sentence::= Number()|Char()|String()|CharSET()|StructGrammar()|CommonGrammar().
InputGrammar::= Struct:=Sentence() :Struct().
*)