-- ThreeC4CSyntax.ThreeC4
-- Sturgis, May 7, 1986 4:33:09 pm PDT
-- Shoup, June 23, 1986 10:11:23 am PDT

Include[ThreeC4BaseDecl, ThreeC4BasicAbTypes, ThreeC4RootAbGram, ThreeC4ModItemAbGram,
			ThreeC4OtherModItemsAbGram, ThreeC4RecFcnImplAbGram, ThreeC4CProdAbGram,
			ThreeC4MiscAbGram, ThreeC4FlowGraphAbGram];

ThreeC4Central: Control Module;

ThreeC4CSyntax1: Module =
Begin

{"Include" "Module" "Control" "Begin" "End" } : SimpleTokens;
{ ":" "=" "[" "]" "," "←" "." "{" "}" ";" } : SimpleTokens;
{ "CedarType" "CedarFunction" "AbstractType" "From" } : SimpleTokens;
{ "BaseType" "EnumeratedBaseType" "BaseFunction" } : SimpleTokens;
{ "AbstractProduction" "TreeRecursiveFunction" } : SimpleTokens;
{ "Returns" "CedarEnumType" "GenericToken" "SimpleTokens" "NonTerminal" } : SimpleTokens;
{ "Builds" "Build" } : SimpleTokens;
{ "for" "let" "in" "if" "then" "else" "where" "(" ")" "<" ">" } : SimpleTokens;
{ "SourcePosition" "SourceLength" } : SimpleTokens;

{ "DamagedReps" "SharedReps" } : SimpleTokens;

MainGoal: NonTerminal Builds MainGoal;
	for MainGoal ← WholeFile
		Build MainGoal[WholeFile];
	
WholeFile: NonTerminal Builds WholeFile;
	for WholeFile ← OptionalIncludeClause ModuleList "."
		Build WholeFile[OptionalIncludeClause, ModuleList];

OptionalIncludeClause: NonTerminal Builds IncludeClause;
	for OptionalIncludeClause.empty ← 
		Build IncludeClause[IdList.Empty[]];
	
	for OptionalIncludeClause.nonEmpty ← "Include" "[" IdList "]" ";"
		Build IncludeClause[IdList];
		
ModuleList: NonTerminal Builds ModuleList;
	for ModuleList.one ← ModuleBody
		Build ModuleList.One[ModuleBody];
	
	for ModuleList.many ← ModuleList ";" ModuleBody
		Build ModuleList.Many[ModuleList, ModuleBody];
		
ModuleBody: NonTerminal Builds ModuleBody;
	for ModuleBody.control ← Identifier ":" "Control" "Module"
		Build ModuleBody.control[Identifier];
	
	for ModuleBody.normalNoSemi ← Identifier ":" "Module" "=" "Begin" ModuleItemList "End"
		Build ModuleBody.normal[Identifier, ModuleItemList];
	for ModuleBody.normalSemi ← Identifier ":" "Module" "=" "Begin" ModuleItemList  ";" "End"
		Build ModuleBody.normal[Identifier, ModuleItemList];
		
		
ModuleItemList: NonTerminal Builds ModuleItemList;
	for ModuleItemList.one ← ModuleItem
		Build ModuleItemList.One[ModuleItem];
		
	for ModuleItemList.many ← ModuleItemList ";" ModuleItem
		Build ModuleItemList.Many[ModuleItemList, ModuleItem];
		
		
ModuleItem: NonTerminal Builds ModuleItem;	
	for ModuleItem.cedarItems ← CedarItems
		Build ModuleItem.cedarItems[CedarItems];
	
	for ModuleItem.baseItems ← BaseItems
		Build ModuleItem.baseItems[BaseItems];
	
	for ModuleItem.abGramItems ← AbGramItems
		Build ModuleItem.abGramItems[AbGramItems];
	
	for ModuleItem.cGramItems	← CGramItems
		Build ModuleItem.cGramItems[CGramItems];
		
	for ModuleItem.genTkn ← Identifier ":" "GenericToken" "=" Rope
		Build ModuleItem.genTkn[Identifier, Rope];

CedarItems: NonTerminal Builds CedarItems;
	for CedarItems.cedarTypesFromOne ← Identifier.tName ":" "CedarType" "From" Identifier.fName
		Build CedarItems.cedarTypesFrom[IdList.nonEmpty[Identifier.tName, IdList.Empty[(Identifier.tName, Identifier.tName]]], Identifier.fName];
		
	for CedarItems.cedarTypesFromMany ← Identifier.tName  "," IdList ":" "CedarType" "From" Identifier.fName
		Build CedarItems.cedarTypesFrom[IdList.nonEmpty[Identifier.tName, IdList], Identifier.fName];
	
	for CedarItems.cedarTypesOne ← Identifier.tName ":" "CedarType" 
		Build CedarItems.cedarTypes[IdList.nonEmpty[Identifier.tName, IdList.Empty[(Identifier.tName, Identifier.tName]]]];
		
	for CedarItems.cedarTypesMany ← Identifier.tName  "," IdList ":" "CedarType" 
		Build CedarItems.cedarTypes[IdList.nonEmpty[Identifier.tName, IdList]];	
		
	for CedarItems.cedarEnumTypeFrom
		← Identifier.tName ":" "CedarEnumType" "=" "{" IdList "}"  "From" Identifier.fName
			Build CedarItems.cedarEnumTypeFrom[Identifier.tName, IdList, Identifier.fName];
	
	for CedarItems.cedarFnFrom
		← Identifier.fnName ":" "CedarFunction" OptionalArgModIdList "Returns" "[" ModIdList "]" "From" Identifier.fName DamageShareAssertionList
			Build CedarItems.cedarFunctionFrom[Identifier.fnName, OptionalArgModIdList, ModIdList, Identifier.fName, DamageShareAssertionList];
			
	for CedarItems.cedarFnFrom1
		← Identifier.fnName ":" "CedarFunction" OptionalArgModIdList "Returns" "[" ModIdList "]" DamageShareAssertionList1 "From" Identifier.fName 
			Build CedarItems.cedarFunctionFrom[Identifier.fnName, OptionalArgModIdList, ModIdList, Identifier.fName, DamageShareAssertionList1];
			
			
			
			
CGramItems: NonTerminal Builds CGramItems;
	for CGramItems.simpleTokens ← "{" RopeList "}" ":" "SimpleTokens"
		Build CGramItems.simpleTokens[RopeList];
	
	for CGramItems.nonTerminal ← Identifier.ntName ":" "NonTerminal" "Builds" Identifier.fName
		Build CGramItems.nonTerminal[Identifier.ntName, Identifier.fName];
	
	for CGramItems.concreteProduction ← "for" ModId "←" OptionalConcreteRightSideList "Build" BuildExp
		Build CGramItems.concreteProduction[ConcreteProduction[ModId, OptionalConcreteRightSideList, BuildExp]];

BaseItems: NonTerminal Builds BaseItems;
	for BaseItems.oneBaseType ← Identifier ":" "BaseType"
		Build BaseItems.baseTypes[IdList.nonEmpty[Identifier, IdList.Empty[(Identifier, Identifier]]]];
	
	for BaseItems.manyBaseTypes ← Identifier "," IdList ":" "BaseType"
		Build BaseItems.baseTypes[IdList.nonEmpty[Identifier, IdList]];
	
	for BaseItems.enumBaseType ← Identifier ":" "EnumeratedBaseType" "=" "{" IdList "}"
		Build BaseItems.enumBaseType[Identifier, IdList];
	
	for BaseItems.baseFcn ← Identifier ":" "BaseFunction" OptionalArgModIdList "Returns" "[" ModIdList "]" DamageShareAssertionList
		Build BaseItems.baseFcn[Identifier, OptionalArgModIdList, ModIdList, DamageShareAssertionList];
	
	for BaseItems.treeRecFcn ← Identifier ":" "TreeRecursiveFunction" "[" ModIdList.args "]" "Returns" "[" ModIdList.results "]" DamageShareAssertionList
		Build BaseItems.treeRecFcn[Identifier, ModIdList.args, ModIdList.results, DamageShareAssertionList];

OptionalArgModIdList: NonTerminal Builds ModIdList;
	for OptionalArgModIdList.empty1 ←
		Build ModIdList.Empty[];
		
	for OptionalArgModIdList.empty2 ← "[" "]"
		Build ModIdList.Empty[];
	
	for OptionalArgModIdList.present ← "[" ModIdList "]"
		Build ModIdList;

AbGramItems: NonTerminal Builds AbGramItems;
	for AbGramItems.abType ← Identifier ":" "AbstractType" "[" IdList "]"
		Build AbGramItems.abType[Identifier, IdList];
	
	for AbGramItems.abProdTwoIds ←
				Identifier.a "." Identifier.b ":" "AbstractProduction" "[" OptionalModIdList "]"
		Build AbGramItems.abProd[ModId.twoIds[Identifier.a, Identifier.b], OptionalModIdList];
	
	for AbGramItems.abProdOneId ← Identifier ":" "AbstractProduction" "[" OptionalModIdList "]"
		Build AbGramItems.abProd[ModId.oneId[Identifier], OptionalModIdList];
	
	for AbGramItems.abProdFcnImpl ← AbProductionFcnImpl
		Build AbGramItems.abProdFcnImpl[AbProductionFcnImpl];

AbProductionFcnImpl: NonTerminal Builds AbProductionFcnImpl;
	for AbProductionFcnImpl.oneId ←
				"for" Identifier ":" "AbstractProduction" "[" OptionalModIdList "]" RecFcnImplList
		Build AbProductionFcnImpl[ModId.oneId[Identifier], OptionalModIdList, RecFcnImplList];
	
	for AbProductionFcnImpl.twoIds ←
				"for" Identifier.a "." Identifier.b ":" "AbstractProduction" "[" OptionalModIdList "]" RecFcnImplList
		Build AbProductionFcnImpl[ModId.twoIds[Identifier.a, Identifier.b], OptionalModIdList, RecFcnImplList];

RecFcnImplList: NonTerminal Builds RecFcnImplList;
	for RecFcnImplList.one ← "let" Identifier "[" IdList "]" "←" RecExpression
		Build RecFcnImplList.one[Identifier, IdList, RecExpression];

	for RecFcnImplList.many ← RecFcnImplList "let" Identifier "[" IdList "]" "←" RecExpression
		Build RecFcnImplList.many[RecFcnImplList, RecFcnImplList.one[Identifier, IdList, RecExpression]]


End;

ThreeC4CSyntax2: Module =
Begin

RecExpression: NonTerminal Builds RecExpression;
	for RecExpression.RecExp1 ← RecExp1
		Build RecExp1;
		
	for RecExpression.withWhereList ← RecExp1 WhereExpSeq
		Build RecExpression.withWhereList[RecExp1, WhereExpSeq];	
		
	for RecExpression.withLetList ← "let" LetList "in" RecExp1
		Build RecExpression.withWhereList[RecExp1, LetList];

RecExp1: NonTerminal Builds RecExpression;
	for RecExp1.cond ← "if" RecExp1.ifClause "then" RecExp1.thenClause "else" RecExp1.elseClause
		Build RecExpression.cond[RecExp1.ifClause, RecExp1.thenClause, RecExp1.elseClause];
	
	for RecExp1.paranthesis ← "(" RecExpression ")"
		Build RecExpression;
	
	for RecExp1.call ← Identifier "[" OptionalRecExpSeq "]"
		Build RecExpression.call[Identifier, OptionalRecExpSeq];
	
	for RecExp1.seq ← "<" RecExpSeq ">"
		Build RecExpression.seq[RecExpSeq];
	
	for RecExp1.id ← Identifier
		Build RecExpression.id[Identifier];
	
	for RecExp1.modId ← Identifier.a "." Identifier.b
		Build RecExpression.modId[Identifier.a, Identifier.b];
	
	for RecExp1.rope ← Rope
		Build RecExpression.rope[Rope];
	
	for RecExp1.numb ← NonNegInteger
		Build RecExpression.numb[NonNegInteger];
	
	for RecExp1.sourcePosition ← "SourcePosition" "[" ModId "]"
		Build RecExpression.sourcePosition[ModId];
	
	for RecExp1.sourceLength ← "SourceLength" "[" ModId "]"
		Build RecExpression.sourceLength[ModId];

OptionalRecExpSeq: NonTerminal Builds RecExpSeq;
	for OptionalRecExpSeq.empty ←
		Build RecExpSeq.empty[];
	
	for OptionalRecExpSeq.nonEmpty ← RecExpSeq
		Build RecExpSeq;

RecExpSeq: NonTerminal Builds RecExpSeq;
	for RecExpSeq.one ← RecExpression
		Build RecExpSeq.one[RecExpression];

	for RecExpSeq.many ← RecExpSeq "," RecExpression
		Build RecExpSeq.many[RecExpSeq, RecExpSeq.one[RecExpression]];
		

WhereExpSeq: NonTerminal Builds WhereExpSeq;
	for WhereExpSeq.one ← WhereExp
		Build WhereExp;
	
	for WhereExpSeq.many ← WhereExpSeq WhereExp
		Build WhereExpSeq.many[WhereExpSeq, WhereExp];

WhereExp: NonTerminal Builds WhereExpSeq;
	for WhereExp.oneId ← "where" Identifier "←" RecExp1
		Build WhereExpSeq.one[IdList.nonEmpty[Identifier, IdList.Empty[(Identifier, Identifier]]], RecExp1];
	
	for WhereExp.manyIds ← "where" "<" IdList ">" "←" RecExp1
		Build WhereExpSeq.one[IdList, RecExp1];
		
LetList: NonTerminal Builds WhereExpSeq;
	for LetList.one ← LetExp
		Build LetExp;
		
	for LetList.many ← LetExp  ","  LetList
		Build WhereExpSeq.many[LetList, LetExp];
		
LetExp: NonTerminal Builds WhereExpSeq;
	for LetExp.oneId ← Identifier "←" RecExp1
		Build WhereExpSeq.one[IdList.nonEmpty[Identifier, IdList.Empty[(Identifier, Identifier]]], RecExp1];
		
	for LetExp.manyIds ←  "<" IdList ">" "←" RecExp1
		Build WhereExpSeq.one[IdList, RecExp1];

		 
	

	
	
	
			
	
	

OptionalConcreteRightSideList: NonTerminal Builds ConcreteRightSideList;
	for OptionalConcreteRightSideList.empty ←
		Build ConcreteRightSideList.empty[];
		
	for OptionalConcreteRightSideList.nonEmpty ← ConcreteRightSideList
		Build ConcreteRightSideList;
	
ConcreteRightSideList: NonTerminal Builds ConcreteRightSideList;
	for ConcreteRightSideList.one ← ConcreteRightSideItem
		Build ConcreteRightSideList.one[ConcreteRightSideItem];
		
	for ConcreteRightSideList.many ← ConcreteRightSideList ConcreteRightSideItem
		Build ConcreteRightSideList.many[ConcreteRightSideList, ConcreteRightSideItem];
		
ConcreteRightSideItem: NonTerminal Builds ConcreteRightSideItem;
	for ConcreteRightSideItem.rope ← Rope
		Build ConcreteRightSideItem.rope[Rope];
		
	for ConcreteRightSideItem.modId ← ModId
		Build ConcreteRightSideItem.modId[ModId];
		
BuildExp: NonTerminal Builds BuildExp;
	for BuildExp.modId ← ModId
		Build BuildExp.modId[ModId];
	
	for BuildExp.buildNodeBoth ← ModId "[" IntervalExp "," BuildExpList "]"
		Build BuildExp.buildNode[ModId, IntervalExp, BuildExpList];
		
	for BuildExp.buildNodeListOnly ← ModId "[" BuildExpList "]"
		Build BuildExp.buildNode[ModId, IntervalExp.none[[BuildExpList, BuildExpList)], BuildExpList];
	
	for BuildExp.buildNodeIntervalOnly ← ModId "[" IntervalExp "]"
		Build BuildExp.buildNode[ModId, IntervalExp, BuildExpList.empty[(IntervalExp, IntervalExp]]];
	
	for BuildExp.buildNodeNeither ← ModId "[" "]"
		Build BuildExp.buildNode[ModId, IntervalExp.none[(ModId, ModId]], BuildExpList.empty[(ModId, ModId]]];
		
IntervalExp: NonTerminal Builds IntervalExp;
	for IntervalExp.closed ← "[" ModId.left "," ModId.right "]"
		Build IntervalExp.present[IntervalForm.closed, ModId.left, ModId.right];

	for IntervalExp.leftOpen ← "(" ModId.left "," ModId.right "]"
		Build IntervalExp.present[IntervalForm.leftOpen, ModId.left, ModId.right];
		
	for IntervalExp.rightOpen ← "[" ModId.left "," ModId.right ")"
		Build IntervalExp.present[IntervalForm.rightOpen, ModId.left, ModId.right];
		
	for IntervalExp.fullOpen ← "(" ModId.left "," ModId.right ")"
		Build IntervalExp.present[IntervalForm.fullOpen, ModId.left, ModId.right];
	
BuildExpList: NonTerminal Builds BuildExpList;
	for BuildExpList.one ← BuildExp
		Build BuildExpList.one[BuildExp];
	for BuildExpList.many ← BuildExpList "," BuildExp
		Build BuildExpList.many[BuildExpList, BuildExp];
	
ModId: NonTerminal Builds ModId;
	for ModId.oneId ← Identifier
		Build ModId.oneId[Identifier];
		
	for ModId.twoIds ← Identifier.left "." Identifier.right
		Build ModId.twoIds[Identifier.left, Identifier.right];
	
	
IdList: NonTerminal Builds IdList;
	for IdList.one ← Identifier
		Build IdList.nonEmpty[Identifier, IdList.Empty[(Identifier, Identifier]]];
		
	for IdList.many ← Identifier "," IdList
		Build IdList.nonEmpty[Identifier, IdList];

OptionalModIdList: NonTerminal Builds ModIdList;
	for OptionalModIdList.empty ←
		Build ModIdList.Empty[];
	
	for OptionalModIdList.nonEmpty ← ModIdList
		Build ModIdList;
	
ModIdList: NonTerminal Builds ModIdList;
	for ModIdList.one ← ModId
		Build ModIdList.Many[ModIdList.Empty[[ModId, ModId)], ModId];
	
	for ModIdList.many ← ModIdList "," ModId
		Build ModIdList.Many[ModIdList, ModId];
	
RopeList: NonTerminal Builds RopeList;
	for RopeList.one ← Rope
		Build RopeList.One[Rope];
		
	for RopeList.many ← RopeList Rope
		Build RopeList.Many[RopeList, Rope];


DamageShareAssertionList: NonTerminal Builds DamageShareAssertions;
	for DamageShareAssertionList.empty ←
		Build DamageShareAssertions.empty[];
	
	for DamageShareAssertionList.nonEmpty ← DamageShareAssertionList DamageShareAssertion
		Build DamageShareAssertions.many[DamageShareAssertionList, DamageShareAssertion];
		
DamageShareAssertionList1: NonTerminal Builds DamageShareAssertions;
	for DamageShareAssertionList1.one ← DamageShareAssertion
		Build DamageShareAssertions.many[DamageShareAssertions.empty[(DamageShareAssertion, DamageShareAssertion]], DamageShareAssertion];
		
	for DamageShareAssertionList1.many ← DamageShareAssertionList1 DamageShareAssertion
		Build DamageShareAssertions.many[DamageShareAssertionList1, DamageShareAssertion];



DamageShareAssertion: NonTerminal Builds DamageShareAssertion;
	for DamageShareAssertion.damageAssertion ← "DamagedReps" "[" ModIdList "]"
		Build DamageShareAssertion.damagedReps[ModIdList];
	
	for DamageShareAssertion.shareAssertion ← "SharedReps" "[" ModIdList "]"
		Build DamageShareAssertion.sharedReps[ModIdList]


End.