如何解析限定名称表达式中的字段

这是我的“类型”Xtext 语法:


grammar sample.types.Types with org.eclipse.xtext.common.Terminals


generate types "http://www.types.sample/Types"


Model:

    structs     += Struct*

    data        += Data*

    assignments += Assignment*

;

Struct:

    'struct' name=ID '{'

        fields += Field*

    '}'

;

Field:

    type=Type name=ID

;

Type:

      'number'

    | 'string'

;

Data:

    type=[Struct|ID] name=ID

;

Assignment:

    qname=QName '=' value=Value

;

QName:

    data=[Data|ID] '.' path=[Field|ID]

;

Value:

      INT

    | STRING

;

这是“类型”语法的一个实例:


struct SampleA {

    number n

    string s

}

struct SampleB {

    number n

    string s

}


SampleA sampleA1

SampleA sampleA2

SampleB sampleB


sampleA1.n = 12

sampleA1.s = "Hello"


sampleA2.n = 12

sampleA2.s = "Hello"


sampleB.n  = 42

sampleB.s  = "Hello"

最后六行引用字段“n”和“s”,生成错误:


无法解析对字段“x”的引用。


我编写了以下自定义范围提供程序,但没有成功:


class TypesScopeProvider extends AbstractTypesScopeProvider {


   override getScope( EObject context, EReference reference ) {

      if( reference === TypesPackage.Literals.QNAME__PATH ) {

         val model = EcoreUtil2.getContainerOfType(context, Model)

         if( model !== null ) {

            val result = newArrayList

            for( data : model.data ) {

               for( field : data.type.fields ) {

                  result.add(

                     EObjectDescription.create(

                        QualifiedName.create( data.name, field.name ),

                        field ))

               }

            }

            return new SimpleScope(IScope.NULLSCOPE, result)

         }

      }

      super.getScope( context, reference )

   }

}


呼唤远方
浏览 139回答 1
1回答

撒科打诨

在你的语法中你有QName:    data=[Data|ID] '.' path=[Field|ID];因此a.b将成为两个参考的范围。因此你要么必须在你的范围提供商中反映这一点// TODO: context will be a qname. ask it for its data. ask that for its data and collect fields from there and then// scope for pathEObjectDescription.create(                    QualifiedName.create(field.name ),                    field ))例如override getScope(EObject context, EReference reference) {    if (reference === MyDslPackage.Literals.QNAME__PATH) {        if (context instanceof QName) {            val result = newArrayList            for (field : context.data.type.fields) {                result.add(EObjectDescription.create(QualifiedName.create(field.name), field))            }            System.err.println(result)            return new SimpleScope(IScope.NULLSCOPE, result)        }    }    super.getScope(context, reference)}或者你有语法来反映你的范围DataOrField: Data | Field;QName: dataOrField=[DataOrField|FQN]FQN: ID ("." ID)?;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java