我有一个简单的示例模型,在这个模型中,我希望为Position规则的对象生成没有给as <NAME>命名的名称。这是必要的,以便我可以找到他们以后与内置的FQN范围提供程序。
我的想法是在position_name_generator对象处理器中这样做,但是只有在解析了整个模型之后才会调用它。我并不真正理解其中的原因,因为当我需要在Position中使用Project对象时,对象已经创建了,但是对象处理器仍然不会被调用。
另一个想法是在Position.location的自定义作用域提供程序中这样做,后者首先生成名称,然后使用内置的FQN查找Location对象。虽然这是可行的,但我认为这是一种麻烦事,我宁愿避免它。
textX解决这个问题的方法是什么?
(请考虑到这只是一个小例子。在现实中,一个相当大而复杂的模型需要类似的功能。使用生成的名称更改此行为是不可能的,因为这是必需的。)
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()发布于 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框架的新方面。
您的示例包括:name.py
https://stackoverflow.com/questions/56362019
复制相似问题