Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Cross reference, Qualified name and scoping(Problem when referencing a qualified name using cross reference)
Cross reference, Qualified name and scoping [message #1349676] Mon, 12 May 2014 09:45 Go to next message
Raja B. is currently offline Raja B.Friend
Messages: 6
Registered: May 2014
Junior Member
I want to make cross reference using qualified name but i had some problem with it.
I want to be able to parse
Probe P1 { 
  11 22 33 //the content of Probe is not important
}
Condition C1 {
  P1.value = 1
}


Here is an extract of the grammar
Probe : 
  'Probe' name=ID '{'
   descr+=INT+
  '}'
Condition :
  'Condition' name=ID '{'
   probe=[Probe] '.' met=ID '=' val=INT
  '}'


Using this grammar, I can only parse 'P1 . value' and not 'P1.value' . It parse 'P1.value' as a single token. Note that the 'value' field is not defined in the language anywhere.

I tried a workaround :
Condition :
  'Condition' name=ID '{'
   probe=QualifiedName '=' val=INT
  '}'


I don't use the cross reference directly but a qualified name. I bind it with to correct probe in the MyDslGenerator (in my generated code), check that the used probe is defined in the MyDslValidator, and add the correct auto-completion in the MyDslProposalProvider.

Is there a less hacky way to do it ?

Thanks
Re: Cross reference, Qualified name and scoping [message #1350354 is a reply to message #1349676] Mon, 12 May 2014 16:24 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi xxx=[Sometype] is short for xxx=[Sometype|ID] and means "parse an
ID To reference a Some type. Thus you want to have
xxx=[SomeType|QualifiedName]

BTW why should x.y with your first grammar not work. Maybe you have
some other conflicting terminals

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference, Qualified name and scoping [message #1350397 is a reply to message #1350354] Mon, 12 May 2014 16:48 Go to previous messageGo to next message
Raja B. is currently offline Raja B.Friend
Messages: 6
Registered: May 2014
Junior Member
Christian Dietrich wrote on Mon, 12 May 2014 12:24
Hi xxx=[Sometype] is short for xxx=[Sometype|ID] and means "parse an
ID To reference a Some type. Thus you want to have
xxx=[SomeType|QualifiedName]


I can't have xxx=[SomeType|QualifiedName] because the Probe is defined only by its name 'P1', and when is used with : 'P1.value' . The field 'value' is not defined anywhere. I tried with xxx=[SomeType|QualifiedName], I have as error : Couldn't resolve reference to Probe 'P1.value'.

Christian Dietrich wrote on Mon, 12 May 2014 12:24

BTW why should x.y with your first grammar not work. Maybe you have
some other conflicting terminals


I was suprised that it didn't work. I only have two others terminal rules :
terminal QualifiedName:
	ID ("." ID)+
;

terminal COMPARATOR: '<' | '>' | '>=' | '<=' | '=';
Re: Cross reference, Qualified name and scoping [message #1350449 is a reply to message #1350397] Mon, 12 May 2014 17:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi qualifiedname should be a data type rule instead of a terminal.

QualifiedName: ID ("." ID)*;


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference, Qualified name and scoping [message #1350476 is a reply to message #1350449] Mon, 12 May 2014 17:32 Go to previous messageGo to next message
Raja B. is currently offline Raja B.Friend
Messages: 6
Registered: May 2014
Junior Member
That was the problem.

Thanks a lot !
Re: Cross reference, Qualified name and scoping [message #1783666 is a reply to message #1349676] Thu, 15 March 2018 10:42 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 343
Registered: August 2013
Senior Member
Hi

I have the following rule for qualified names:
QualifiedName:
    ((catalogName=ID '.')? schemaName=ID '.')? identifier=ID;


And I can't use it for cross-references because it's not a data rule returning EString.

Also in my language the following idnetifiers are the same: dbo.person, "dbo".person, dbo.PERSON

I think I need to transform them into a canonicial form before comparision or implement a custom comparision.

Could you suggest how to implement it?

For now I have the following scope provider:
class SQLScopeProvider implements IScopeProvider {

    override getScope(EObject context, EReference reference) {
        if (context instanceof ReferencesColumnConstraint) {
            if (reference == SqlPackage.eINSTANCE.referencesColumnConstraint_ReferredTableName) {
                val rootElement = EcoreUtil2.getRootContainer(context)
                val candidates = EcoreUtil2.getAllContentsOfType(rootElement, TableDefinition)
                return new SimpleScope(candidates.map[EObjectDescription.create(it.tableName.fullyQualifiedName, it)])
            }
            else if (reference == SqlPackage.eINSTANCE.referencesColumnConstraint_ReferredColumnNames) {
                if (context.referredTableName !== null) {
                    val rootElement = context.referredTableName
                    val candidates = EcoreUtil2.getAllContentsOfType(rootElement, ColumnDefinition)
                    return new SimpleScope(candidates.map[EObjectDescription.create(it.name, it)])
                }
            }
        }
    }

    def QualifiedName getFullyQualifiedName(TableName obj) {
        if (obj.schemaName === null) {
            QualifiedName.create(obj.identifier)
        }
        else if (obj.catalogName === null) {
            QualifiedName.create(obj.schemaName, obj.identifier)
        }
        else {
            QualifiedName.create(obj.catalogName, obj.schemaName, obj.identifier)
        }
    }

}
Re: Cross reference, Qualified name and scoping [message #1783668 is a reply to message #1783666] Thu, 15 March 2018 10:55 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you can always implement a IQualifiedNameProvider or a helper as you did .
which comparison are you talking about


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Cross reference, Qualified name and scoping [message #1783680 is a reply to message #1783668] Thu, 15 March 2018 13:39 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 343
Registered: August 2013
Senior Member
Thanks! I've got it.

Here is a simplified fragment of the grammar:
TableDefinition:
    'CREATE' 'TABLE'
    tableName=TableName
    contentsSource=TableContentsSource;

AlterTableStatement:
    'ALTER' 'TABLE'
    tableName=[TableDefinition]
    action=AlterTableAction;

TableName:
    ((catalogName=ID '.')? schemaName=ID '.')? identifier=ID;

ID returns ecore::EString:
    IDENTIFIER ('.' IDENTIFIER)*;


I have to use diferent rules for identifier itself (TableName rule in my grammar) and identifier reference (ID rule in my grammar). I can't use TableName for both. An alternative approach is to use ID rule for both kinds of ids.

On comparision... In my language dbo.person equals dbo."person". I've implemented a value converter, which adds quotes to all segments of an identifier:

class IdConverter implements IValueConverter<String> {

    final static String IDENTIFIER_PATTERN = '([A-Za-z][A-Za-z0-9_]*|"([^"]|"")*")'
    final static Pattern patternFirst = Pattern.compile('''^«IDENTIFIER_PATTERN»([.]«IDENTIFIER_PATTERN»)*$''')
    final static Pattern patternFollowing = Pattern.compile('''[.]«IDENTIFIER_PATTERN»''')

    override toString(String value) throws ValueConverterException {
        // TODO: Remove quotes?
        value
    }

    override toValue(String string, INode node) throws ValueConverterException {
        if (string === null) return null
        val matcherFirst = patternFirst.matcher(string)
        if (!matcherFirst.matches()) {
            throw new IllegalArgumentException("Invalid value: " + string)
        }
        val matcherFollowing = patternFollowing.matcher(string)
        val segments = new ArrayList<String>()
        segments.add(matcherFirst.group(1))
        for (var start = 0; matcherFollowing.find(start); start = matcherFollowing.end()) {
            segments.add(matcherFollowing.group(1))
        }
        segments.map[quote].join('.')
    }

    def private static quote(String value) {
        if (value.startsWith('"')) return value
        '"' + value.replace('"', '""') + '"'
    }

}


Also my ScopeProvider quotes all identifier's segments. So identifier comparision works as expected now.
Re: Cross reference, Qualified name and scoping [message #1783682 is a reply to message #1783680] Thu, 15 March 2018 13:49 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 343
Registered: August 2013
Senior Member
The only problem is that ID is the terminal rule. So, if an identifier will contain a comment
dbo./*comment*/person
this comment will be lost after parsing-serialization cycle.
Re: Cross reference, Qualified name and scoping [message #1783700 is a reply to message #1783682] Thu, 15 March 2018 17:29 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
hmmmm have no idea on that.

hat was not working with having name in 3 parts?
or is this about the cross reference containing comments?



Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:Opting to use original formatter over formatter2
Next Topic:Unable to execute MWE2Runner with maven
Goto Forum:
  


Current Time: Fri Apr 19 16:07:18 GMT 2024

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

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

Back to the top