blob: 2ff6c753d9134b27f1b8e01f2f93f894367d49d6 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2010 E.D.Willink and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*
* </copyright>
*
* $Id: EssentialOCL.xtext,v 1.14 2011/05/21 14:55:09 ewillink Exp $
*/
grammar org.eclipse.ocl.examples.xtext.essentialocl.EssentialOCL hidden(WS, ML_COMMENT, SL_COMMENT) //with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
import "platform:/resource/org.eclipse.ocl.examples.pivot/model/Pivot.ecore" as pivot
import "platform:/resource/org.eclipse.ocl.examples.xtext.base/model/BaseCST.ecore" as base
import "platform:/resource/org.eclipse.ocl.examples.xtext.essentialocl/model/EssentialOCLCST.ecore"
//generate essentialOCLCST "http://www.eclipse.org/ocl/3.0.0/EssentialOCLCST"
Model returns ContextCS:
ownedExpression=ExpCS;
terminal fragment ESCAPED_CHARACTER:
'\\' ('b' | 't' | 'n' | 'f' | 'r' | 'u' | '"' | "'" | '\\');
terminal fragment LETTER_CHARACTER:
'a'..'z' | 'A'..'Z' | '_';
terminal DOUBLE_QUOTED_STRING:
'"' (ESCAPED_CHARACTER | !('\\' | '"'))* '"';
terminal SINGLE_QUOTED_STRING:
"'" (ESCAPED_CHARACTER | !('\\' | "'"))* "'";
terminal ML_SINGLE_QUOTED_STRING:
"/'"->"'/";
terminal SIMPLE_ID:
LETTER_CHARACTER (LETTER_CHARACTER | ('0'..'9'))*;
terminal ESCAPED_ID:
"_" SINGLE_QUOTED_STRING;
ID: SIMPLE_ID | ESCAPED_ID;
terminal INT: // String to allow diverse re-use
('0'..'9')+; // multiple leading zeroes occur as floating point fractional part
LOWER returns ecore::EInt:
INT
;
UPPER returns ecore::EInt:
INT | '*'
;
NUMBER_LITERAL returns BigNumber: // Not terminal to allow parser backtracking to sort out "5..7"
INT; // EssentialOCLTokenSource pieces this together ('.' INT)? (('e' | 'E') ('+' | '-')? INT)?;
terminal ML_COMMENT:
'/*' ->'*/';
terminal SL_COMMENT:
'--' !('\n' | '\r')* ('\r'? '\n')?;
terminal WS:
(' ' | '\t' | '\r' | '\n')+;
terminal ANY_OTHER:
.;
URI:
SINGLE_QUOTED_STRING;
EssentialOCLReservedKeyword:
'and'
| 'else'
| 'endif'
| 'if'
| 'implies'
| 'in'
| 'let'
| 'not'
| 'or'
| 'then'
| 'xor';
EssentialOCLPrefixOperator:
'-' | 'not';
EssentialOCLInfixOperator:
'*' | '/' | '+' | '-' | '>' | '<' | '>=' | '<=' | '=' | '<>' | 'and' | 'or' | 'xor' | 'implies';
EssentialOCLNavigationOperator:
'.' | '->';
Identifier:
ID;
StringLiteral:
SINGLE_QUOTED_STRING;
PrefixOperator: // Intended to be overridden
EssentialOCLPrefixOperator;
InfixOperator: // Intended to be overridden
EssentialOCLInfixOperator;
NavigationOperator: // Intended to be overridden
EssentialOCLNavigationOperator;
//---------------------------------------------------------------------
// Names
//---------------------------------------------------------------------
EssentialOCLUnrestrictedName returns ecore::EString:
Identifier;
UnrestrictedName returns ecore::EString: // Intended to be overridden
EssentialOCLUnrestrictedName;
EssentialOCLUnreservedName returns ecore::EString:
UnrestrictedName
| CollectionTypeIdentifier
| PrimitiveTypeIdentifier
| 'Tuple'
;
UnreservedName returns ecore::EString: // Intended to be overridden
EssentialOCLUnreservedName;
PathNameCS returns base::PathNameCS:
path+=FirstPathElementCS ('::' path+=NextPathElementCS)*;
FirstPathElementCS returns base::PathElementCS:
element=[pivot::NamedElement|UnrestrictedName];
NextPathElementCS returns base::PathElementCS:
element=[pivot::NamedElement|UnreservedName];
//---------------------------------------------------------------------
// Types
//---------------------------------------------------------------------
PrimitiveTypeIdentifier:
'Boolean'
| 'Integer'
| 'Real'
| 'String'
| 'UnlimitedNatural'
| 'OclAny'
| 'OclInvalid'
| 'OclVoid';
PrimitiveTypeCS returns base::PrimitiveTypeRefCS:
name=PrimitiveTypeIdentifier;
CollectionTypeIdentifier returns ecore::EString:
'Set'
| 'Bag'
| 'Sequence'
| 'Collection'
| 'OrderedSet';
CollectionTypeCS returns CollectionTypeCS:
name=CollectionTypeIdentifier ('(' ownedType=TypeExpCS ')')?;
MultiplicityBoundsCS returns base::MultiplicityBoundsCS:
lowerBound=LOWER ('..' upperBound=UPPER)?;
MultiplicityCS returns base::MultiplicityCS:
'[' (MultiplicityBoundsCS | MultiplicityStringCS) ']';
MultiplicityStringCS returns base::MultiplicityStringCS:
stringBounds=('*'|'+'|'?');
TupleTypeCS returns base::TupleTypeCS:
name='Tuple' ('(' (ownedParts+=TuplePartCS (',' ownedParts+=TuplePartCS)*)? ')')?;
TuplePartCS returns base::TuplePartCS:
name=UnrestrictedName ':' ownedType=TypeExpCS;
//---------------------------------------------------------------------
// Literals
//---------------------------------------------------------------------
CollectionLiteralExpCS returns CollectionLiteralExpCS:
ownedType=CollectionTypeCS
'{' (ownedParts+=CollectionLiteralPartCS
(',' ownedParts+=CollectionLiteralPartCS)*)?
'}';
CollectionLiteralPartCS returns CollectionLiteralPartCS:
expressionCS=ExpCS ('..' lastExpressionCS=ExpCS)?;
ConstructorPartCS returns ConstructorPartCS:
property=[pivot::Property|UnrestrictedName] '=' initExpression=ExpCS;
PrimitiveLiteralExpCS returns PrimitiveLiteralExpCS:
NumberLiteralExpCS
| StringLiteralExpCS
| BooleanLiteralExpCS
| UnlimitedNaturalLiteralExpCS
| InvalidLiteralExpCS
| NullLiteralExpCS;
TupleLiteralExpCS returns TupleLiteralExpCS:
'Tuple' '{' ownedParts+=TupleLiteralPartCS (',' ownedParts+=TupleLiteralPartCS)* '}';
TupleLiteralPartCS returns TupleLiteralPartCS:
name=UnrestrictedName (':' ownedType=TypeExpCS)? '=' initExpression=ExpCS;
NumberLiteralExpCS returns NumberLiteralExpCS:
name=NUMBER_LITERAL;
StringLiteralExpCS returns StringLiteralExpCS:
name+=StringLiteral+;
BooleanLiteralExpCS returns BooleanLiteralExpCS:
name='true'
| name='false';
UnlimitedNaturalLiteralExpCS returns UnlimitedNaturalLiteralExpCS:
{UnlimitedNaturalLiteralExpCS} '*';
InvalidLiteralExpCS returns InvalidLiteralExpCS:
{InvalidLiteralExpCS} 'invalid';
NullLiteralExpCS returns NullLiteralExpCS:
{NullLiteralExpCS} 'null';
TypeLiteralCS returns base::TypedRefCS:
PrimitiveTypeCS
| CollectionTypeCS
| TupleTypeCS;
TypeLiteralExpCS returns TypeLiteralExpCS:
ownedType=TypeLiteralCS;
TypeNameExpCS returns TypeNameExpCS:
pathName=PathNameCS;
TypeExpCS returns base::TypedRefCS:
(TypeNameExpCS | TypeLiteralCS) (multiplicity=MultiplicityCS)?;
//---------------------------------------------------------------------
// Expressions
//---------------------------------------------------------------------
// An ExpCS permits a LetExpCS only in the final term to ensure
// that let is right associative, whereas infix operators are left associative.
// a = 64 / 16 / let b : Integer in 8 / let c : Integer in 4
// is
// a = (64 / 16) / (let b : Integer in 8 / (let c : Integer in 4 ))
ExpCS returns ExpCS:
({InfixExpCS} (ownedExpression+=PrefixedExpCS ownedOperator+=BinaryOperatorCS)+
ownedExpression+=PrefixedExpOrLetExpCS)
| ({PrefixExpCS} ownedOperator+=UnaryOperatorCS+ ownedExpression=PrimaryExpOrLetExpCS)
| PrimaryExpOrLetExpCS;
BinaryOperatorCS returns BinaryOperatorCS:
InfixOperatorCS | NavigationOperatorCS;
InfixOperatorCS returns BinaryOperatorCS:
name=InfixOperator;
NavigationOperatorCS returns NavigationOperatorCS:
name=NavigationOperator;
PrefixedExpCS returns ExpCS:
PrimaryExpCS
| ({PrefixExpCS} ownedOperator+=UnaryOperatorCS+ ownedExpression=PrimaryExpCS);
PrefixedExpOrLetExpCS returns ExpCS:
PrimaryExpOrLetExpCS
| ({PrefixExpCS} ownedOperator+=UnaryOperatorCS+ ownedExpression=PrimaryExpOrLetExpCS);
UnaryOperatorCS returns UnaryOperatorCS:
name=PrefixOperator;
PrimaryExpCS returns ExpCS: // These rules are ordered most rejectable first
({IndexExpCS} pathName=PathNameCS '[' firstIndexes+=ExpCS (',' firstIndexes+=ExpCS)* ']'
('[' secondIndexes+=ExpCS (',' secondIndexes+=ExpCS)* ']')? (atPre?='@' 'pre')?)
| ({ConstructorExpCS} pathName=PathNameCS
'{' ((ownedParts+=ConstructorPartCS (',' ownedParts+=ConstructorPartCS)*) | (value=StringLiteral)) '}')
| ({InvocationExpCS} pathName=PathNameCS (atPre?='@' 'pre')?
'(' (argument+=NavigatingArgCS (argument+=NavigatingCommaArgCS)*
(argument+=NavigatingSemiArgCS (argument+=NavigatingCommaArgCS)*)?
(argument+=NavigatingBarArgCS (argument+=NavigatingCommaArgCS)*)?)?
')')
| ({NameExpCS} pathName=PathNameCS (atPre?='@' 'pre')?)
| SelfExpCS
| PrimitiveLiteralExpCS
| TupleLiteralExpCS
| CollectionLiteralExpCS
| TypeLiteralExpCS
| IfExpCS
| NestedExpCS;
PrimaryExpOrLetExpCS returns ExpCS:
PrimaryExpCS
| LetExpCS;
NavigatingArgCS returns NavigatingArgCS:
name=NavigatingArgExpCS (':' ownedType=TypeExpCS ('=' init=ExpCS)?)?; // Type-less init is an illegal infix expression
NavigatingBarArgCS returns NavigatingArgCS:
prefix='|' name=NavigatingArgExpCS (':' ownedType=TypeExpCS ('=' init=ExpCS)?)?; // Type-less init is an illegal infix expression
NavigatingCommaArgCS returns NavigatingArgCS:
prefix=',' name=NavigatingArgExpCS (':' ownedType=TypeExpCS ('=' init=ExpCS)?)?; // Type-less init is an illegal infix expression
NavigatingSemiArgCS returns NavigatingArgCS:
prefix=';' name=NavigatingArgExpCS (':' ownedType=TypeExpCS ('=' init=ExpCS)?)?; // Type-less init is an illegal infix expression
NavigatingArgExpCS returns ExpCS: // Intended to be overridden
ExpCS
// '?' -- defined by Complete OCL
;
IfExpCS returns IfExpCS:
'if' condition=ExpCS
'then' thenExpression=ExpCS
'else' elseExpression=ExpCS
'endif';
LetExpCS returns LetExpCS:
'let' variable+=LetVariableCS (',' variable+=LetVariableCS)*
'in' in=ExpCS;
LetVariableCS returns LetVariableCS:
name=UnrestrictedName (':' ownedType=TypeExpCS)? '=' initExpression=ExpCS;
NestedExpCS returns NestedExpCS:
'(' source=ExpCS ')';
SelfExpCS returns SelfExpCS:
{SelfExpCS} 'self';