Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Type aware parser; conditional syntactic predicates
Type aware parser; conditional syntactic predicates [message #1096609] Wed, 28 August 2013 12:24 Go to next message
Eclipse UserFriend
Hi,

sorry for the bad title of my question... I coudn't find a better one...

I think my problem is well-known, but I couldn't find out how to handle this situation: I've got two different rules which are equally valid for the parser. Xtext/Antlr cannot handle this situation alone, but I think it should be possible (even though not in an early stage of parsing, since additional information about referenced types is required). Let me give an example:

DSLRoot:
    types += (TypeOneClass | TypeTwoClass)*
    ('select' selections += AnyType ";")*
;

TypeOneClass:
    'one' name=ID ';'
;

TypeTwoClass:
    'two' name=ID ';'
;

TypeOne:
    feature=[TypeOneClass|ID]
;

TypeTwo:
    feature=[TypeTwoClass|ID]
;

AnyType returns Target:
    TypeOne | TypeTwo
;


The problem is the last rule. The parser cannot differ between "TypeOne" and "TypeTwo" (because in both cases the ambiguous terminal "ID" is expected).

My first idea was to use a syntactic predicate to tell the parser that it should use TypeOne. I hoped that the parser would use rule TypeOne, but would fall-back to TypeTwo if the reference cannot be resolved.

AnyType returns Target:
    (=> TypeOne) | TypeTwo
;


Unfortunately this doesn't work; the screenshots show what's happening: scoping works fine (this is a little bit unexpected), but any reference to a TypeTwoClass cannot be resolved (because only TypeOneClasses are accepted - this again is as feared).

How can I solve this issue? I thought that I might have to enable backtracking, but woudn't like this... And I fear that this won't work anyway.

/edit:
Of course, I could add terminals that allow easy distinguishing between the "TypeOne" and "TypeTwo" rules. But this would cause my language to become ugly. Another approach would be that I combine/merge "TypeOne" and "TypeTwo" in my grammer. But this would force me to implement scoping and resolving manually - the major reason why I'm using Xtext.


  • Attachment: scoping.png
    (Size: 7.25KB, Downloaded 147 times)
  • Attachment: resolving.png
    (Size: 11.87KB, Downloaded 143 times)

[Updated on: Wed, 28 August 2013 12:32] by Moderator

Re: Type aware parser; conditional syntactic predicates [message #1096625 is a reply to message #1096609] Wed, 28 August 2013 12:50 Go to previous messageGo to next message
Eclipse UserFriend
Parsing is done independently from scoping which is done afterwards so I'm afraid you'll have to fall back to the options you're mentioning.
Re: Type aware parser; conditional syntactic predicates [message #1097068 is a reply to message #1096625] Thu, 29 August 2013 03:32 Go to previous messageGo to next message
Eclipse UserFriend
Hm... what a pitty. But after thinking about the problem for a while, I have to admit that it wouldn't be so good to solve it on the parser side, anyway.

However, what I would find great was to have the possibility to annotate my grammer in order to guide scoping. I've never seen something like this, so I doubt that it is possible. But are there any plans for the future? It could look something like this:

DSLRoot:
    types += (TypeOneClass | TypeTwoClass)*
    ('select' selections += AnyTypeRef ';')*
;

TypeOneClass:
    'one' name=ID ';'
;

TypeTwoClass:
    'two' name=ID ';'
;

AnyTypeRef:
    feature=[ (=>TypeOneClass | TypeTwoClass) | ID ]
;


The syntax used for feature of the AnyTypeRef rule is supposed to mean "Parser, expect the terminal ID here. Scoping, expect the name of a TypeOneClass here; if you cannt find such instance, expect the name of a TypeTwoClass". Thus, for the parser, the last rule would be equal to this:

AnyTypeRef:
    feature=ID
;


I think this wouldn't be too hard to implement, would it?

Re: Type aware parser; conditional syntactic predicates [message #1097167 is a reply to message #1097068] Thu, 29 August 2013 06:17 Go to previous messageGo to next message
Eclipse UserFriend
Whoops! Smile

I just realized that I can use Ecore::EObject to have most of the scoping implemented:

DSLRoot:
    types += (TypeOneClass | TypeTwoClass)*
    ('select' selections += AnyTypeRef ';')*
;

TypeOneClass:
    'one' name=ID ';'
;

TypeTwoClass:
    'two' name=ID ';'
;

AnyTypeRef:
    feature=[Ecore::EObject|ID]
;


This will do most of the work; the only thing I have to add is a FilteringScope.

public IScope scope_EObject(AnyTypeRef tr, EReference ref)
{
    IScope delegateScope = delegateGetScope(tr, ref);
    
    Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>()
        {
            @Override
            public boolean apply(IEObjectDescription input)
            {
                EObject item = input.getEObjectOrProxy();
                
                if (item instanceof TypeOneClass ||
                    item instanceof TypeTwoClass)
                    return true;
                else
                    return false;
            }
        };
    
    IScope filteredScope = new FilteringScope(delegateScope, filter); 
    return filteredScope;
}
Re: Type aware parser; conditional syntactic predicates [message #1097209 is a reply to message #1096609] Thu, 29 August 2013 07:31 Go to previous messageGo to next message
Eclipse UserFriend
How about using a super class instead of EObject?

DSLRoot:
    types += (TypedClass)*
    ('select' selections += AnyTypeRef ';')*
;

//this should make TypedClass the super class of TypeOneClass and TypeTwoClass;
TypedClass: TypeOneClass | TypeTwoClass;

TypeOneClass:
    'one' name=ID ';'
;

TypeTwoClass:
    'two' name=ID ';'
;

AnyTypeRef:
    feature=[TypedClass|ID]
;

Re: Type aware parser; conditional syntactic predicates [message #1097809 is a reply to message #1097209] Fri, 30 August 2013 03:24 Go to previous messageGo to next message
Eclipse UserFriend
Good point. Certainly it would be better to introduce an appropriate superclass.

My real scenario, however, is a bit more complicated than the example above: "TypeTwoClass" is no Xtext/grammer element there, but an EClass from a custom Ecore model. I already have corresponding superclasses in my custom Ecore model, but coudn't imagine of some technique to have a common superclass with an EClass introduced by Xtext. I would expect the following attempt to fail:

TypedClass: TypeOneClass | MyModel::MyEClass;

TypeOneClass:
    'two' name=ID ';'
;

AnyTypeRef:
    feature=[TypedClass|ID]
;


Didn't try that out, though.

But I think I'll play around a bit... maybe I can do something like this:

TypeOneClass returns MyModel::MySuperclass:
    'two' name=ID ';'
;

AnyTypeRef:
    feature=[MySuperclass|ID]
;


The idea was that "MySuperclass" should become the superclass of "TypeOneClass". For "TypeTwoClass" it is already modeled that way in the Ecore model.
Re: Type aware parser; conditional syntactic predicates [message #1097918 is a reply to message #1097809] Fri, 30 August 2013 06:40 Go to previous message
Eclipse UserFriend
in that case I often use an action to ensure the returned class is not directly the superclass
TypeOneClass returns MyModel::MySuperclass: {TypeOneClass}
    'two' name=ID ';'
;

Previous Topic:Working with huge models in an embedded editor
Next Topic:Lexer problem
Goto Forum:
  


Current Time: Fri Jul 04 11:55:23 EDT 2025

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

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

Back to the top