Issue 10439: Recommendations re ptc/2005-06-06 (ocl2-rtf) Source: NIST (Mr. Peter Denno, peter.denno(at)nist.gov) Nature: Uncategorized Issue Severity: Summary: Recommendation: The specification would be better were it to additionally describe a practical grammar useful to tool implementors and persons trying to understand what constitutes legal OCL syntax. Of course, we all know that even practical OCL grammars are permissive of strings that aren't meaningful (for example, 7->isEmpty() is typically legal) but more can be done than is expressed by the current description. I am not suggesting that you replace the current method of description, but that you add (perhaps only as an informative, non-normative appendix) a conventional grammar. The spec, after all, is supposed to serve the purposes of implementors. There are published papers describing practical grammars for OCL, or I can supply you with one, if you'd like. PS By "practical grammar" I mean one that limits the look-ahead to a finite number wherever possible. It is, of course, the use of OclExpression in the RHS of so many productions that runs up against the infinite look-ahead problem, and makes the published grammar unusable by implementors. Resolution: (AS INITIALLY VOTED, DO NOT APPLY SINCE DEFERRED) At the end of 9.2.1 A practical grammar that can be realised by an LALR(1) parser is provided in Section 9.7. Add Sections 9.7 9.7 OCL Grammars The grammars presented in this Section are suitable for implementation by an LALR(1) parser generator such as yacc, bison or LPG after minor spelling adjustments to accommodate toolspecific characteristics. This grammar does not uniquely determine a Concrete Syntax; in many cases a number of alternative Concrete Syntaxes are identified that require disambiguation in accordance with the rules for each candidate Concrete Syntax presented in Section 9.3. The definitions of the IDENTIFIER, INTEGER_LITERAL, REAL_LITERAL, and STRING_LITERAL terminals may be found in Section 9.3 under simpleNameCS, IntegerLiteralExpCS, RealLiteralExpCS and StringLiteralExpCS. 9.7.1 Essential OCL Grammar The Essential OCL grammar defines only those concepts necessary for Essential OCL. The additional concepts for Complete OCL are added by the grammar in Section 9.7.2. Reserved keywords cannot be used as names in any context, unless enclosed by underscoreprefixed single quotes. Restricted keywords can only be used as names following a package or classifier qualification, unless enclosed by underscore-prefixed single quotes. -- Reserved keywords and implies not or xor if then else endif let in false true null invalid self -- Restricted keywords Bag Collection OrderedSet Sequence Set Tuple Boolean Integer Real String UnlimitedNatural OclAny OclInvalid OclVoid -- Terminals INTEGER_LITERAL REAL_LITERAL STRING_LITERAL ----------------------------------------------------------------------- -- Names ----------------------------------------------------------------------- reservedKeyword ::= and reservedKeyword ::= else reservedKeyword ::= endif reservedKeyword ::= if reservedKeyword ::= implies reservedKeyword ::= in reservedKeyword ::= let reservedKeyword ::= not reservedKeyword ::= or reservedKeyword ::= then reservedKeyword ::= xor tupleKeywordCS ::= Tuple reservedKeywordCS ::= reservedKeyword restrictedKeywordCS ::= CollectionTypeIdentifierCS restrictedKeywordCS ::= primitiveTypeCS restrictedKeywordCS ::= oclCS restrictedKeywordCS ::= tupleKeywordCS selfKeywordCS ::= self simpleNameCS ::= IDENTIFIER unreservedSimpleNameCS ::= simpleNameCS unreservedSimpleNameCS ::= restrictedKeywordCS pathNameCS ::= simpleNameCS pathNameCS ::= pathNameCS '::' unreservedSimpleNameCS ----------------------------------------------------------------------- -- Types ----------------------------------------------------------------------- primitiveTypeCS ::= Boolean primitiveTypeCS ::= Integer primitiveTypeCS ::= Real primitiveTypeCS ::= String primitiveTypeCS ::= UnlimitedNatural oclTypeCS ::= OclAny oclTypeCS ::= OclInvalid oclTypeCS ::= OclVoid CollectionTypeIdentifierCS ::= Set CollectionTypeIdentifierCS ::= Bag CollectionTypeIdentifierCS ::= Sequence CollectionTypeIdentifierCS ::= Collection CollectionTypeIdentifierCS ::= OrderedSet typeCS ::= primitiveTypeCS typeCS ::= oclTypeCS typeCS ::= pathNameCS typeCS ::= collectionTypeCS typeCS ::= tupleTypeCS collectionTypeCS ::= CollectionTypeIdentifierCS '(' typeCS ')' tupleTypeCS ::= Tuple '(' tupleTypePartsCSopt ')' tupleTypePartsCSopt ::= $empty tupleTypePartsCSopt ::= tupleTypePartsCS tupleTypePartsCS ::= typedUninitializedVariableCS tupleTypePartsCS ::= tupleTypePartsCS ',' typedUninitializedVariableCS ----------------------------------------------------------------------- -- Declarations ----------------------------------------------------------------------- untypedUninitializedVariableCS ::= simpleNameCS typedUninitializedVariableCS ::= untypedUninitializedVariableCS ':' typeCS untypedInitializedVariableCS ::= untypedUninitializedVariableCS '=' OclExpressionCS typedInitializedVariableCS ::= typedUninitializedVariableCS '=' OclExpressionCS initializedVariableCS ::= untypedInitializedVariableCS initializedVariableCS ::= typedInitializedVariableCS uninitializedVariableCS ::= untypedUninitializedVariableCS uninitializedVariableCS ::= typedUninitializedVariableCS VariableDeclarationCS ::= untypedUninitializedVariableCS VariableDeclarationCS ::= untypedInitializedVariableCS VariableDeclarationCS ::= typedUninitializedVariableCS VariableDeclarationCS ::= typedInitializedVariableCS ----------------------------------------------------------------------- -- Literals ----------------------------------------------------------------------- -- EnumLiteralExpCS is parsed as a PropertyCallExpCS[C] -- LiteralExpCS ::= EnumLiteralExpCS LiteralExpCS ::= CollectionLiteralExpCS LiteralExpCS ::= TupleLiteralExpCS LiteralExpCS ::= PrimitiveLiteralExpCS LiteralExpCS ::= TypeLiteralExpCS CollectionLiteralExpCS ::= CollectionTypeIdentifierCS '{' CollectionLiteralPartsCSopt '}' CollectionLiteralExpCS ::= collectionTypeCS '{' CollectionLiteralPartsCSopt '}' CollectionLiteralPartsCSopt ::= $empty CollectionLiteralPartsCSopt ::= CollectionLiteralPartsCS CollectionLiteralPartsCS ::= CollectionLiteralPartCS CollectionLiteralPartsCS ::= CollectionLiteralPartsCS ',' CollectionLiteralPartCS CollectionLiteralPartCS ::= CollectionRangeCS CollectionLiteralPartCS ::= OclExpressionCS CollectionRangeCS ::= OclExpressionCS '..' OclExpressionCS PrimitiveLiteralExpCS ::= IntegerLiteralExpCS PrimitiveLiteralExpCS ::= RealLiteralExpCS PrimitiveLiteralExpCS ::= StringLiteralExpCS PrimitiveLiteralExpCS ::= BooleanLiteralExpCS PrimitiveLiteralExpCS ::= UnlimitedNaturalLiteralExpCS PrimitiveLiteralExpCS ::= InvalidLiteralExpCS PrimitiveLiteralExpCS ::= NullLiteralExpCS TupleLiteralExpCS ::= Tuple '{' TupleLiteralPartsCS '}' TupleLiteralPartsCS ::= initializedVariableCS TupleLiteralPartsCS ::= TupleLiteralPartsCS ',' initializedVariableCS IntegerLiteralExpCS ::= INTEGER_LITERAL RealLiteralExpCS ::= REAL_LITERAL StringLiteralExpCS ::= STRING_LITERAL StringLiteralExpCS ::= StringLiteralExpCS STRING_LITERAL BooleanLiteralExpCS ::= true BooleanLiteralExpCS ::= false UnlimitedNaturalLiteralExpCS ::= '*' InvalidLiteralExpCS ::= invalid NullLiteralExpCS ::= null -- unqualified pathNameCS is parsed as SimpleNameExpCS -- qualified pathNameCS is parsed as PropertyCallExpCS[C] TypeLiteralExpCS ::= primitiveTypeCS TypeLiteralExpCS ::= oclTypeCS TypeLiteralExpCS ::= collectionTypeCS TypeLiteralExpCS ::= tupleTypeCS ----------------------------------------------------------------------- -- Calls ----------------------------------------------------------------------- CallExpCS ::= FeatureCallExpCS CallExpCS ::= LoopExpCS LoopExpCS ::= IteratorExpCS LoopExpCS ::= IterateExpCS -- IteratorExpCS[A.1] is parsed as OperationCallExpCS[B] IteratorExpCS ::= -- [A.2] primaryExpCS '->' simpleNameCS '(' uninitializedVariableCS '|' OclExpressionCS ')' IteratorExpCS ::= -- [A.3.1] primaryExpCS '->' simpleNameCS '(' simpleNameCS ',' uninitializedVariableCS '|' OclExpressionCS ')' IteratorExpCS ::= -- [A.3.2] primaryExpCS '->' simpleNameCS '(' typedUninitializedVariableCS ',' uninitializedVariableCS '|' OclExpressionCS ')' -- IteratorExpCS[B] is parsed as OperationCallExpCS[C] -- IteratorExpCS[C] is parsed as AssociationClassCallExpCS[A.1] -- IteratorExpCS[D] is parsed as AssociationClassCallExpCS[A] -- IteratorExpCS[E] is parsed as AssociationClassCallExpCS[A] IterateExpCS ::= primaryExpCS '->' simpleNameCS '(' typedInitializedVariableCS '|' OclExpressionCS ')' IterateExpCS ::= primaryExpCS '->' simpleNameCS '(' uninitializedVariableCS ';' typedInitializedVariableCS '|' OclExpressionCS ')' FeatureCallExpCS ::= OperationCallExpCS FeatureCallExpCS ::= PropertyCallExpCS FeatureCallExpCS ::= NavigationCallExpCS -- OperationCallExpCS[A] is realized by the infix OclExpressionCS productions OperationCallExpCS ::= -- [B.1] primaryExpCS '->' simpleNameCS '(' ')' OperationCallExpCS ::= -- [B.2],IteratorExpCS[A.1] primaryExpCS '->' simpleNameCS '(' OclExpressionCS ')' OperationCallExpCS ::= -- [B.3.1] primaryExpCS '->' simpleNameCS '(' notNameExpressionCS ',' argumentsCS ')' OperationCallExpCS ::= -- [B.3.2] primaryExpCS '->' simpleNameCS '(' simpleNameCS ',' argumentsCS ')' OperationCallExpCS ::= -- [C],[E],IteratorExpCS[B] primaryExpCS '.' simpleNameCS isMarkedPreCSopt '(' argumentsCSopt ')' OperationCallExpCS ::= -- [D],[F],[G.1] simpleNameCS isMarkedPreCSopt '(' argumentsCSopt ')' OperationCallExpCS ::= -- [G.2] pathNameCS '::' unreservedSimpleNameCS '(' argumentsCSopt ')' -- OperationCallExpCS[H] is realized by the prefix OclExpressionCS productions OperationCallExpCS ::= -- [I],[J] primaryExpCS '.' pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt '(' argumentsCSopt ')' -- NavigationCallExpCS ::= PropertyCallExpCS -- parsed as FeatureCallExpCS NavigationCallExpCS ::= AssociationClassCallExpCS -- PropertyCallExpCS[A] is parsed as AssociationClassCallExpCS[A.1] -- PropertyCallExpCS[B.1] is parsed as a SimpleNameExpCS -- PropertyCallExpCS[B.2] is parsed as a AssociationClassCallExpCS[B.1] PropertyCallExpCS ::= -- [C] excluding [B] pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt PropertyCallExpCS ::= -- [D] primaryExpCS '.' pathNameCS '::' unreservedSimpleNameCS isMarkedPreCSopt AssociationClassCallExpCS ::= -- [A.1],PropertyCallExpCS[A],IteratorExpCS[C,D,E] primaryExpCS '.' simpleNameCS isMarkedPreCSopt AssociationClassCallExpCS ::= -- [A.2],IteratorExpCS[D,E] primaryExpCS '.' simpleNameCS '[' argumentsCS ']' isMarkedPreCSopt -- AssociationClassCallExpCS[B.1.1] parsed as SimpleNameExpCS -- AssociationClassCallExpCS[B.1.2] is added by Complete OCL AssociationClassCallExpCS ::= -- [B.2] simpleNameCS '[' argumentsCS ']' isMarkedPreCSopt isMarkedPreCSopt ::= $empty argumentsCSopt ::= $empty argumentsCSopt ::= argumentsCS argumentsCS ::= OclExpressionCS argumentsCS ::= argumentsCS ',' OclExpressionCS ----------------------------------------------------------------------- -- Expressions ----------------------------------------------------------------------- -- An OclExpressionCS comprising just a SimpleNameCS is kept separate as -- SimpleNameExpCS to avoid ambiguity when parsing "a->b(c,d" until the next -- letter resolves the usage as a two iterator or as a two or more argument -- OperationCallExpCS. -- An OclExpressionCS comprising one or more LetExpCS is kept separate 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 )) OclExpressionCS ::= notNameExpressionCS OclExpressionCS ::= SimpleNameExpCS -- VariableExpCS[.1] simpleNameCS parsed as SimpleNameExpCS VariableExpCS ::= -- [.2] selfKeywordCS SimpleNameExpCS ::= -- AssociationClassCallExpCS[B.1.1], -- PropertyCallExpCS[B],VariableExpCS[.1] simpleNameCS notNameExpressionCS ::= impliesNotNameNotLetCS notNameExpressionCS ::= impliesWithLetCS impliesNotLetCS ::= impliesNotNameNotLetCS impliesNotLetCS ::= SimpleNameExpCS impliesNotNameNotLetCS ::= xorNotNameNotLetCS impliesNotNameNotLetCS ::= impliesNotLetCS implies xorNotLetCS impliesWithLetCS ::= xorWithLetCS impliesWithLetCS ::= impliesNotLetCS implies xorWithLetCS xorNotLetCS ::= xorNotNameNotLetCS xorNotLetCS ::= SimpleNameExpCS xorNotNameNotLetCS ::= orNotNameNotLetCS xorNotNameNotLetCS ::= xorNotLetCS xor orNotLetCS xorWithLetCS ::= orWithLetCS xorWithLetCS ::= xorNotLetCS xor orWithLetCS orNotLetCS ::= orNotNameNotLetCS orNotLetCS ::= SimpleNameExpCS orNotNameNotLetCS ::= andNotNameNotLetCS orNotNameNotLetCS ::= orNotLetCS or andNotLetCS orWithLetCS ::= andWithLetCS orWithLetCS ::= orNotLetCS or andWithLetCS andNotLetCS ::= andNotNameNotLetCS andNotLetCS ::= SimpleNameExpCS andNotNameNotLetCS ::= equalityNotNameNotLetCS andNotNameNotLetCS ::= andNotLetCS and equalityNotLetCS andWithLetCS ::= equalityWithLetCS andWithLetCS ::= andNotLetCS and equalityWithLetCS equalityNotLetCS ::= equalityNotNameNotLetCS equalityNotLetCS ::= SimpleNameExpCS equalityNotNameNotLetCS ::= relationalNotNameNotLetCS equalityNotNameNotLetCS ::= equalityNotLetCS '=' relationalNotLetCS equalityNotNameNotLetCS ::= equalityNotLetCS '<>' relationalNotLetCS equalityWithLetCS ::= relationalWithLetCS equalityWithLetCS ::= equalityNotLetCS '=' relationalWithLetCS equalityWithLetCS ::= equalityNotLetCS '<>' relationalWithLetCS relationalNotLetCS ::= relationalNotNameNotLetCS relationalNotLetCS ::= SimpleNameExpCS relationalNotNameNotLetCS ::= additiveNotNameNotLetCS relationalNotNameNotLetCS ::= relationalNotLetCS '>' additiveNotLetCS relationalNotNameNotLetCS ::= relationalNotLetCS '<' additiveNotLetCS relationalNotNameNotLetCS ::= relationalNotLetCS '>=' additiveNotLetCS relationalNotNameNotLetCS ::= relationalNotLetCS '<=' additiveNotLetCS relationalWithLetCS ::= additiveWithLetCS relationalWithLetCS ::= relationalNotLetCS '>' additiveWithLetCS relationalWithLetCS ::= relationalNotLetCS '<' additiveWithLetCS relationalWithLetCS ::= relationalNotLetCS '>=' additiveWithLetCS relationalWithLetCS ::= relationalNotLetCS '<=' additiveWithLetCS additiveNotLetCS ::= additiveNotNameNotLetCS additiveNotLetCS ::= SimpleNameExpCS additiveNotNameNotLetCS ::= multiplicativeNotNameNotLetCS additiveNotNameNotLetCS ::= additiveNotLetCS '+' multiplicativeNotLetCS additiveNotNameNotLetCS ::= additiveNotLetCS '-' multiplicativeNotLetCS additiveWithLetCS ::= multiplicativeWithLetCS additiveWithLetCS ::= additiveNotLetCS '+' multiplicativeWithLetCS additiveWithLetCS ::= additiveNotLetCS '-' multiplicativeWithLetCS multiplicativeNotLetCS ::= multiplicativeNotNameNotLetCS multiplicativeNotLetCS ::= SimpleNameExpCS multiplicativeNotNameNotLetCS ::= unaryNotNameNotLetCS multiplicativeNotNameNotLetCS ::= multiplicativeNotLetCS '*' unaryNotLetCS multiplicativeNotNameNotLetCS ::= multiplicativeNotLetCS '/' unaryNotLetCS multiplicativeWithLetCS ::= unaryWithLetCS multiplicativeWithLetCS ::= multiplicativeNotLetCS '*' unaryWithLetCS multiplicativeWithLetCS ::= multiplicativeNotLetCS '/' unaryWithLetCS unaryNotLetCS ::= unaryNotNameNotLetCS unaryNotLetCS ::= SimpleNameExpCS unaryNotNameNotLetCS ::= primaryNotNameCS unaryNotNameNotLetCS ::= '-' unaryNotLetCS unaryNotNameNotLetCS ::= not unaryNotLetCS unaryWithLetCS ::= LetExpCS -- OclExpressionCS[D] unaryWithLetCS ::= '-' unaryWithLetCS unaryWithLetCS ::= not unaryWithLetCS primaryExpCS ::= primaryNotNameCS primaryExpCS ::= SimpleNameExpCS primaryNotNameCS ::= CallExpCS -- OclExpressionCS[A] primaryNotNameCS ::= VariableExpCS -- OclExpressionCS[B] primaryNotNameCS ::= LiteralExpCS -- OclExpressionCS[C] -- primaryNotNameCS ::= OclMessageExpCS -- OclExpressionCS[E] is added by Complete OCL primaryNotNameCS ::= IfExpCS -- OclExpressionCS[F] primaryNotNameCS ::= '(' OclExpressionCS ')' IfExpCS ::= if OclExpressionCS then OclExpressionCS else OclExpressionCS endif LetExpCS ::= let letVariablesCS in OclExpressionCS letVariablesCS ::= typedInitializedVariableCS letVariablesCS ::= letVariablesCS ',' typedInitializedVariableCS 9.7.2 Complete OCL Grammar The Complete OCL grammar is an addition to the Essential OCL grammar. -- Reserved keywords body context def derive endpackage init inv package post pre static -- Restricted keywords OclMessage ----------------------------------------------------------------------- -- Names ----------------------------------------------------------------------- reservedKeyword ::= body reservedKeyword ::= context reservedKeyword ::= def reservedKeyword ::= derive reservedKeyword ::= endpackage reservedKeyword ::= init reservedKeyword ::= inv reservedKeyword ::= package reservedKeyword ::= post reservedKeyword ::= pre reservedKeyword ::= static unreservedSimpleNameCSopt ::= $empty unreservedSimpleNameCSopt ::= unreservedSimpleNameCS ----------------------------------------------------------------------- -- Types ----------------------------------------------------------------------- oclTypeCS ::= OclMessage typeCSopt ::= $empty typeCSopt ::= typeCS ----------------------------------------------------------------------- -- Calls ----------------------------------------------------------------------- OperationCallExpCS ::= -- [B] primaryExpCS '->' simpleNameCS isMarkedPreCS '(' argumentsCSopt ')' AssociationClassCallExpCS ::= -- [B.1],PropertyCallExpCS[B] simpleNameCS isMarkedPreCS isMarkedPreCS ::= '@' pre isMarkedPreCSopt ::= isMarkedPreCS OclMessageExpCS ::= primaryExpCS '^^' simpleNameCS '(' OclMessageArgumentsCSopt ')' OclMessageExpCS ::= primaryExpCS '^' simpleNameCS '(' OclMessageArgumentsCSopt ')' OclMessageArgumentsCSopt ::= $empty OclMessageArgumentsCSopt ::= OclMessageArgumentsCS OclMessageArgumentsCS ::= OclMessageArgCS OclMessageArgumentsCS ::= OclMessageArgumentsCS ',' OclMessageArgCS OclMessageArgCS ::= '?' OclMessageArgCS ::= '?' ':' typeCS OclMessageArgCS ::= OclExpressionCS ----------------------------------------------------------------------- -- Expressions ----------------------------------------------------------------------- primaryNotNameCS ::= OclMessageExpCS ----------------------------------------------------------------------- -- Contexts ----------------------------------------------------------------------- packageDeclarationsCS ::= packageDeclarationCS packageDeclarationsCS ::= packageDeclarationsCS packageDeclarationCS_A packageDeclarationCS ::= packageDeclarationCS_A packageDeclarationCS ::= packageDeclarationCS_B packageDeclarationCS_A ::= package pathNameCS contextDeclsCSopt endpackage packageDeclarationCS_B ::= contextDeclsCS contextDeclsCSopt ::= $empty contextDeclsCSopt ::= contextDeclsCS contextDeclsCS ::= contextDeclCS contextDeclsCS ::= contextDeclsCS contextDeclCS contextDeclCS ::= propertyContextDeclCS contextDeclCS ::= classifierContextDeclCS contextDeclCS ::= operationContextDeclCS propertyContextDeclCS ::= context pathNameCS '::' unreservedSimpleNameCS ':' typeCS initOrDerValuesCS initOrDerValuesCS ::= initOrDerValueCS initOrDerValuesCS ::= initOrDerValuesCS initOrDerValueCS initOrDerValueCS ::= init ':' OclExpressionCS initOrDerValueCS ::= derive ':' OclExpressionCS classifierContextDeclCS ::= context pathNameCS invOrDefsCS classifierContextDeclCS ::= context simpleNameCS ':' pathNameCS invOrDefsCS invOrDefsCS ::= invOrDefCS invOrDefsCS ::= invOrDefsCS invOrDefCS invOrDefCS ::= inv unreservedSimpleNameCSopt ':' OclExpressionCS invOrDefCS ::= def unreservedSimpleNameCSopt ':' defExpressionCS invOrDefCS ::= static def unreservedSimpleNameCSopt ':' defExpressionCS defExpressionCS ::= typedUninitializedVariableCS '=' OclExpressionCS defExpressionCS ::= operationCS1 '=' OclExpressionCS operationContextDeclCS ::= context operationCS2 prePostOrBodyDeclsCS prePostOrBodyDeclsCS ::= prePostOrBodyDeclCS prePostOrBodyDeclsCS ::= prePostOrBodyDeclsCS prePostOrBodyDeclCS prePostOrBodyDeclCS ::= pre unreservedSimpleNameCSopt ':' OclExpressionCS prePostOrBodyDeclCS ::= post unreservedSimpleNameCSopt ':' OclExpressionCS prePostOrBodyDeclCS ::= body unreservedSimpleNameCSopt ':' OclExpressionCS operationCS1 ::= simpleNameCS '(' parametersCSopt ')' ':' typeCSopt operationCS2 ::= pathNameCS '::' unreservedSimpleNameCS '(' parametersCSopt ')' ':' typeCSopt parametersCSopt ::= $empty parametersCSopt ::= parametersCS parametersCS ::= VariableDeclarationCS parametersCS ::= parametersCS ',' VariableDeclarationCS Disposition: Deferred NOTE: RESOLVED in Ballot 1 but DEFERRED by disposition of issue 15761 Revised Text: Actions taken: November 2, 2006: received issue Discussion: Good suggestion. Deferred since such grammar need to be defined carefully. The OCL 2.1 specification provides only a partial and ambiguous grammar some of whose problems may be resolved by application of the disambiguating rules. Provision of a complete unambiguous grammar requires the clear semantics for reserved words that may be found in Issue 14583. Resolution of reserved word semantics highlights a number of other problems. The Essential OCL and Complete OCL grammars presented here therefore assume adoption of the following resolutions: Issue 12953: Collection Literals with explicit element types Issue 14196: Integration of UnlimitedNaturalLiteralExpCS Issue 14236: Integration of InvalidLiteralExpCS and NullLiteralExpCS Issue 14237: CollectionRangeCS separator is DotDot. Issue 14357: Token Concrete Syntaxes: String Literals may be concatenated. Issue 14582: Precedence and Associativity. Issue 14583: Reserved Words. false, invalid, null, self, true are reserved words. Boolean, Integer, Real, String, UnlimitedNatural, OclAny, OclInvalid, OclVoid, Bag, Collection, OrderedSet, Sequence, Set, Tuple are restricted words. body, context, def, derive, endpackage, init, inv, package, post, pre, static are reserved words in Complete OCL only. OclMessage is a restricted word in Complete OCL only. Issue 14584: TupleLiteralExp part type inference. Issue 14585: TypeLiteralExpCS is introduced. Issue 14586: named-self classifierContextDeclCS is supported. Issue 14587: attrOrAssocContextCS is renamed. Practical Grammar The LALR(1) grammar in the revised text replaces the unrealisable OperationCallExpCS[A] and OperationCallExpCS[H] by a clear grammar in which precedence and associativity are explicit. Atomic terms such as () and if...endif are primaryExpCS. The awkward let..in.. is both high and low precedence. All infix operators are left associative. The OCL 2.1 grammar is difficult to parse because the presentation in Section 9.3 contains • obvious conflicts (PropertyCallExpCS is directly a FeatureCallExpCS and indirectly a FeatureCallExpCS as a NavigationCallExpCS) • subtle conflicts (EnumLiteralExpCS is a PropertyCallExpCS[C]) • no precedence or associativity grammar • no identifier or string grammar • unclear reserved word policy Once these problems are resolved the grammar remains difficult to parse without semantic information because • LetExpCS is both high and low precedence • OperationCallExpCS[B] and IteratorExpCS[A] require a lookahead to the "ß" token to resolve "c" as a VariableDeclarationCS or a VariableExpCS in "a->b(c,dß". These problems are resolved by expressing the infix and prefix grammar to define precedence and associativity, while allowing use of a simpleNameCS in the awkward overlap between OperationCallExpCS[B] and IteratorExpCS[A]. End of Annotations:===== s is issue # 10439 Recommendations re ptc/2005-06-06 Recommendation: The specification would be better were it to additionally describe a practical grammar useful to tool implementors and persons trying to understand what constitutes legal OCL syntax. Of course, we all know that even practical OCL grammars are permissive of strings that aren't meaningful (for example, 7->isEmpty() is typically legal) but more can be done than is expressed by the current description. I am not suggesting that you replace the current method of description, but that you add (perhaps only as an informative, non-normative appendix) a conventional grammar. The spec, after all, is supposed to serve the purposes of implementors. There are published papers describing practical grammars for OCL, or I can supply you with one, if you'd like. PS By "practical grammar" I mean one that limits the look-ahead to a finite number wherever possible. It is, of course, the use of OclExpression in the RHS of so many productions that runs up against the infinite look-ahead X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAEtI6ErUnw4S/2dsb2JhbADbE4Q/BA Date: Wed, 28 Oct 2009 20:36:46 +0000 From: Ed Willink User-Agent: Thunderbird 2.0.0.22 (Windows/20090605) To: "'ocl2-rtf@omg.org'" Subject: Re: Issue 10439 Recommendations re ptc/2005-06-06 X-Plusnet-Relay: bbbacf0039a1c2f313a9b089e308c80a Hi Mariano Finally with all the dependent problems submitted, a coherent LALR(1) grammar. Regards Ed Willink problem, and makes the published grammar unusable by implementors.