从元模型中读取文字
Read literal from meta model
我想问一下是否可以从我的 Python 代码中读取我在元模型中定义的文字。这可能最好用一个例子来解释。假设这是我的元模型(受 Entitiy 示例启发):
EntityModel:
entities+=Entity
;
Entity:
EntityKeyword name=ID '{'
attributes+=Attribute
'}'
;
EntityKeyword:
'entity'
;
现在,如果我解析它,我将可以访问输入文件中定义的任何实体。但我还希望能够读取 EntityKeyword 规则中定义的 'entity' 文字。我试图这样做是为了避免在我自己的代码中对值 ('entity') 进行硬编码。
我一直没能找到办法做到这一点。可能吗?
我已通读文档并尝试使用内置对象。我没有运气。
希望我说得有道理。
谢谢。
更新:
感谢您的回答 - 对我迟到的回复深表歉意。
我现在知道我的例子很糟糕。我很抱歉。
我玩弄了 textX 并阅读了更多文档,并遇到了这一部分:
"textX integrates with Python typing system. In textX there is no keyword returns. The class used for the rule will be dynamically created Python class for all non-match rules. Language designer can provide class using user classes registration on meta-model. If the rule is of [match type] than it will always return Python string or some of base Python types for BASETYPES inherited rules."
Types used for rules
粗体部分听起来很像我想要实现的目标。我会尝试这样做,但如果您有时间的话,我会非常感激这样的例子。
问候
唐豪加德
所以,我找到了解决问题的方法。
我的问题是什么?我想避免在我的元模型中对任何文字进行硬编码。例如
EntityKeyword:
'entity'
;
是一个简单的匹配类型 class,它试图匹配文字 'entity'。如果此关键字是对象的可选参数的名称,那么在执行查找 "hasattr(obj, 'entity')" 时,我将不得不在我的 Python 源代码中对该关键字进行硬编码。这意味着我有一个关键字值要在 2 个地方维护 - 在我的元模型和我的源代码中。
我找到的解决方案真的很简单。我只是使用 "metamodel_from_str()" 从字符串加载元模型。这看起来如何?:
from string import Template
from textx.metamodel import metamodel_from_str
EXTEND_KEYWORD = 'entity'
GRAMMAR=Template("""
EntityKeyword:
'$ext_keyword'
;
""").substitute(ext_keyword=EXTEND_KEYWORD)
Whosebug_mm = metamodel_from_str(GRAMMAR)
我在这里所做的是将我的元模型定义为字符串并使用 string.Template (https://docs.python.org/3/library/string.html#template-strings) 来替换任何关键字。之后我可以将元模型作为字符串加载。现在我只需要维护一个文字(属性 "EXTEND_KEYWORD"),我可以自由地做 "hasattr(obj, EXTEND_KEYWORD)".
这种方法的缺点当然是元语言可能会被各种转义符 ($$) 污染,因为我使用 string.Template 来替换任何关键字。
如果元语言很大,将它写在单独的文件中并将其作为字符串加载可能更有意义。
我想问一下是否可以从我的 Python 代码中读取我在元模型中定义的文字。这可能最好用一个例子来解释。假设这是我的元模型(受 Entitiy 示例启发):
EntityModel:
entities+=Entity
;
Entity:
EntityKeyword name=ID '{'
attributes+=Attribute
'}'
;
EntityKeyword:
'entity'
;
现在,如果我解析它,我将可以访问输入文件中定义的任何实体。但我还希望能够读取 EntityKeyword 规则中定义的 'entity' 文字。我试图这样做是为了避免在我自己的代码中对值 ('entity') 进行硬编码。
我一直没能找到办法做到这一点。可能吗?
我已通读文档并尝试使用内置对象。我没有运气。
希望我说得有道理。
谢谢。
更新:
感谢您的回答 - 对我迟到的回复深表歉意。
我现在知道我的例子很糟糕。我很抱歉。
我玩弄了 textX 并阅读了更多文档,并遇到了这一部分:
"textX integrates with Python typing system. In textX there is no keyword returns. The class used for the rule will be dynamically created Python class for all non-match rules. Language designer can provide class using user classes registration on meta-model. If the rule is of [match type] than it will always return Python string or some of base Python types for BASETYPES inherited rules." Types used for rules
粗体部分听起来很像我想要实现的目标。我会尝试这样做,但如果您有时间的话,我会非常感激这样的例子。
问候 唐豪加德
所以,我找到了解决问题的方法。
我的问题是什么?我想避免在我的元模型中对任何文字进行硬编码。例如
EntityKeyword:
'entity'
;
是一个简单的匹配类型 class,它试图匹配文字 'entity'。如果此关键字是对象的可选参数的名称,那么在执行查找 "hasattr(obj, 'entity')" 时,我将不得不在我的 Python 源代码中对该关键字进行硬编码。这意味着我有一个关键字值要在 2 个地方维护 - 在我的元模型和我的源代码中。
我找到的解决方案真的很简单。我只是使用 "metamodel_from_str()" 从字符串加载元模型。这看起来如何?:
from string import Template
from textx.metamodel import metamodel_from_str
EXTEND_KEYWORD = 'entity'
GRAMMAR=Template("""
EntityKeyword:
'$ext_keyword'
;
""").substitute(ext_keyword=EXTEND_KEYWORD)
Whosebug_mm = metamodel_from_str(GRAMMAR)
我在这里所做的是将我的元模型定义为字符串并使用 string.Template (https://docs.python.org/3/library/string.html#template-strings) 来替换任何关键字。之后我可以将元模型作为字符串加载。现在我只需要维护一个文字(属性 "EXTEND_KEYWORD"),我可以自由地做 "hasattr(obj, EXTEND_KEYWORD)".
这种方法的缺点当然是元语言可能会被各种转义符 ($$) 污染,因为我使用 string.Template 来替换任何关键字。
如果元语言很大,将它写在单独的文件中并将其作为字符串加载可能更有意义。