首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >textX:如何用ObjectProcessors生成对象名?

textX:如何用ObjectProcessors生成对象名?
EN

Stack Overflow用户
提问于 2019-05-29 13:41:39
回答 1查看 89关注 0票数 2

我有一个简单的示例模型,在这个模型中,我希望为Position规则的对象生成没有给as <NAME>命名的名称。这是必要的,以便我可以找到他们以后与内置的FQN范围提供程序。

我的想法是在position_name_generator对象处理器中这样做,但是只有在解析了整个模型之后才会调用它。我并不真正理解其中的原因,因为当我需要在Position中使用Project对象时,对象已经创建了,但是对象处理器仍然不会被调用。

另一个想法是在Position.location的自定义作用域提供程序中这样做,后者首先生成名称,然后使用内置的FQN查找Location对象。虽然这是可行的,但我认为这是一种麻烦事,我宁愿避免它。

textX解决这个问题的方法是什么?

(请考虑到这只是一个小例子。在现实中,一个相当大而复杂的模型需要类似的功能。使用生成的名称更改此行为是不可能的,因为这是必需的。)

代码语言:javascript
复制
import textx


MyLanguage = """
    Model
        :   (locations+=Location)*
            (employees+=Employee)*
            (positions+=Position)*
            (projects+=Project)*
        ;

    Project
        :   'project' name=ID
            ('{'
                ('use' use=[Position])*
            '}')?
        ;

    Position
        :   'define' 'position' employee=[Employee|FQN] '->' location=[Location|FQN] ('as' name=ID)?
        ;

    Employee
        :   'employee' name=ID   
        ;

    Location
        :   'location' name=ID
            ( '{'
                (sub_location+=Location)+
            '}')?
        ;

    FQN
        :   ID('.' ID)*
        ;

    Comment:
      /\/\/.*$/
    ;                
"""

MyCode = """
    location Building
    {
        location Entrance
        location Exit
    }

    employee Hans
    employee Juergen

    // Shall be referred to with the given name: "EntranceGuy"
    define position Hans->Building.Entrance as EntranceGuy 
    // Shall be referred to with the autogenerated name: <Employee>"At"<LastLocation>
    define position Juergen->Building.Exit                  

    project SecurityProject
    {
        use EntranceGuy
        use JuergenAtExit
    }
"""


def position_name_generator(obj):
    if "" == obj.name:
        obj.name = obj.employee.name + "At" + obj.location.name


def main():
    meta_model = textx.metamodel_from_str(MyLanguage)
    meta_model.register_scope_providers({
        "Position.location": textx.scoping.providers.FQN(),
    })

    meta_model.register_obj_processors({
        "Position": position_name_generator,
    })

    model = meta_model.model_from_str(MyCode)
    assert model, "Could not create model..."


if "__main__" == __name__:
    main()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-02 18:33:05

解决这个问题的方法是什么..。

您描述的用例是基于其他模型元素定义对象的名称,包括对其他模型元素的引用。目前,这并不是测试套件和textx中包含的任何测试和用例的一部分。

对象处理器在模型构建期间在定义的阶段执行(请参阅http://textx.github.io/textX/stable/scoping/#using-the-scope-provider-to-modify-a-model)。在所描述的设置中,它们在引用解析后执行。由于要定义/推导的名称本身是引用解析所必需的,因此对象处理器不能在这里使用(即使允许在执行对象处理器之前或之后控制对象处理器的执行,所描述的设置仍然无法工作)。

考虑到模型加载的动态性(请参阅http://textx.github.io/textX/stable/scoping/#using-the-scope-provider-to-modify-a-model),解决方案位于作用域提供程序中(如您所建议的)。在这里,我们允许控制引用解析的顺序,以便将对由自定义过程命名的对象的引用推迟到推导/定义解析的名称所需的引用。

可能的解决办法

关于如何解决用例的初步草图将在https://github.com/textX/textX/pull/194中讨论(附带问题https://github.com/textX/textX/issues/193)。这个textx包含一个可能用于项目的scoping.py版本(只需复制并重命名模块)。一个成熟的解决方案可能是textxTEP-001的一部分,在TextTEP-001中,我们计划使范围对最终用户更加可控。

玩这个绝对有趣的问题向我揭示了textx框架的新方面。

  • 名称依赖于模型内容(涉及未解析的引用)。根据我们的参考解析逻辑,这个名称解析可以推迟(在引用的PR中,请参阅下面)。
  • 更有趣的是:指向指向位置的引用发生了什么情况,发现了未解决的名称?在这里,我们必须推迟引用解析过程,因为我们无法知道名称在解析时是否匹配.

您的示例包括:name.py

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56362019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档