grammar org.eclipse.qvtd.doc.MiniOCLCS with org.eclipse.xtext.common.Terminals

generate minioclcs "http://www.eclipse.org/qvtd/doc/MiniOCLCS"

RootCS:
	imports+=ImportCS*
	(packages+=PackageCS
	| constraints+=ConstraintsDefCS)*
;
ImportCS:
  'import' (alias=ID ':') uri=STRING ';'
;
PackageCS:
	'package' name=ID '{'
		(packages+=PackageCS
		//|classifiers+=ClassifierCS
		| classes+=ClassCS
		)*
	'}'
;

//ClassifierCS:
//   ClassCS | DatatypeCS
//;

ClassCS:
	'class' name=ID ('extends' extends=PathNameCS)? '{'
		( properties+=PropertyCS
		| operations+=OperationCS )*
	'}'
;

//DatatypeCS:
//  'datatype' name=ID ':' typeName=STRING ';'
//;

PropertyCS:
  //('attribute' | 'containment' | 'cross_reference')
  'prop'
  name=ID ':' typeRef=PathNameCS
  (multiplicity=MultiplicityCS)? ';'
;

MultiplicityCS:
  '['
  (opt?='?' | mult?='*' | mandatory=INT |  (lowerInt=INT '..' (upperInt=INT | upperMult?='*')))
  ']'
;
OperationCS:
	'op' name=ID
	'(' (params+=ParameterCS (','params+=ParameterCS)*)? ')'
	':' resultRef=PathNameCS
	'=' body=ExpCS
	';'
;

ParameterCS:
	name=ID ':' typeRef=PathNameCS
;

ConstraintsDefCS:
	'context' typeRef=PathNameCS '{'
		(invariants+=InvariantCS)*
	'}'
;

InvariantCS:
	'inv' ':' exp=ExpCS ';'
;

// Expressions
ExpCS:
	EqualityExpCS
;

EqualityExpCS:
	CallExpCS ({EqualityExpCS.left=current} opName=('=' | '<>') right=CallExpCS)*
;

CallExpCS:
	PrimaryExpCS ({CallExpCS.source=current} opName=('.' | '->') navExp=NavigationExpCS)*
;

PrimaryExpCS:
  SelfExpCS | NameExpCS | LiteralExpCS | LetExpCS
;

SelfExpCS:
   {SelfExpCS} 'self'
;

NavigationExpCS:
  LoopExpCS | NameExpCS
;

LoopExpCS:
  CollectExpCS | IterateExpCS
;

CollectExpCS:
  'collect' '(' (itVar=IteratorVarCS '|')? exp=ExpCS')'
;

IteratorVarCS:
  itName = ID (':' itType=PathNameCS)?
;

IterateExpCS:
  'iterate' '(' itVar=IteratorVarCS ';' accVar=AccVarCS '|' exp=ExpCS ')'
;

AccVarCS:
  accName = ID (':' accType=PathNameCS)? '=' accInitExp=ExpCS
;

NameExpCS:
	expName=PathNameCS
	(roundedBrackets=RoundedBracketClauseCS)?
;

RoundedBracketClauseCS:
	{RoundedBracketClauseCS}
	'('
		(args+=ExpCS (','args+=ExpCS)* )?
	')'
;

LiteralExpCS:
	IntLiteralExpCS | BooleanLiteralExpCS | NullLiteralExpCS | CollectionLiteralExpCS
;

IntLiteralExpCS :
	intSymbol=INT
;

BooleanLiteralExpCS:
	{BooleanExpCS}
	(boolSymbol?='true'
	| 'false')
;

NullLiteralExpCS:
  {NullLiteralExpCS}
	'null'
;

enum CollectionKindCS:
  Collection='Collection'
;

CollectionLiteralExpCS:
  kind=CollectionKindCS '{'
  (parts+=CollectionLiteralPartCS)*
  '}'
;

CollectionLiteralPartCS:
  first=ExpCS
  ('..' last=ExpCS)?
;

LetExpCS:
  'let' letVars+=LetVarCS (',' letVars+=LetVarCS)*
  'in' inExp=ExpCS
;

LetVarCS:
  name=ID (':' typeRef=PathNameCS)? '=' initExp=ExpCS
;

PathNameCS :
	  pathElements+=PathElementCS
	  ('::'pathElements+=PathElementCS)*
;

PathElementCS:
	elementName=ID
;
