Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » dealing with type computation of array access
dealing with type computation of array access [message #1513503] Tue, 16 December 2014 15:49 Go to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
Hi

In a new Xbase DSL I started to work on, I need array access like in
Java with []. I've already managed to cope with possible ambiguities in
the grammar (since I don't need lambda expressions), and I have a custom
XAssignment rule that introduces array access, something like

feature=[types::JvmIdentifiableElement|FeatureCallID]
=>('[' index=XAssignment ']')?
OpSingleAssign value=XAssignment ...

Now I have to tweak the type computer so that expressions like

args[0] = "..."

are accepted (args has type String[]).

It is not clear to me how to do that.

The XbaseTypeComputer does

protected void _computeTypes(final XAssignment assignment,
ITypeComputationState state) {
List<? extends IFeatureLinkingCandidate> candidates =
state.getLinkingCandidates(assignment);
ILinkingCandidate best = getBestCandidate(candidates);
best.applyToComputationState();
}

and from what I understand "best.applyToComputationState()" also
triggers type computation of the right-hand expression of the
assignment, and thus I get a type mismatch error "cannot convert from
String to String[]".

Any suggestion?

thanks in advance
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1514273 is a reply to message #1513503] Wed, 17 December 2014 06:46 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
HI Lorenzo,

please bind a custom ExpressionArgumentFactory and override
createExpressionArguments(XExpression, AbstractLinkingCandidate<?>).
Your instance of AssignmentFeatureCallArguments should have the proper
type, e.g the component type of the array type that you are using. Also
note that you have to compute the type for the index individually, e.g.
by calling state.withExpection(*int*).computeTypes(arrayAssign.getIndex).

Best,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: dealing with type computation of array access [message #1514462 is a reply to message #1514273] Wed, 17 December 2014 10:11 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
On 17/12/2014 07:46, Sebastian Zarnekow wrote:
> HI Lorenzo,
>
> please bind a custom ExpressionArgumentFactory and override
> createExpressionArguments(XExpression, AbstractLinkingCandidate<?>).
> Your instance of AssignmentFeatureCallArguments should have the proper
> type, e.g the component type of the array type that you are using. Also
> note that you have to compute the type for the index individually, e.g.
> by calling state.withExpection(*int*).computeTypes(arrayAssign.getIndex).

Thanks for the suggestion Sebastian; I was trying to override

public IFeatureCallArguments createExpressionArguments(XExpression
expression, AbstractLinkingCandidate<?> candidate) {
JvmIdentifiableElement feature = candidate.getFeature();
...
if (expression instanceof XAssignment) {
XAssignment assignment = (XAssignment) expression;
LightweightTypeReference featureType =
candidate.getActualType(candidate.getFeature(), true);
return new AssignmentFeatureCallArguments(assignment.getValue(),
featureType);
}
...
}
}

but unfortunately
org.eclipse.xtext.xbase.typesystem.internal.AbstractLinkingCandidate.getActualType(JvmIdentifiableElement,
boolean) is protected (ExpressionArgumentFactory is in the same package
so it can access it, but my derived class can't)... actually almost
everything is not accessible in AbstractLinkingCandidate ;)

I'll try to compute the feature type in another way... but in
ExpressionArgumentFactory there does not seem to be any way to have a
TypeComputationState...

cheers
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1514870 is a reply to message #1514462] Wed, 17 December 2014 17:26 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Lorenzo,

you may want to try super.createExpressionArguments and inspect the
result afterwards? E.g. if instanceof AssignmentFeatureCallArguments &&
... is array access ... return new AssignmentFeatureCallArguments(..) ?

Let me know which methods you would like to use and we'll see what kind
of API we can offer.

Best,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: dealing with type computation of array access [message #1517783 is a reply to message #1514870] Fri, 19 December 2014 18:55 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
On 12/17/2014 6:26 PM, Sebastian Zarnekow wrote:
> Hi Lorenzo,
>
> you may want to try super.createExpressionArguments and inspect the
> result afterwards? E.g. if instanceof AssignmentFeatureCallArguments &&
> .. is array access ... return new AssignmentFeatureCallArguments(..) ?
>

Thank you Sebastian, this works! :)

> Let me know which methods you would like to use and we'll see what kind
> of API we can offer.

I'll try some other uses and make a proposal...

now I'm stuck due to a grammar problem though... as I said, I removed
all the rules that call Closure related rules (both primary expression
rules, literal rules and rules such as constructor call), and I have the
custom XAssignment rule as follows (MyXAssignment contains the new
feature index):

XAssignment returns XExpression :
{MyXAssignment} feature=[types::JvmIdentifiableElement|FeatureCallID]
('[' index=XExpression ']')?
OpSingleAssign value=XAssignment |
XOrExpression (
=>({XBinaryOperation.leftOperand=current}
feature=[types::JvmIdentifiableElement|OpMultiAssign])
rightOperand=XAssignment
)?;

Now, I'd like to have index access also on the right hand side, and I
thought about something like (MyXFeatureCall contains the new feature index)

XFeatureCall returns XExpression:
{JavammXFeatureCall}
feature=[types::JvmIdentifiableElement|IdOrSuper]
(=>explicitOperationCall?='('
(
featureCallArguments+=XExpression (','
featureCallArguments+=XExpression)*
)?
')'
)?
(=>'[' index=XExpression ']')?;

But I always get "rule ruleXAssignment has non-LL(*) decision"

shouldn't the predicate take care of the ambiguity?

thanks in advance
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1522572 is a reply to message #1517783] Mon, 22 December 2014 11:49 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
Hi again

concerning the grammar ambiguity I solved it with something like that

XAssignment returns XExpression :
=>({MyXAssignment} feature=[types::JvmIdentifiableElement|FeatureCallID]
'[' index=XExpression ']'
OpSingleAssign) value=XAssignment |
=>({XAssignment} feature=[types::JvmIdentifiableElement|FeatureCallID]
OpSingleAssign) value=XAssignment |
XOrExpression ... as in Xbase.xtext;

and to type the right hand side expression with a possible array access
I added to the type computer

def protected _computeTypes(MyXFeatureCall featureCall,
ITypeComputationState state) {
val candidates = state.getLinkingCandidates(featureCall);
val best = getBestCandidate(candidates) as IFeatureLinkingCandidate;
val expState = state as ExpressionTypeComputationState
val actualType = expState.resolvedTypes.getActualType(best.feature)
if (featureCall.index != null) {
... compute the type of the index expression
if (actualType instanceof ArrayTypeReference) {
expState.reassignType(best.feature, actualType.componentType)
}
}
super._computeTypes(featureCall, state)
}

So I need to reassign the type. Trying to simply assign a type would
lead to an illegal exception since the type had already been assigned.

Unfortunately this leads the Xbase type system to give the right
expression (e.g., given the right handside expression i[0]) the compound
type

int[] & int

And this requires avoiding the Xbase compiler to add a cast in the
generated Java code.

This is not a problem, but I was wondering whether it would be better to
have a new XExpression (say MyArrayAccessXExpression) which contains
both the expression and the array access.

What would you suggest?

thanks in advance
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1534788 is a reply to message #1522572] Mon, 29 December 2014 09:45 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Lorenzo,

indeed I would introduce a new ArrayAccessExpression and add a variant
to XMemberFeatureCall that allows to use an arbitrary number of [idx]
after a member feature call and also after an XFeatureCall. Something like

ArrayAccessExpression extends XExpression {
array: XAbstractFeatureCall
index: XExpression
}

The type computer for that thing would be almost trivial since you could
simply query the type for the array XAbstractFeatureCall and ask that
one for its component type. And you'd have to compute the type for the
index with an int-expecation.

Does that make sense to you?

Best,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: dealing with type computation of array access [message #1535393 is a reply to message #1534788] Mon, 29 December 2014 17:40 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
On 29/12/2014 10:45, Sebastian Zarnekow wrote:
> Hi Lorenzo,
>
> indeed I would introduce a new ArrayAccessExpression and add a variant
> to XMemberFeatureCall that allows to use an arbitrary number of [idx]
> after a member feature call and also after an XFeatureCall. Something like
>
> ArrayAccessExpression extends XExpression {
> array: XAbstractFeatureCall
> index: XExpression
> }
>
> The type computer for that thing would be almost trivial since you could
> simply query the type for the array XAbstractFeatureCall and ask that
> one for its component type. And you'd have to compute the type for the
> index with an int-expecation.
>
> Does that make sense to you?

Hi Sebastian

that's what I was thinking of :)

as for the grammar, did you mean something like that? (let's consider
XFeatureCall only, and one single array index for the moment)

XFeatureCall returns XAbstractFeatureCall:
{MyXFeatureCall}
feature=[types::JvmIdentifiableElement|IdOrSuper]
(=>explicitOperationCall?='('
(
featureCallArguments+=XExpression (','
featureCallArguments+=XExpression)*
)?
')'
)?; // no lambda syntax

ArrayAccessExpression returns XExpression:
XFeatureCall
(
=>({ArrayAccessExpression.array=current} '[' index=XExpression ']')
)?
;

and

XPrimaryExpression returns XExpression:
...
ArrayAccessExpression | // instead of XFeatureCall
...

To make ArrayAccessExpression.array=current type check I had to write

XFeatureCall returns XAbstractFeatureCall:

instead of

XFeatureCall returns XExpression:

is that what you meant?

thanks in advance
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1536843 is a reply to message #1535393] Tue, 30 December 2014 13:12 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
> To make ArrayAccessExpression.array=current type check I had to write
>
> XFeatureCall returns XAbstractFeatureCall:
>
> instead of
>
> XFeatureCall returns XExpression:
>
> is that what you meant?

I'm afraid I don't understand. The type of the array containment
reference value is computed for that value. It should be done by means
of state.withNonVoidExpectation().computeType(arrayAccessExpr.getArray())

This should be independent from the static type of the containment
reference itself. Except from that, using XArrayAccessExpression instead
of XFeatureCall in the primary expression sounds good to me.

Best,
Sebastian
Re: dealing with type computation of array access [message #1537143 is a reply to message #1536843] Tue, 30 December 2014 17:10 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
On 30/12/2014 14:12, Sebastian Zarnekow wrote:
>> To make ArrayAccessExpression.array=current type check I had to write
>>
>> XFeatureCall returns XAbstractFeatureCall:
>>
>> instead of
>>
>> XFeatureCall returns XExpression:
>>
>> is that what you meant?
>
> I'm afraid I don't understand. The type of the array containment
> reference value is computed for that value. It should be done by means
> of state.withNonVoidExpectation().computeType(arrayAccessExpr.getArray())
>
> This should be independent from the static type of the containment
> reference itself. Except from that, using XArrayAccessExpression instead
> of XFeatureCall in the primary expression sounds good to me.

Hi

since you suggested this structure for the model element

ArrayAccessExpression extends XExpression {
array: XAbstractFeatureCall
index: XExpression
}

in order to perform the assignment ArrayAccessExpression.array=current
in this grammar rule

ArrayAccessExpression returns XExpression:
XFeatureCall
(
=>({ArrayAccessExpression.array=current} '[' index=XExpression ']')
)?
;

I need the rule for XFeatureCall to return an XAbstractFeatureCall
instead of an XExpression... on a second thought however, I think that
any XExpression should be assignable to ArrayAccessExpression.array.

As for type computation I did something more:

def protected _computeTypes(ArrayAccessExpression arrayAccess,
ITypeComputationState state) {
for (expectation : state.expectations) {
val expectedType = expectation.expectedType
val arrayTypeRef =
state.referenceOwner.newArrayTypeReference(expectedType)
val actualType =
state.withExpectation(arrayTypeRef).computeTypes(arrayAccess.featureCall).actualExpressionType
if (actualType.isArray) {
state.acceptActualType(actualType.componentType)
} else {
state.acceptActualType(actualType)
}
}
val conditionExpectation =
state.withExpectation(getTypeForName(Integer.TYPE, state))
conditionExpectation.computeTypes(arrayAccess.index)
}

if I understand the Xbase type system correctly: I'm typing the array
expression expecting it to be an array of the expected type (the
expectations come from outer expressions, e.g., assignments), and this
will also perform type checking; then I give the ArrayAccessExpression
the component type of the actual array type (the else case avoids having
too many errors reported, since in case array expression is not an array
the error will be reported on that very expression).

cheers
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Re: dealing with type computation of array access [message #1541952 is a reply to message #1537143] Fri, 02 January 2015 10:27 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Lorenzo,

first of all: happy new year :)

Your _computeTypes impl looks good to me. A minor remark:
you should use expectation.acceptActualType(actualType.componentType).
Even though we use only one expectation at the moment, future
refinements in the type system may pass multiple expectations into a
single computateTypes invocation.

Best,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: dealing with type computation of array access [message #1545551 is a reply to message #1541952] Sun, 04 January 2015 11:17 Go to previous message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1812
Registered: July 2009
Location: Firenze, Italy
Senior Member
On 1/2/2015 11:27 AM, Sebastian Zarnekow wrote:
> Hi Lorenzo,
>
> first of all: happy new year :)

Hi Sebastian

Happy new Xtext year to you too :)

>
> Your _computeTypes impl looks good to me. A minor remark:
> you should use expectation.acceptActualType(actualType.componentType).
> Even though we use only one expectation at the moment, future
> refinements in the type system may pass multiple expectations into a
> single computateTypes invocation.

OK, I see.

Actually for the moment I changed the implementation a bit: I was
assuming there are always type expectations, but that's not the case: in
an assignment there are type expectations but in other contexts, e.g.,
if expression, the expectation is simply "not void" so the expected type
would be null... of course I could check that, but for the moment I
simplified the type computation like you suggested in your previous post:

val actualType =
state.withNonVoidExpectation.computeTypes(arrayAccess.array).actualExpressionType
.... similar to before

Correct me if I'm wrong, but the possible expected type would not help
the typ computation of arrayAccess.array anyway, would it?

I also modified the grammar so that the array expression can be any
XExpression, instead of just an XAbstractFeatureCall (otherwise it would
not parse expressions such as (a)[0]). In order to do that, I
reinserted XFeatureCall as a XPrimaryExpression and I modified the
XPostfixOperation as follows:

XPostfixOperation returns XExpression:
XMemberFeatureCall
(
=>({XPostfixOperation.operand=current}
feature=[types::JvmIdentifiableElement|OpPostfix])
|
=>({ArrayAccessExpression.array=current} '[' indexes+=XExpression
']'(=>'[' indexes+=XExpression ']')*)
)?
;

Moreover, to handle multiple dimension array access I modified the index
feature into indexes. I would have liked to parse array access
expressions recursively, i.e., a[i][j] as (a[i])[j]. This would have
worked for argument expressions, but not when the array access
expression is a left hand side expression of an assignment, since
XAssignment left element is a feature call and I didn't want to change
the structure of an XAssignment. At least, in this solution, array
access will be handled in the same way both on the left and the right
hand side of an assignment...

cheers
Lorenzo

--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book


Previous Topic:Xtext -> Xcore -> Xtext
Next Topic:Xtext parser in standalone
Goto Forum:
  


Current Time: Fri Apr 26 15:46:15 GMT 2024

Powered by FUDForum. Page generated in 0.03690 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top