| /** |
| * <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 "http://www.eclipse.org/ocl/3.1.0/Pivot" as pivot |
| import "http://www.eclipse.org/ocl/3.1.0/BaseCST" as base |
| import "http://www.eclipse.org/ocl/3.1.0/EssentialOCLCST" |
| //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'; |
| |
| EssentialOCLUnaryOperatorCS returns UnaryOperatorCS: |
| name=('-' | 'not'); |
| |
| EssentialOCLInfixOperatorCS returns BinaryOperatorCS: |
| name=('*' | '/' | '+' | '-' | '>' | '<' | '>=' | '<=' | '=' | '<>' | 'and' | 'or' | 'xor' | 'implies'); |
| |
| EssentialOCLNavigationOperatorCS returns NavigationOperatorCS: |
| name=('.' | '->'); |
| |
| Identifier: |
| ID; |
| |
| StringLiteral: |
| SINGLE_QUOTED_STRING; |
| |
| BinaryOperatorCS returns BinaryOperatorCS: |
| InfixOperatorCS | NavigationOperatorCS; |
| |
| InfixOperatorCS returns BinaryOperatorCS: // Intended to be overrideable |
| EssentialOCLInfixOperatorCS; |
| |
| NavigationOperatorCS returns NavigationOperatorCS: // Intended to be overrideable |
| EssentialOCLNavigationOperatorCS; |
| |
| UnaryOperatorCS returns UnaryOperatorCS: // Intended to be overrideable |
| EssentialOCLUnaryOperatorCS; |
| |
| //--------------------------------------------------------------------- |
| // 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]; |
| |
| URIPathNameCS returns base::PathNameCS: |
| path+=URIFirstPathElementCS ('::' path+=NextPathElementCS)*; |
| |
| URIFirstPathElementCS returns base::PathElementCS: |
| element=[pivot::NamedElement|UnrestrictedName] | {base::PathElementWithURICS} element=[pivot::Namespace|URI]; |
| |
| //--------------------------------------------------------------------- |
| // 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; |
| |
| TypeLiteralWithMultiplicityCS returns base::TypedRefCS: |
| TypeLiteralCS multiplicity=MultiplicityCS?; |
| |
| TypeLiteralExpCS returns TypeLiteralExpCS: |
| ownedType=TypeLiteralWithMultiplicityCS; |
| |
| 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: |
| (PrefixedExpCS |
| ({InfixExpCS.ownedExpression+=current} ownedOperator+=BinaryOperatorCS |
| ( (ownedExpression+=PrefixedExpCS |
| (ownedOperator+=BinaryOperatorCS ownedExpression+=PrefixedExpCS)* |
| (ownedOperator+=BinaryOperatorCS ownedExpression+=LetExpCS)? |
| ) |
| | (ownedExpression+=LetExpCS) |
| ) |
| )? |
| ) |
| | ({PrefixExpCS} ownedOperator+=UnaryOperatorCS+ ownedExpression=LetExpCS) |
| | LetExpCS; |
| |
| PrefixedExpCS returns ExpCS: |
| ({PrefixExpCS} ownedOperator+=UnaryOperatorCS+ ownedExpression=PrimaryExpCS) |
| | PrimaryExpCS; |
| |
| PrimaryExpCS returns ExpCS: |
| NestedExpCS |
| | IfExpCS |
| | SelfExpCS |
| | PrimitiveLiteralExpCS |
| | TupleLiteralExpCS |
| | CollectionLiteralExpCS |
| | TypeLiteralExpCS |
| | ({NameExpCS} pathName=PathNameCS |
| ( |
| (({IndexExpCS.nameExp=current} '[' firstIndexes+=ExpCS (',' firstIndexes+=ExpCS)* ']' |
| ('[' secondIndexes+=ExpCS (',' secondIndexes+=ExpCS)* ']')? |
| (atPre?='@' 'pre')? |
| )) |
| | |
| ({ConstructorExpCS.nameExp=current} '{' |
| ( (ownedParts+=ConstructorPartCS (',' ownedParts+=ConstructorPartCS)*) |
| | (value=StringLiteral) |
| ) '}' |
| ) |
| | ( (atPre?='@' 'pre')? |
| ({InvocationExpCS.nameExp=current} '(' ( |
| argument+=NavigatingArgCS (argument+=NavigatingCommaArgCS)* |
| (argument+=NavigatingSemiArgCS (argument+=NavigatingCommaArgCS)*)? |
| (argument+=NavigatingBarArgCS (argument+=NavigatingCommaArgCS)*)? |
| )? ')' |
| )? |
| ) |
| ) |
| ); |
| |
| 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'; |
| |