/**
 * <copyright>
 *
 * Copyright (c) 2012 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 *
 * </copyright>
 */
/*
http://lampwww.epfl.ch/teaching/archive/compilation-ssc/2000/part4/parsing/node3.html

For building parsers (especially bottom-up) a BNF grammar is often better, than EBNF. But it's easy to convert an EBNF Grammar to BNF:

    Convert every repetition { E } to a fresh non-terminal X and add
    X = $\epsilon$ | X E.
    Convert every option [ E ] to a fresh non-terminal X and add
    X = $\epsilon$ | E.
    (We can convert X = A [ E ] B. to X = A E B | A B.)
    Convert every group ( E ) to a fresh non-terminal X and add
    X = E.
    We can even do away with alternatives by having several productions with the same non-terminal.
    X = E | E'. becomes X = E. X = E'. 
    
---
	As above, also normalize so that the output is a
	rule comprising
	-- a disjunction of
	-- one or more conjunctions comprising
	-- zero or more elements.
	
	Additional rules for multiplicities and alternatives are created as sub-rules, some
	of which may be inlined by a subsequent inline transformation.
*/
modeltype ECORE uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype XBNF uses 'http://www.eclipse.org/ocl/XBNF';
modeltype XBNFwc uses 'http://www.eclipse.org/ocl/XBNFwithCardinality';

transformation normalize(in xtext : XBNFwc, out XBNF);

main() {
	xtext.rootObjects()[XBNF::Syntax]->map syntax2syntax();
}

mapping XBNF::Syntax::syntax2syntax() : XBNF::Syntax {
	var allRules : Sequence(TypedRule) = self.grammars->collect(rules->sortedBy(name));
	var firstRules : OrderedSet(TypedRule) = allRules->collect(r1 | allRules->select(r2 | r1.name = r2.name)->first())->asOrderedSet();
	name := self.name;
	grammars := Sequence { self.map grammars2lexerGrammar(firstRules), self.map grammars2parserGrammar(firstRules) };
	var untypedRules : Sequence(UntypedRule) := grammars.allSubobjectsOfKind(UntypedRule)->selectByKind(UntypedRule);
	untypedRules->forEach(untypedRule) {
		untypedRule.name := untypedRule.typedRule.name + '_' + untypedRule.typedRule.subrules->indexOf(untypedRule).toString();
	};
}

---------------------------------------------------------------------------------------
--	Copy the lexer rules
---------------------------------------------------------------------------------------

mapping XBNF::Syntax::grammars2lexerGrammar(firstRules : Set(TypedRule)) : XBNF::LexerGrammar {
	name := self.name;
	rules := self.grammars.rules->selectByKind(TerminalRule)->map terminalRule2rule(firstRules);
	goals := self.grammars.goals.resolveone(TypedRule);
}

mapping XBNF::TerminalRule::terminalRule2rule(firstRules : Set(TypedRule)) : XBNF::TerminalRule
{
	var subRules : List(XBNF::UntypedRule) = List{};
	name := self.name;
	type := self.type;
	var candidate := self.element.map element2element(subRules, null, self, firstRules);
	element := if candidate.oclIsKindOf(Disjunction)
				then candidate
				else if candidate.oclIsKindOf(Conjunction)
				then object Disjunction {
					debug := self.debug;
					conjunctions += candidate.oclAsType(Conjunction);
				}
				else object Disjunction {
					debug := self.debug;
					conjunctions += object Conjunction {
						debug := self.debug;
						elements += candidate;
					};
				}
				endif
				endif;
	debug := subRules->size().toString();
	subrules := subRules->iterate(r; acc : Sequence(XBNF::UntypedRule) = Sequence{} | acc->append(r));
} 

---------------------------------------------------------------------------------------
--	Create the extra parser rules for XBNF compounds
---------------------------------------------------------------------------------------

mapping XBNF::Syntax::grammars2parserGrammar(firstRules : Set(TypedRule)) : XBNF::ParserGrammar {
	name := self.name;
	var parserRules : Sequence(ParserRule) = self.grammars.rules->selectByKind(ParserRule);
	var parserRuleNames : OrderedSet(String) = parserRules.name->asSet()->sortedBy(n | n);
	var sortedParserRules : Sequence(ParserRule) = parserRules->sortedBy(name);
	rules := parserRuleNames->iterate(prn; acc : OrderedSet(ParserRule) = OrderedSet{} |
		let pr : ParserRule = parserRules->select(name = prn)->any(true) in acc->append(pr.map parserRule2rule(firstRules)));
	goals := self.grammars->selectByKind(ParserGrammar).goals->first().resolveone(TypedRule);
}

mapping XBNF::ParserRule::parserRule2rule(firstRules : Set(TypedRule)) : XBNF::ParserRule
{
	var subRules : List(XBNF::UntypedRule) = List{};
	var theElement : AbstractElement = self.element.map element2element(subRules, null, self, firstRules);
	var disjunction : Disjunction = theElement.asDisjunction();
	name := self.name;
	debug := self.debug;
	type := self.type;
	element := disjunction;
	subrules := subRules->iterate(r; acc : Sequence(XBNF::UntypedRule) = Sequence{} | acc->append(r));
} 

mapping XBNF::AbstractElement::element2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement
disjuncts
ActionAssignment::actionAssignment2element,
Alternatives::alternativesAtRoot2element,
Alternatives::alternativesNested2element,
CharacterRange::characterRange2element,
KeywordAssignment::keywordAssignment2element,
Keyword::keyword2element,
NegatedToken::negatedToken2element,
OneOrMore::oneOrMore2element,
RuleCallAssignment::ruleCallAssignment2element,
RuleCall::ruleCall2element,
Succession::succession2element,
UntilToken::untilToken2element,
Wildcard::wildcard2element,
ZeroOrMore::zeroOrMore2element,
ZeroOrOne::zeroOrOne2element,
AbstractElement::element2element_default
{}

mapping XBNF::AbstractElement::element2element_default(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object Wildcard {
			debug := 'default';
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::ActionAssignment::actionAssignment2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object ActionAssignment {
			debug := self.debug;
			feature := self.feature;
			operator := self.operator;
			type := self.type;
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNFwc::Alternatives::alternativesAtRoot2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement
when { self.parentRule <> null }
{
	init {
		result := object Disjunction {
			debug := self.debug;
			conjunctions := self.elements->iterate(e; acc : Sequence(Conjunction) = Sequence {} |
					let eFlat = e.flattenAndMap(subRules, null, firstRules) in
					acc->append(eFlat.asConjunction()));
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNFwc::Alternatives::alternativesNested2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement
{
	init {
		var me : Alternatives = self;
		var alternatives : OrderedSet(AbstractElement) = self.elements;
		var oneRule : XBNF::UntypedRule = object Disjunction {
				debug := '1 : ' + alternatives->size().toString();
				conjunctions := alternatives->iterate(e; acc : Sequence(Conjunction) = Sequence{} | 
					let eFlat = e.flattenAndMap(subRules, null, firstRules) in
					acc->append(eFlat.asConjunction()));
			}.asRule();
		subRules->add(oneRule);
		result := oneRule.asRuleCall().appendAsConjunctions(tailElement);
	}
}

mapping XBNF::CharacterRange::characterRange2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object CharacterRange {
			debug := self.debug;
			left := self.left;
			right := self.right;
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::Keyword::keyword2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object Keyword {
			debug := self.debug;
			value := self.value;
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::KeywordAssignment::keywordAssignment2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object KeywordAssignment {
			debug := self.debug;
			feature := self.feature;
			operator := self.operator;
			value := self.value;
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::NegatedToken::negatedToken2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object NegatedToken {
			debug := self.debug;
			terminal := self.terminal.map element2element(subRules, null, disambiguator, firstRules);
		}.appendAsConjunctions(tailElement);
	}
}

//
//		x+ Y
//
//		X1: x
//		X2: X1 Y
//		X3: X1 X2
//		X: X2 | X3
// - we must handle Y to avoid shift reduce conflicts
//
mapping XBNFwc::OneOrMore::oneOrMore2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		var eFlat := self.element.flattenAndMap(subRules, null, firstRules);
		var oneRule : XBNF::UntypedRule = eFlat.asRule();
		subRules->add(oneRule);
		var oneOrMoreRule := object UntypedRule {};
		oneOrMoreRule.element := object Disjunction { debug := '1 or +';
				conjunctions := Sequence {
					object Conjunction {
						elements := Sequence { oneRule.asRuleCall() };
						if (tailElement <> null) {
							elements += tailElement;
						};
					},
					object Conjunction {
						elements := Sequence { oneRule.asRuleCall(), oneOrMoreRule.asRuleCall() };
					}
				};
			};
		subRules->add(oneOrMoreRule);
		result := oneOrMoreRule.asRuleCall();
	}
}

mapping XBNF::RuleCall::ruleCall2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object RuleCall {
			debug := self.debug;
			referredRule := firstRules->select(r | r.name = self.referredRule.name)->any(true).late resolveone(XBNF::AbstractRule);
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::RuleCallAssignment::ruleCallAssignment2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object RuleCallAssignment {
			debug := self.debug;
			feature := self.feature;
			operator := self.operator;
			referredRule := firstRules->select(r | r.name = self.referredRule.name)->any(true).late resolveone(XBNF::AbstractRule);
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNFwc::Succession::succession2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		var mappedTailElement : AbstractElement := if tailElement <> null then tailElement.map element2element(subRules, null, disambiguator, firstRules) else null endif;
		var element : AbstractElement := self.flattenAndMap(subRules, mappedTailElement, firstRules);
		result := element.asConjunction();
	}
}

mapping XBNF::UntilToken::untilToken2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object UntilToken {
			debug := self.debug;
			terminal := self.terminal.map element2element(subRules, null, disambiguator, firstRules);
		}.appendAsConjunctions(tailElement);
	}
}

mapping XBNF::Wildcard::wildcard2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		result := object Wildcard {
			debug := self.debug;
		}.appendAsConjunctions(tailElement);
	}
}

//
//		x* Y
//
//		X1: x
//		X2: Y
//		X3: X1 X2
//		X: X2 | X3
//
mapping XBNFwc::ZeroOrMore::zeroOrMore2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		var eFlat := self.element.flattenAndMap(subRules, null, firstRules);
		var oneRule = eFlat.asRule();
		subRules->add(oneRule);
		var oneOrMoreRule := object UntypedRule {};
		oneOrMoreRule.element := object Disjunction { debug := '1 or +';
			conjunctions := Sequence {
				object Conjunction {
					elements := Sequence { oneRule.asRuleCall() };
				},
				object Conjunction {
					elements := Sequence { oneOrMoreRule.asRuleCall(), oneRule.asRuleCall() };
				}
			};
		};
		subRules->add(oneOrMoreRule);
		var zeroOrMoreRule = object Disjunction { debug := '0 or +';
			conjunctions := Sequence {
				object XBNF::Epsilon {}.asConjunction(),
				oneOrMoreRule.asRuleCall().asConjunction()
			};
		}.asRule();
		subRules->add(zeroOrMoreRule);
		result := zeroOrMoreRule.asRuleCall().appendAsConjunctions(tailElement);
	}
}

//
//		x?
//
//		X1: x
//		X: epsilon | X1
//
mapping XBNFwc::ZeroOrOne::zeroOrOne2element(inout subRules : List(XBNF::UntypedRule), tailElement : AbstractElement, disambiguator : OclAny, firstRules : Set(TypedRule)) : XBNF::AbstractElement {
	init {
		var eFlat := self.element.flattenAndMap(subRules, null, firstRules);
		var zeroOrOneRule : UntypedRule = object Disjunction {
				debug := '0 or 1';
				conjunctions := Sequence { object XBNF::Epsilon {}.asConjunction(), eFlat.asConjunction() };
			}.asRule();
		subRules->add(zeroOrOneRule);
		result := zeroOrOneRule.asRuleCall().appendAsConjunctions(tailElement);
	}
}

-- Helpers

---------------------------------------------------------------------------------------
--	Return the conjunction of this element and tailElement which may be null.
---------------------------------------------------------------------------------------
helper XBNF::AbstractElement::appendAsConjunctions(tailElement : AbstractElement) : AbstractElement {
	return	if tailElement = null then
				self
			else if tailElement.oclIsKindOf(Conjunction) then
				object Conjunction { elements := tailElement.oclAsType(Conjunction).elements->prepend(self); }
			else
				object Conjunction { elements := Sequence{self, tailElement}; }
			endif
			endif;
}

helper XBNF::Conjunction::appendAsConjunctions(tailElement : AbstractElement) : AbstractElement {
	return	if tailElement = null then
				self
			else if tailElement.oclIsKindOf(Conjunction) then
				object Conjunction { elements := tailElement.oclAsType(Conjunction).elements
					->iterate(e; acc : Sequence(AbstractElement) = self.elements->asSequence() | acc->append(e));}
			else 
				object Conjunction { elements := self.elements->append(tailElement);}
			endif
			endif;
}

---------------------------------------------------------------------------------------
--	Return a conjunction containing thos element.
---------------------------------------------------------------------------------------
helper AbstractElement::asConjunction() : Conjunction {
	return object Conjunction { debug := '1'; elements := self->asSequence(); };
}

helper Conjunction::asConjunction() : Conjunction {
	return self;
}

---------------------------------------------------------------------------------------
--	Return a disjunction containing thos element.
---------------------------------------------------------------------------------------
helper AbstractElement::asDisjunction() : Disjunction {
	return object Disjunction { debug := '1'; conjunctions := self.asConjunction()->asSequence(); };
}

helper Disjunction::asDisjunction() : Disjunction {
	return self;
}

---------------------------------------------------------------------------------------
--	Return a rule containing thos element.
---------------------------------------------------------------------------------------
helper AbstractElement::asRule() : UntypedRule {
	return object UntypedRule {
		element := self.asDisjunction();
	};
}

helper AbstractRule::asRuleCall() : RuleCall {
	return object RuleCall {
		debug := self.name;
		referredRule := self;
	};
}

---------------------------------------------------------------------------------------
--	Return an in-order sequence of the flattened terms comprising head followed by self.
---------------------------------------------------------------------------------------
helper AbstractElement::flattenAndMap(inout subRules : List(XBNF::UntypedRule), outerTailElement : AbstractElement, firstRules : Set(TypedRule)) : AbstractElement {
	var flatElements : Sequence(AbstractElement) := self.flatten(Sequence{}, self);
	var flatSize : Integer = flatElements->size();
	return Sequence{1..flatSize}->iterate(i; innerTailElement : AbstractElement = outerTailElement |
		let iReverse = flatSize-i+1 in
		let flatElement = flatElements->at(iReverse) in
		flatElement.map element2element(subRules, innerTailElement, self, firstRules));
}

helper XBNF::AbstractElement::flatten(head : Sequence(AbstractElement), disambiguator : OclAny) : Sequence(AbstractElement)
{
	return head->append(self);
}

helper XBNFwc::Succession::flatten(head : Sequence(AbstractElement), disambiguator : OclAny) : Sequence(AbstractElement)
{
	return self.elements->iterate(e; acc : Sequence(AbstractElement) = head | e.flatten(acc, disambiguator));
}
